返回 last30days-skill
2026-08-14-demote-grok-cli-opt-in-plan.md
根目录 / docs / plans / 2026-08-14-demote-grok-cli-opt-in-plan.md
1 # feat(x): demote Grok CLI to opt-in backup
2
3 Stop using the Grok CLI as the default X backend. A leftover `~/.grok/auth.json` must never steal the X lane. Grok stays as a pin-only backup: off unless LAST30DAYS_X_BACKEND=grok or --x-backend grok.
4
5 ### Requirements
6 - R1. Unpinned auto chain is bird → xai → xurl → xquik. Bird is first. Grok is not a member. Presence of ~/.grok/auth.json (ok, expired, or error) must not change which backend an unpinned run uses.
7 - R2. Grok remains a valid explicit selection: LAST30DAYS_X_BACKEND=grok and --x-backend grok. A pin forces grok with no failover. If grok is unusable, X is unconfigured and doctor/footer say so with the existing login hint.
8 - R3. Doctor "will use: grok" only when grok is pinned and the probe is OK or DEGRADED. Unpinned, grok may appear as unused opt-in ("available, unused — pin LAST30DAYS_X_BACKEND=grok"), never as the predicted winner.
9 - R4. get_x_source_status and get_x_source_with_method must prefer bird over xai/xurl/xquik when cookies are present. Grok wins only when the pin is grok.
10 - R5. Host docs stop presenting grok as the default keyless X path. Document it as opt-in backup. Default story is bird first, then xai / xurl / xquik.
11 - R6. Setup / first-run / prescriptions do not nag grok login as the fix for missing X. Cookie consent and paid keys remain the default prescriptions. Grok login is mentioned only as an optional pin.
12 - R7. Do not delete scripts/lib/grok_x.py, retrieve-judge-retry, or expires_at honesty. Pinned grok still uses them.
13 - R8. A machine with only a grok login (no cookies, no XAI/XQUIK, no xurl) has X unconfigured until the user pins grok. Footer: X skipped-unconfigured, not auth-failed-from-grok.
14 - R9. Tests cover the cases above; docs/changelog updated.
15
16 ### Implementation units
17 U1 env.py: _X_BACKEND_ORDER = ("bird", "xai", "xurl", "xquik"); X_BACKEND_OPT_IN = ("grok",); X_BACKEND_KNOWN = ORDER + OPT_IN; pin uses KNOWN; unpinned walks ORDER only; get_x_source_status bird first, grok only if pinned; get_x_source_with_method bird before xai.
18
19 U2 backends.py / doctor.py / prescriptions.py: descriptor is auto ORDER then grok opt-in; unpinned collect-then-pick ignores opt-in; do not change _probe_grok honesty.
20
21 U3 SKILL.md, CONFIGURATION.md, README.md, README.pt-BR.md if needed, changelog.d: remove "sits ahead of the cookie path"; document bird → xai → xurl → xquik; pin grok to enable it.
22
23 U4 tests: unpinned grok-only empty; unpinned grok+bird → bird; unpinned bird+xai → bird; pin grok+store → ["grok"]; pin grok no store empty; doctor unpinned never predicts grok; descriptor parity treats grok as trailing opt-in.
24
25 ### Tests T1–T7
26 T1 unpinned grok AUTH_OK, no other creds → X unconfigured
27 T2 unpinned grok AUTH_EXPIRED, no other creds → X unconfigured (not will-use grok)
28 T3 unpinned grok AUTH_OK + cookies → bird
29 T4 unpinned XAI_API_KEY + grok store, no cookies → xai
30 T4b unpinned XAI_API_KEY + cookies → bird
31 T5 pin grok AUTH_OK → grok no failover
32 T6 pin grok no store → error / grok login prescription
33 T7 docs match R5
34
35 ### Keep-the-door-open (KTD)
36 1. grok_x.py stays untouched
37 2. x_judge.py stays untouched
38 3. expires_at honesty stays untouched
39 4. auth.x.ai is never called
40 5. bird cookie extraction is unchanged
41
41 lines MARKDOWN