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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
//! The `models.yaml` half of the §9.4 block grammar: declaring a model the
//! operator picked from a live `bz --list-models` roster, and **reading back**
//! what the file declares so a dead entry can be caught (§9.2 Apply gate,
//! §9.4 role rows).
//!
//! Its whole reason to exist is lernie's cross-check — a role naming a model
//! `models.yaml` does not declare is a hard load error, so the picker writes
//! this half FIRST and the assignment second (§9.4). What brazen did not
//! publish for the picked row is written as a **declared default, not a
//! discovery**, under a comment that says so — and what it *did* publish is
//! written as the provider's own number, under a comment that says that
//! instead (bl-848f).
//!
//! The reader is the same anchored grammar as [`roles`](super::roles), applied
//! to the other file: `provider:` on a model entry is a brazen provider-row
//! NAME, so it is checkable against brazen's own effective table
//! ([`BzRunner::providers`](crate::config_edit::brazen::BzRunner::providers))
//! and, since bl-53be, is checked at both the §9.2 write and the §9.4 read.
use ;
/// The context window yog declares for a model **whose provider served none**
/// (§9.4). brazen publishes one only for the providers that serve it on their
/// list GET (Google today; Anthropic, OpenAI and Ollama serve none), so this is
/// a **declared default, not a discovery** — deliberately conservative, because
/// under-stating a window degrades to early compaction where over-stating it
/// overflows the request.
///
/// **It is no longer unread.** Since bl-a48b the declared window is the
/// denominator of §5.1 #35's context-fullness figure ([`context_windows`]), so
/// a wrong default shows up as a wrong percentage. Since bl-848f it is also no
/// longer written over a number brazen had already served: the picker seeds the
/// entry from `Model.context_window` wherever the roster carried one
/// ([`crate::model_pick::query::served_window`]) and falls back to this only
/// where nobody published a window at all.
pub const DEFAULT_CONTEXT_WINDOW: u32 = 200_000;
/// The comment yog writes above a generated entry whose window nobody served,
/// so the two declared-default fields are never mistaken for facts brazen
/// published (§9.4).
const DECLARED_NOTE: &str = " # added by yog's model picker from `bz --list-models`.\n \
# this provider publishes no capabilities or context window, so the two\n \
# lines below are declared defaults, not discoveries — edit them here.";
/// The comment for an entry whose window **is** the provider's own, carried
/// through the roster the pick was made from (bl-848f). A true number under the
/// declared-default note would be the same defect one step over: the operator
/// could not tell what was served from what was guessed.
const SERVED_NOTE: &str = " # added by yog's model picker from `bz --list-models`.\n \
# context_window is the number this provider served; capabilities it does\n \
# not publish, so that line is a declared default — edit either here.";
/// The `models.yaml` entry for a model discovered live, at two-space indent.
/// `served` is the provider's own context window where the roster carried one.
/// Declare `model` on `provider` under the global `models:` block.
/// `Ok(None)` means nothing to write — the id is already declared **on this
/// same row**, and the operator's own capabilities/context window stand
/// untouched.
///
/// An id already declared on a *different* row has only its one `provider:`
/// line rewritten (bl-bd89). lernie refuses a config whose
/// `models.<m>.provider` differs from the `roles.<r>.provider` naming it, so
/// leaving a stale row here would brick the workspace just as surely as leaving
/// the model undeclared — the two are one fact, and the picker writes it once.
/// Everything else in the entry is the operator's and is preserved.
///
/// The entry is inserted **directly after the `models:` line**, not at EOF, so
/// a file that carries a later top-level key (`adapter:`) stays valid. A file
/// with no `models:` key at all gets one appended; an inline `models: {}` is
/// refused rather than transformed.
///
/// `served` is the context window the roster this pick was made from carried
/// for `model`, `None` where the provider published none (bl-848f). It seeds a
/// **new** entry only: a declaration that already exists keeps the window it
/// carries, because an operator's edited value wins over any discovery.
/// One `models:` entry as the file declares it: the model id and the brazen
/// provider-row name it points at (§4.1 of lernie's own header — "`provider:`
/// on each model is a brazen provider-row NAME").
/// Every model the file declares, in file order — the mirror of
/// [`roles`](super::roles) over the other file. An entry with no `provider:`
/// line is omitted: it names no row, so it can name no *wrong* row, and
/// lernie's own loader is the authority on a half-written entry.
/// Every declared model's **wire id** paired with the `context_window` its
/// entry declares (§9.2's own field, §5.1 #35) — the denominator of the
/// context-fullness figure, and the one home for it.
///
/// Keyed on `model_id`, falling back to the entry key when the entry declares
/// none, because the id a step's `request.json` names is the wire id lernie
/// sent — not the alias the entry is filed under. An entry with no
/// `context_window:` line, an unparseable one, or a zero is **absent from the
/// map**: a window nobody declared is unknown, and a percentage against a
/// fabricated denominator is exactly the capability theater the figure exists
/// to avoid (brazen's Usage zero-vs-unknown principle, applied one field over).
///
/// **Why the declaration and not brazen's discovery.** brazen carries
/// `Model.context_window` on `--list-models` for the providers that serve one
/// (Google), and `None` for the ones that do not (Anthropic, OpenAI, Ollama) —
/// its own empty-set rule: *"a harness hand-configures only what no provider
/// serves"*. `models.yaml` **is** that hand-configuration: lernie's declared
/// field, written by the §9.4 picker, edited by the §9.5 form. One home, one
/// number, operator-correctable — where reading brazen's cache *as well* would
/// be two representations of one fact, drifting the moment either moves.
/// **The** provider-row judgement: does `provider` name no row in brazen's
/// effective table? Every site that asks it asks it here — the §9.2 Apply gate
/// over `models.yaml` ([`unknown_rows`]), the §9.4 pick gate
/// ([`plan`](crate::model_pick::plan)), and the §9.5 pane's provider control
/// over both files ([`crate::config_edit::form`]) — so the three can never
/// disagree. Every one of them judges a file against the wall of the workspace
/// that holds it; the retired birth gate (bl-c3a9, retired bl-00ee) is the one
/// site that asked it where no wall existed yet.
///
/// `providers` is `bz --list-providers`' answer (built-ins included, which a
/// scan of `config.toml` would miss). An **empty** table is no answer rather
/// than an empty one — brazen could not be asked — so it judges nothing: no
/// surface may refuse on the strength of a question that went unanswered.
/// The declared entries whose `provider:` names no row in brazen's effective
/// table — the §9.2 Apply gate's whole judgement, one [`is_unknown_row`] per
/// entry.
///
/// A file with no `models:` block declares nothing and is therefore always
/// clean, which is why the gate can run over every §9.2 file (a
/// `workflows/*.yaml` simply has nothing to check) instead of branching on
/// which file is open.
/// Why `model` cannot be fired as `models.yaml` stands, or `None` when it is
/// usable (§9.4 role rows). Two faults, because lernie refuses the config for
/// either: the id is not declared at all, or it is declared on a provider row
/// brazen's table does not have.