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
70
71
72
73
74
75
76
77
78
79
# Gemini readiness manifest (E6.3) - declarative port of the hardcoded
# `GeminiReadinessDetector` / `prompt_ready` in `readiness.rs`.
#
# Identical in rule shape to codex.toml today (gemini shares PROMPT_GLYPHS and
# the same prompt_ready logic). Kept as its own file because manifests resolve
# per agent id and these WILL diverge when each is pinned against its live TUI;
# collapsing them would break the per-agent resolution the engine relies on.
#
# The load-bearing case (design Open Question #3): gemini's "Waiting for auth"
# is a known FALSE-READY - a prompt glyph is on screen but the CLI is at an auth
# wall. The auth_wall rule (priority 980, above idle_prompt's 100) is what keeps
# it from badging idle. See readiness.rs WALL_MARKERS.
#
# State vocabulary + arbitration: see codex.toml header (same contract).
#
# ponytail: glyphs/markers mirror readiness.rs; pin against a live gemini TUI
# (capture-readiness-grid.sh) when E2 lands. Conservative bias: a wrong glyph is
# false-NOT-ready, never false-ready.
[[]]
= "auth_wall"
= "blocked"
= 980
= "bottom_non_empty_lines(3)"
= { = [
{ = "Waiting for auth" },
{ = "waiting for auth" },
{ = "Do you trust" },
{ = "Login required" },
] }
[[]]
= "busy"
= "working"
= 900
= "bottom_non_empty_lines(3)"
= { = [
{ = "esc to interrupt" },
{ = "Esc to interrupt" },
{ = "Working" },
{ = "Thinking" },
] }
[[]]
= "idle_prompt"
= "idle"
= 100
= "bottom_non_empty_lines(1)"
= { = '[\x{276f}\x{203a}\x{2595}][ \t]*$' }
# Answerable numbered prompt (x-5103). Gemini's trust prompt renders a BOXED
# numbered radio ("│ ● 1. Trust folder … │" / "│ 2. … │" / "│ 3. Don't trust │"):
# a left/right box border (│ U+2502) frames each line and the selected row
# carries a "●" (U+25CF) radio marker. Distinct from codex.toml (borderless, ›
# marker) - the divergence the per-agent split exists for. Validated against a
# live gemini TUI (fresh untrusted dir): the bare digit COMMITS and advances to
# the next screen, so send="digit"; digit_enter would leak a CR into that next
# prompt. Region is 12 (not codex's 10) because gemini's box padding lines count
# as non-empty, pushing the "Do you trust" question further up the window. The
# option regex consumes the optional border + radio marker before the digit and
# an optional trailing border after the label. Gated on the trust question AND a
# MARKED numbered line: the gate's line_regex REQUIRES the "●" radio glyph before
# the digit (the answer regex below keeps it optional to extract every option). A
# live radio always draws "●" on its current choice; a model reply printing "Do
# you trust …" plus a plain numbered list has no "●" before those digits, so it
# can't fake the gate and inject a digit into the composer (codex review P2). A
# bare auth wall keeps its focus-only auth_wall fallback.
[[]]
= "trust_prompt"
= "blocked"
= 985
= "bottom_non_empty_lines(12)"
= { = [
{ = [ { = "Do you trust" }, { = "do you trust" } ] },
{ = '^\s*\x{2502}?\s*\x{25cf}\s*[0-9]\.\s' },
] }
[]
= '^\s*\x{2502}?\s*\x{25cf}?\s*(?P<idx>[0-9])\.\s+(?P<label>.+?)\s*\x{2502}?\s*$'
= "digit"