1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
//! Auth-shaped step-failure classification (DESIGN §8.3 detection, §15 M6 Z8): a
//! pure predicate over the already-derived step facts (§5.1 #10/#13 — framing
//! Failed + the response/error text) deciding whether a failed step *looks* like a
//! credential / authorization problem, so the Login affordance surfaces one click
//! away (beside the failed step and in the toolchain pane). Shell paints; this is
//! covered logic — the steps view-model reads [`is_auth_failure`] into its Login
//! flag.
use crateerror_text;
/// Case-insensitive substrings that mark an **auth-shaped** failure — the
/// credential / auth / 401 / 403 / permission-denied class (§8.3). Matched against
/// the raw error event line ([`error_text`]), so both an HTTP status code and its
/// reason phrase catch. Deliberately narrow so a transport reset or a 500 never
/// fires this: bare `auth` is **excluded** (it hits `author`); the tokens are the
/// full `authenticat` / `authoriz` / `authoris` stems, and every other marker
/// names a genuinely auth-related concept.
const AUTH_MARKERS: & = &;
/// Does `error_line` (a raw JSONL error event) look auth-shaped? Pure,
/// case-insensitive substring match against [`AUTH_MARKERS`].
/// Whether a step's settled `response.json` is an **auth-shaped failure** (§8.3):
/// its framing is Failed (an error event settled the last segment) **and** that
/// error text matches [`looks_auth`]. [`error_text`] returning `Some` already
/// means framing Failed (they share the last-segment traversal), so one call
/// answers both facts — the single source the steps view-model reads for its
/// Login flag.
/// Whether an agent's **latest** step is an auth-shaped failure (§11 center):
/// the conversation-view detection that banners Login inline. Reads through the
/// steps view-model ([`crate::steps_view::build`] — the one owner of the
/// per-step Login flag), so the banner, the Steps tab, and the toolchain pane
/// all derive from the same classification. `state` is that build's §3.5
/// liveness argument, which this predicate itself does not consult: an
/// auth-shaped failure is settled error bytes, and settled bytes are the same
/// whoever holds the lock.