返回 last30days-skill
test_x_policy.py
根目录 / tests / test_x_policy.py
1 """U1: host signal, X policy helper, and chain registration.
2
3 One helper in lib/env.py (``x_policy``) owns the official-only rule keyed on
4 ``LAST30DAYS_HOST=grok-bot``. It shapes the unpinned chain and cookie
5 discovery; the ``LAST30DAYS_X_BACKEND`` pin keeps its exclusive semantics on
6 every host and may name any known backend. ``LAST30DAYS_X_HOST_LANE`` is the
7 per-session lane signal read from the process environment only (a ``.env``
8 line is ignored), and ``pipeline.available_sources`` lists X for the lane or
9 a validated envelope in every cookie mode.
10
11 Only obvious dummy values are used for every credential.
12 """
13
14 from __future__ import annotations
15
16 import contextlib
17 import os
18 import re
19 from pathlib import Path
20 from unittest import mock
21
22 import pytest
23
24 from lib import backends, env, health, pipeline
25
26 ROOT = Path(__file__).resolve().parents[1]
27 LIB_DIR = ROOT / "skills" / "last30days" / "scripts" / "lib"
28
29 _PAIR = {"auth_token": "test-auth-token", "ct0": "test-ct0"}
30 _COOKIES = {"AUTH_TOKEN": "test-auth-token", "CT0": "test-ct0"}
31
32
33 def _grok_bot(**over):
34 cfg = {"LAST30DAYS_HOST": "grok-bot"}
35 cfg.update(over)
36 return cfg
37
38
39 def _stub_backends(
40 *,
41 bird_installed=True,
42 xurl_available=False,
43 xurl_stored=False,
44 grok_authed=False,
45 ):
46 """Local-only backend probes so chain resolution touches no network."""
47 stack = contextlib.ExitStack()
48 stack.enter_context(mock.patch("lib.bird_x.is_bird_installed", return_value=bird_installed))
49 stack.enter_context(mock.patch("lib.xurl_x.is_available", return_value=xurl_available))
50 stack.enter_context(mock.patch("lib.xurl_x.has_stored_auth", return_value=xurl_stored))
51 stack.enter_context(mock.patch("lib.grok_x.has_stored_auth", return_value=grok_authed))
52 return stack
53
54
55 def _no_cookie_reads():
56 """Every cookie leg raises: the policy must return before any of them."""
57 stack = contextlib.ExitStack()
58 for target in (
59 "lib.agentcookie.read_x_cookies",
60 "lib.chrome_cdp.read_x_cookies",
61 "lib.cookie_extract.extract_cookies",
62 ):
63 stack.enter_context(
64 mock.patch(target, side_effect=AssertionError(f"{target} must not run"))
65 )
66 return stack
67
68
69 # ---------------------------------------------------------------------------
70 # Registration (KTD1, KTD10)
71 # ---------------------------------------------------------------------------
72
73
74 def _hermetic_config(tmp_path, monkeypatch, env_file_text: str | None):
75 config_file = tmp_path / ".env"
76 if env_file_text is not None:
77 config_file.write_text(env_file_text, encoding="utf-8")
78 config_file.chmod(0o600)
79 monkeypatch.setenv("LAST30DAYS_CONFIG_DIR", str(tmp_path))
80 monkeypatch.setattr(env, "CONFIG_DIR", tmp_path)
81 monkeypatch.setattr(env, "CONFIG_FILE", config_file)
82 monkeypatch.chdir(tmp_path)
83 for key in (
84 "LAST30DAYS_HOST", "LAST30DAYS_X_HOST_LANE", "X_BEARER_TOKEN",
85 "LAST30DAYS_X_BACKEND", "XAI_API_KEY", "AUTH_TOKEN", "CT0",
86 "XQUIK_API_KEY", "FROM_BROWSER", "AGENTCOOKIE", "BROWSER_CDP_URL",
87 ):
88 monkeypatch.delenv(key, raising=False)
89 return contextlib.ExitStack()
90
91
92 def _neutral_sources(stack: contextlib.ExitStack) -> None:
93 stack.enter_context(mock.patch.object(env, "_load_keychain", return_value={}))
94 stack.enter_context(mock.patch.object(env, "_load_pass", return_value={}))
95 stack.enter_context(mock.patch.object(env, "_find_project_env", return_value=None))
96
97
98 def test_new_keys_are_registered_in_get_config(tmp_path, monkeypatch):
99 stack = _hermetic_config(tmp_path, monkeypatch, None)
100 with stack:
101 _neutral_sources(stack)
102 config = env.get_config()
103 for key in ("LAST30DAYS_HOST", "X_BEARER_TOKEN", "LAST30DAYS_X_HOST_LANE"):
104 assert key in config, key
105
106
107 def test_bearer_token_joins_keychain_keys():
108 assert "X_BEARER_TOKEN" in env.KEYCHAIN_KEYS
109
110
111 def test_host_and_bearer_load_from_env_file(tmp_path, monkeypatch):
112 stack = _hermetic_config(
113 tmp_path, monkeypatch,
114 "LAST30DAYS_HOST=grok-bot\nX_BEARER_TOKEN=dummy-bearer\n",
115 )
116 with stack:
117 _neutral_sources(stack)
118 config = env.get_config()
119 assert config["LAST30DAYS_HOST"] == "grok-bot"
120 assert config["X_BEARER_TOKEN"] == "dummy-bearer"
121 assert env.x_policy(config).official_only is True
122
123
124 def test_lane_signal_from_process_env_is_declared(tmp_path, monkeypatch):
125 stack = _hermetic_config(tmp_path, monkeypatch, None)
126 monkeypatch.setenv("LAST30DAYS_X_HOST_LANE", "1")
127 with stack:
128 _neutral_sources(stack)
129 config = env.get_config()
130 assert config["LAST30DAYS_X_HOST_LANE"] == "1"
131 assert env.x_host_lane_declared(config) is True
132
133
134 def test_lane_signal_in_env_file_only_is_ignored(tmp_path, monkeypatch):
135 """KTD10: a removed connector must never leave a stale .env declaration."""
136 stack = _hermetic_config(tmp_path, monkeypatch, "LAST30DAYS_X_HOST_LANE=1\n")
137 with stack:
138 _neutral_sources(stack)
139 config = env.get_config()
140 assert not config.get("LAST30DAYS_X_HOST_LANE")
141 assert env.x_host_lane_declared(config) is False
142
143
144 # ---------------------------------------------------------------------------
145 # Policy record (KTD2)
146 # ---------------------------------------------------------------------------
147
148
149 def test_constants():
150 assert env.X_BACKEND_ORDER == ("bird", "xai", "xurl", "xquik")
151 assert env.X_BACKEND_OPT_IN == ("grok", "xapi")
152 assert env.X_OFFICIAL == ("xapi", "xai", "xurl")
153 assert set(env.X_OFFICIAL) <= set(env.X_BACKEND_KNOWN)
154
155
156 def test_policy_default_host_matches_today():
157 policy = env.x_policy({})
158 assert policy.host == ""
159 assert policy.official_only is False
160 assert tuple(policy.auto_chain) == env.X_BACKEND_ORDER
161 assert policy.cookie_discovery is True
162 assert policy.hint_namespace == "default"
163 assert env.x_auto_chain({}) == list(env.X_BACKEND_ORDER)
164
165
166 def test_policy_grok_bot_is_official_only():
167 policy = env.x_policy(_grok_bot())
168 assert policy.host == "grok-bot"
169 assert policy.official_only is True
170 assert tuple(policy.auto_chain) == ("xapi", "xai", "xurl")
171 assert policy.cookie_discovery is False
172 assert policy.hint_namespace == "official"
173 assert env.x_auto_chain(_grok_bot()) == ["xapi", "xai", "xurl"]
174
175
176 def test_policy_is_frozen():
177 policy = env.x_policy(_grok_bot())
178 with pytest.raises(Exception):
179 policy.official_only = False # type: ignore[misc]
180
181
182 def test_policy_never_infers_host_from_agent_env_or_platform():
183 """Only LAST30DAYS_HOST switches the policy (AE8: CURSOR_AGENT is not it)."""
184 with (
185 mock.patch.dict(os.environ, {"CURSOR_AGENT": "1", "GROK_CLI": "1"}, clear=False),
186 mock.patch("platform.system", return_value="Linux"),
187 ):
188 policy = env.x_policy({})
189 assert policy.official_only is False
190 assert tuple(policy.auto_chain) == env.X_BACKEND_ORDER
191 assert policy.cookie_discovery is True
192
193
194 def test_other_host_values_are_not_official_only():
195 for host in ("claude-code", "codex", "cursor", "grok", "hermes", "openclaw"):
196 assert env.x_policy({"LAST30DAYS_HOST": host}).official_only is False
197
198
199 def test_bird_pin_re_enables_cookie_discovery_on_grok_bot():
200 policy = env.x_policy(_grok_bot(LAST30DAYS_X_BACKEND="bird"))
201 assert policy.official_only is True
202 assert policy.cookie_discovery is True
203
204
205 def test_non_bird_pin_keeps_discovery_off_on_grok_bot():
206 for pin in ("xquik", "grok", "xai", "xurl", "xapi"):
207 assert env.x_policy(_grok_bot(LAST30DAYS_X_BACKEND=pin)).cookie_discovery is False
208
209
210 def test_grok_bot_literal_compared_only_in_env():
211 """The policy helper is the only place the host string is compared."""
212 pattern = re.compile(r"""==\s*['"]grok-bot['"]|['"]grok-bot['"]\s*==""")
213 offenders = []
214 for path in LIB_DIR.glob("*.py"):
215 if path.name == "env.py":
216 continue
217 if pattern.search(path.read_text(encoding="utf-8")):
218 offenders.append(path.name)
219 assert offenders == []
220
221
222 # ---------------------------------------------------------------------------
223 # Chain resolution on a Grok Bot host (R1, R3, AE2, AE2a)
224 # ---------------------------------------------------------------------------
225
226
227 def test_grok_bot_bird_pin_gives_bird_and_discovery_runs():
228 config = _grok_bot(LAST30DAYS_X_BACKEND="bird", AGENTCOOKIE="on")
229 with (
230 mock.patch("platform.system", return_value="Linux"),
231 mock.patch("lib.agentcookie.read_x_cookies", return_value=dict(_PAIR)) as sidecar,
232 mock.patch("lib.chrome_cdp.read_x_cookies", return_value=None),
233 mock.patch.object(env, "extract_browser_credentials", return_value={}),
234 ):
235 env._discover_and_apply_x_credentials(config)
236 assert sidecar.called
237 assert config["AUTH_TOKEN"] == "test-auth-token"
238 with _stub_backends(), mock.patch("lib.bird_x.set_credentials") as prime:
239 assert env.x_backend_chain(config) == ["bird"]
240 assert prime.called
241
242
243 def test_grok_bot_xquik_pin_gives_xquik_without_discovery():
244 config = _grok_bot(LAST30DAYS_X_BACKEND="xquik", XQUIK_API_KEY="dummy-key",
245 FROM_BROWSER="firefox", AGENTCOOKIE="on")
246 with (
247 mock.patch("platform.system", return_value="Linux"),
248 _no_cookie_reads(),
249 ):
250 env._discover_and_apply_x_credentials(config)
251 assert "AUTH_TOKEN" not in config
252 with _stub_backends():
253 assert env.x_backend_chain(config) == ["xquik"]
254
255
256 def test_grok_bot_grok_pin_with_signed_in_cli_gives_grok():
257 config = _grok_bot(LAST30DAYS_X_BACKEND="grok", **_COOKIES)
258 with _stub_backends(grok_authed=True):
259 assert env.x_backend_chain(config) == ["grok"]
260
261
262 @pytest.mark.parametrize("pin", ["xai", "xurl", "xapi"])
263 def test_grok_bot_official_pins_select_only_that_backend(pin):
264 config = _grok_bot(
265 LAST30DAYS_X_BACKEND=pin,
266 X_BEARER_TOKEN="dummy-bearer",
267 XAI_API_KEY="dummy-xai",
268 **_COOKIES,
269 )
270 with _stub_backends(xurl_available=True, xurl_stored=True):
271 assert env.x_backend_chain(config) == [pin]
272 assert env.x_backend_chain(config, local_only=True) == [pin]
273
274
275 def test_grok_bot_unpinned_pin_of_unavailable_backend_is_empty():
276 config = _grok_bot(LAST30DAYS_X_BACKEND="xapi", XAI_API_KEY="dummy-xai")
277 with _stub_backends():
278 assert env.x_backend_chain(config) == []
279
280
281 def test_grok_bot_bearer_gives_xapi():
282 config = _grok_bot(X_BEARER_TOKEN="dummy-bearer", **_COOKIES, XQUIK_API_KEY="dummy-key")
283 with _stub_backends():
284 assert env.x_backend_chain(config) == ["xapi"]
285 assert env.get_x_source(config) == "xapi"
286
287
288 def test_grok_bot_bearer_and_xai_key_gives_xapi_then_xai():
289 config = _grok_bot(X_BEARER_TOKEN="dummy-bearer", XAI_API_KEY="dummy-xai")
290 with _stub_backends():
291 assert env.x_backend_chain(config) == ["xapi", "xai"]
292
293
294 def test_grok_bot_bearer_xai_and_xurl_gives_full_official_chain():
295 config = _grok_bot(X_BEARER_TOKEN="dummy-bearer", XAI_API_KEY="dummy-xai", **_COOKIES)
296 with _stub_backends(xurl_available=True, xurl_stored=True):
297 assert env.x_backend_chain(config) == ["xapi", "xai", "xurl"]
298 assert env.x_backend_chain(config, local_only=True) == ["xapi", "xai", "xurl"]
299
300
301 def test_grok_bot_cookies_only_unpinned_is_unconfigured_and_never_primes_bird():
302 config = _grok_bot(**_COOKIES, XQUIK_API_KEY="dummy-key")
303 with (
304 _stub_backends(),
305 mock.patch("lib.bird_x.set_credentials",
306 side_effect=AssertionError("bird must not be primed on grok-bot")),
307 ):
308 assert env.x_backend_chain(config) == []
309 assert env.get_x_source(config) is None
310
311
312 def test_non_grok_chain_still_primes_bird_when_bird_in_chain():
313 config = dict(_COOKIES)
314 with _stub_backends(), mock.patch("lib.bird_x.set_credentials") as prime:
315 assert env.x_backend_chain(config) == ["bird"]
316 prime.assert_called_once_with("test-auth-token", "test-ct0")
317
318
319 def test_non_grok_xapi_is_opt_in_only():
320 config = {"X_BEARER_TOKEN": "dummy-bearer"}
321 with _stub_backends():
322 assert env.x_backend_chain(config) == []
323 assert env.x_backend_chain({**config, "LAST30DAYS_X_BACKEND": "xapi"}) == ["xapi"]
324
325
326 # ---------------------------------------------------------------------------
327 # get_x_source_status and get_x_source_with_method iterate the policy chain
328 # ---------------------------------------------------------------------------
329
330 _BIRD_OFF = {"installed": True, "authenticated": False, "username": "", "can_install": True}
331 _BIRD_ON = {"installed": True, "authenticated": True, "username": "u", "can_install": True}
332
333
334 def test_status_on_grok_bot_picks_xapi_and_never_probes_bird_or_xquik():
335 config = _grok_bot(X_BEARER_TOKEN="dummy-bearer", XQUIK_API_KEY="dummy-key", **_COOKIES)
336 with (
337 mock.patch("lib.bird_x.get_bird_status", return_value=dict(_BIRD_ON)),
338 mock.patch("lib.bird_x.set_credentials",
339 side_effect=AssertionError("bird must not be primed on grok-bot")),
340 mock.patch("lib.bird_x.probe_works",
341 side_effect=AssertionError("bird must not be probed on grok-bot")),
342 mock.patch("lib.xquik.probe_works",
343 side_effect=AssertionError("xquik must not be probed on grok-bot")),
344 mock.patch("lib.xurl_x.has_stored_auth", return_value=False),
345 mock.patch("lib.xurl_x.is_available", return_value=False),
346 ):
347 status = env.get_x_source_status(config, probe=True)
348 assert status["source"] == "xapi"
349 assert status["xapi_available"] is True
350
351
352 def test_status_on_grok_bot_cookies_only_is_none_but_bird_pin_is_bird():
353 with (
354 mock.patch("lib.bird_x.get_bird_status", return_value=dict(_BIRD_ON)),
355 mock.patch("lib.bird_x.set_credentials"),
356 mock.patch("lib.xurl_x.has_stored_auth", return_value=False),
357 ):
358 assert env.get_x_source_status(_grok_bot(**_COOKIES))["source"] is None
359 pinned = env.get_x_source_status(_grok_bot(**_COOKIES, LAST30DAYS_X_BACKEND="bird"))
360 assert pinned["source"] == "bird"
361
362
363 def test_status_on_grok_bot_grok_pin_is_grok():
364 with (
365 mock.patch("lib.bird_x.get_bird_status", return_value=dict(_BIRD_OFF)),
366 mock.patch("lib.grok_x.has_stored_auth", return_value=True),
367 mock.patch("lib.xurl_x.has_stored_auth", return_value=False),
368 ):
369 status = env.get_x_source_status(_grok_bot(LAST30DAYS_X_BACKEND="grok"))
370 assert status["source"] == "grok"
371
372
373 def test_status_non_grok_ladder_unchanged():
374 with (
375 mock.patch("lib.bird_x.get_bird_status", return_value=dict(_BIRD_ON)),
376 mock.patch("lib.bird_x.set_credentials"),
377 mock.patch("lib.xurl_x.has_stored_auth", return_value=True),
378 ):
379 assert env.get_x_source_status({**_COOKIES, "XAI_API_KEY": "k"})["source"] == "bird"
380 with (
381 mock.patch("lib.bird_x.get_bird_status", return_value=dict(_BIRD_OFF)),
382 mock.patch("lib.xurl_x.has_stored_auth", return_value=True),
383 ):
384 assert env.get_x_source_status({"XAI_API_KEY": "k"})["source"] == "xai"
385 assert env.get_x_source_status({})["source"] == "xurl"
386 with (
387 mock.patch("lib.bird_x.get_bird_status", return_value=dict(_BIRD_OFF)),
388 mock.patch("lib.xurl_x.has_stored_auth", return_value=False),
389 ):
390 assert env.get_x_source_status({"XQUIK_API_KEY": "k"})["source"] == "xquik"
391 # xapi is opt-in on a non-Grok host: never the unpinned source.
392 assert env.get_x_source_status({"X_BEARER_TOKEN": "b"})["source"] is None
393 pinned = env.get_x_source_status(
394 {"X_BEARER_TOKEN": "b", "LAST30DAYS_X_BACKEND": "xapi"}
395 )
396 assert pinned["source"] == "xapi"
397
398
399 def test_source_with_method_iterates_policy_chain():
400 with mock.patch("lib.xurl_x.is_available", return_value=False):
401 assert env.get_x_source_with_method({**_COOKIES, "XAI_API_KEY": "k"}) == ("bird", "env")
402 assert env.get_x_source_with_method({"XAI_API_KEY": "k"}) == ("xai", "xai")
403 assert env.get_x_source_with_method(
404 _grok_bot(X_BEARER_TOKEN="b", **_COOKIES)
405 ) == ("xapi", "bearer")
406 assert env.get_x_source_with_method(_grok_bot(**_COOKIES)) == (None, "none")
407
408
409 # ---------------------------------------------------------------------------
410 # Cookie discovery, browsers, and pending-auth on a Grok Bot host (R2)
411 # ---------------------------------------------------------------------------
412
413
414 def test_discovery_returns_before_every_leg_on_grok_bot():
415 config = _grok_bot(FROM_BROWSER="firefox", AGENTCOOKIE="on",
416 BROWSER_CDP_URL="http://127.0.0.1:18800")
417 with (
418 mock.patch("platform.system", return_value="Linux"),
419 _no_cookie_reads(),
420 mock.patch.object(env, "extract_browser_credentials",
421 side_effect=AssertionError("no browser extract on grok-bot")),
422 ):
423 env._discover_and_apply_x_credentials(config)
424 assert "AUTH_TOKEN" not in config
425 assert "TRUTHSOCIAL_TOKEN" not in config
426
427
428 def test_cookie_extraction_browsers_empty_on_grok_bot_unless_bird_pinned():
429 assert env.cookie_extraction_browsers(_grok_bot(FROM_BROWSER="firefox")) == []
430 assert env.cookie_extraction_browsers(_grok_bot(FROM_BROWSER="auto")) == []
431 assert env.cookie_extraction_browsers(
432 _grok_bot(FROM_BROWSER="firefox", LAST30DAYS_X_BACKEND="bird")
433 ) == ["firefox"]
434 assert env.cookie_extraction_browsers({"FROM_BROWSER": "firefox"}) == ["firefox"]
435
436
437 def test_pending_browser_auth_false_on_grok_bot_unless_bird_pinned():
438 cfg = _grok_bot(FROM_BROWSER="chrome", _BROWSER_COOKIE_MODE="plan_only")
439 with (
440 mock.patch("lib.env.get_x_source", return_value=None),
441 mock.patch("lib.bird_x.is_bird_installed", return_value=True),
442 ):
443 assert env.x_pending_browser_auth(cfg) is False
444 assert env.x_pending_browser_auth({**cfg, "LAST30DAYS_X_BACKEND": "bird"}) is True
445
446
447 # ---------------------------------------------------------------------------
448 # Lane and envelope availability (R12, R13, KTD11, AE5a)
449 # ---------------------------------------------------------------------------
450
451
452 def _no_engine_backend():
453 stack = contextlib.ExitStack()
454 stack.enter_context(mock.patch("lib.env.get_x_source", return_value=None))
455 stack.enter_context(mock.patch("lib.env.x_pending_browser_auth", return_value=False))
456 return stack
457
458
459 def test_lane_signal_lists_x_in_read_mode():
460 cfg = {"LAST30DAYS_X_HOST_LANE": "1", "_BROWSER_COOKIE_MODE": "read"}
461 with _no_engine_backend():
462 assert "x" in pipeline.available_sources(cfg)
463 assert pipeline.available_sources(cfg).count("x") == 1
464
465
466 def test_lane_signal_from_process_env_lists_x_but_env_file_line_does_not(tmp_path, monkeypatch):
467 stack = _hermetic_config(tmp_path, monkeypatch, "LAST30DAYS_X_HOST_LANE=1\n")
468 read = env.ConfigLoadPolicy(browser_cookies="read")
469 with stack:
470 _neutral_sources(stack)
471 stack.enter_context(mock.patch.object(env, "_discover_and_apply_x_credentials"))
472 file_only = env.get_config(read)
473 monkeypatch.setenv("LAST30DAYS_X_HOST_LANE", "1")
474 exported = env.get_config(read)
475 with _no_engine_backend():
476 assert "x" not in pipeline.available_sources(file_only)
477 assert "x" in pipeline.available_sources(exported)
478
479
480 def test_envelope_without_lane_signal_lists_x():
481 cfg = {"_BROWSER_COOKIE_MODE": "read"}
482 with _no_engine_backend():
483 assert "x" not in pipeline.available_sources(cfg)
484 assert "x" in pipeline.available_sources(cfg, x_envelope=True)
485
486
487 def test_lane_available_in_every_cookie_mode():
488 for mode in ("off", "read", "plan_only"):
489 cfg = {"LAST30DAYS_X_HOST_LANE": "1", "_BROWSER_COOKIE_MODE": mode}
490 with _no_engine_backend():
491 assert "x" in pipeline.available_sources(cfg), mode
492
493
494 def test_suppress_x_host_lane_hides_lane_but_not_envelope():
495 cfg = {"LAST30DAYS_X_HOST_LANE": "1"}
496 with _no_engine_backend():
497 assert "x" not in pipeline.available_sources(cfg, suppress_x_host_lane=True)
498 assert "x" in pipeline.available_sources(cfg, x_envelope=True, suppress_x_host_lane=True)
499
500
501 def test_lane_signal_uses_precomputed_x_pending_without_calling_predicate():
502 cfg = {"LAST30DAYS_X_HOST_LANE": "1"}
503 with (
504 mock.patch("lib.env.get_x_source", return_value=None),
505 mock.patch("lib.env.x_pending_browser_auth",
506 side_effect=AssertionError("must use precomputed x_pending")),
507 ):
508 assert "x" in pipeline.available_sources(cfg, x_pending=False)
509
510
511 class _Stop(Exception):
512 pass
513
514
515 def _capture_available_sources_kwargs(**run_kwargs) -> dict:
516 """Drive pipeline.run up to its available_sources call and capture the kwargs."""
517 captured: dict = {}
518
519 def fake(config, requested_sources=None, **kw):
520 captured.update(kw)
521 raise _Stop()
522
523 with mock.patch.object(pipeline, "available_sources", side_effect=fake):
524 with pytest.raises(_Stop):
525 pipeline.run(topic="x policy", config={}, depth="quick", **run_kwargs)
526 return captured
527
528
529 def test_run_passes_suppress_flag_through_and_defaults_false():
530 assert _capture_available_sources_kwargs().get("suppress_x_host_lane") is False
531 assert _capture_available_sources_kwargs(
532 suppress_x_host_lane=True
533 ).get("suppress_x_host_lane") is True
534
535
536 def test_comparison_internal_subrun_does_not_suppress_lane():
537 captured = _capture_available_sources_kwargs(internal_subrun=True)
538 assert captured.get("suppress_x_host_lane") is False
539
540
541 def test_discovery_enrichment_pass_suppresses_lane():
542 calls: list[dict] = []
543
544 def fake_run(**kwargs):
545 calls.append(kwargs)
546 raise RuntimeError("stop")
547
548 nomination = pipeline.Nomination(name="Agent SDK Wars", seed_score=1.0)
549 with mock.patch.object(pipeline, "run", side_effect=fake_run):
550 pipeline.enrich_nominations([nomination], config={}, max_workers=1, budget_seconds=5)
551 assert len(calls) == 1
552 assert calls[0]["internal_subrun"] is True
553 assert calls[0]["suppress_x_host_lane"] is True
554
555
556 # ---------------------------------------------------------------------------
557 # diagnose reports the lane as the connector backend
558 # ---------------------------------------------------------------------------
559
560
561 def test_diagnose_reports_connector_when_lane_declared_and_no_backend():
562 cfg = {"LAST30DAYS_X_HOST_LANE": "1", "_BROWSER_COOKIE_MODE": "plan_only"}
563 with (
564 mock.patch("lib.bird_x.get_bird_status", return_value=dict(_BIRD_OFF)),
565 mock.patch("lib.bird_x.is_bird_installed", return_value=False),
566 mock.patch("lib.xurl_x.has_stored_auth", return_value=False),
567 ):
568 diag = pipeline.diagnose(cfg, safe=True)
569 assert diag["x_backend"] == "connector"
570 assert "x" in diag["available_sources"]
571
572
573 def test_diagnose_keeps_engine_backend_when_lane_declared_with_key():
574 cfg = {"LAST30DAYS_X_HOST_LANE": "1", "XAI_API_KEY": "dummy-xai",
575 "_BROWSER_COOKIE_MODE": "plan_only"}
576 with (
577 mock.patch("lib.bird_x.get_bird_status", return_value=dict(_BIRD_OFF)),
578 mock.patch("lib.bird_x.is_bird_installed", return_value=False),
579 mock.patch("lib.xurl_x.has_stored_auth", return_value=False),
580 ):
581 diag = pipeline.diagnose(cfg, safe=True)
582 assert diag["x_backend"] == "xai"
583
584
585 def test_diagnose_without_lane_or_backend_is_none():
586 cfg = {"_BROWSER_COOKIE_MODE": "plan_only"}
587 with (
588 mock.patch("lib.bird_x.get_bird_status", return_value=dict(_BIRD_OFF)),
589 mock.patch("lib.bird_x.is_bird_installed", return_value=False),
590 mock.patch("lib.xurl_x.has_stored_auth", return_value=False),
591 ):
592 diag = pipeline.diagnose(cfg, safe=True)
593 assert diag["x_backend"] is None
594 assert "x" not in diag["available_sources"]
595
596
597 # ---------------------------------------------------------------------------
598 # backends.resolve filters findings and chain by policy (R4 JSON surface)
599 # ---------------------------------------------------------------------------
600
601
602 def _node_ok(name, timeout=health.PROBE_TIMEOUT):
603 return health.DependencyProbe(name=name, status=health.OK, detail=f"{name} 1.0.0")
604
605
606 def _resolve_x(config):
607 with (
608 mock.patch("lib.bird_x.is_bird_installed", return_value=True),
609 mock.patch("lib.bird_x.set_credentials", lambda *a, **k: None),
610 mock.patch("lib.backends.which", return_value=None),
611 mock.patch("lib.health.probe_dependency", _node_ok),
612 mock.patch("lib.xurl_x.has_stored_auth", return_value=False),
613 mock.patch("lib.xurl_x.is_available", return_value=False),
614 ):
615 return backends.resolve("x", config)
616
617
618 def test_resolve_on_grok_bot_carries_only_official_backends():
619 res = _resolve_x(_grok_bot(**_COOKIES, XQUIK_API_KEY="dummy-key"))
620 assert res.chain == ["xapi", "xai", "xurl"]
621 assert [f.name for f in res.findings] == ["xapi", "xai", "xurl"]
622 assert res.active_backend is None
623 blob = str([(f.name, f.detail, f.prescription, f.requires) for f in res.findings])
624 for word in ("AUTH_TOKEN", "CT0", "cookie", "XQUIK", "grok CLI", "grok login"):
625 assert word.lower() not in blob.lower(), word
626
627
628 def test_resolve_on_grok_bot_predicts_xapi_with_bearer():
629 res = _resolve_x(_grok_bot(X_BEARER_TOKEN="dummy-bearer", **_COOKIES))
630 assert res.active_backend == "xapi"
631 assert res.pinned is False
632 assert res.summary.startswith("will use: xapi")
633
634
635 def test_resolve_on_grok_bot_bird_pin_names_bird_only_as_pinned():
636 res = _resolve_x(_grok_bot(**_COOKIES, LAST30DAYS_X_BACKEND="bird"))
637 assert res.pinned is True and res.pin == "bird"
638 assert res.active_backend == "bird"
639 assert "bird" in res.chain
640 assert "xquik" not in res.chain and "grok" not in res.chain
641
642
643 def test_resolve_non_grok_chain_unchanged():
644 res = _resolve_x(dict(_COOKIES))
645 assert res.chain == list(env.X_BACKEND_ORDER + env.X_BACKEND_OPT_IN)
646 assert res.active_backend == "bird"
647 # xapi is opt-in off Grok Bot: an ambient bearer never wins the prediction.
648 res = _resolve_x({"X_BEARER_TOKEN": "dummy-bearer"})
649 assert res.active_backend is None
650 res = _resolve_x({"X_BEARER_TOKEN": "dummy-bearer", "LAST30DAYS_X_BACKEND": "xapi"})
651 assert res.active_backend == "xapi" and res.pinned is True
652
653
654 def test_xapi_probe_is_key_presence_only():
655 finding = backends._X_PROBES["xapi"]({"X_BEARER_TOKEN": "dummy-bearer"})
656 assert finding.status == "ok"
657 assert finding.requires == "X_BEARER_TOKEN (X API v2)"
658 assert "dummy-bearer" not in finding.detail
659 missing = backends._X_PROBES["xapi"]({})
660 assert missing.status == "missing"
661 assert "xapi" in backends._X_PAID
662 assert backends._X_REQUIRES["xapi"] == "X_BEARER_TOKEN (X API v2)"
663
663 lines PYTHON