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
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
//! The ONE intrinsic effect table (issue #1128).
//!
//! `infer::body::InferPass::infer_intrinsic` harvests each unresolved
//! stdlib-intrinsic call's effect atoms — the faulting set (NS-A2's fault
//! dimension) and the RNG-cell write set (NS-A6's "every draw is an ordinary
//! write") — and `await_purity` consults the same facts for an unresolved
//! call sitting *directly in* an `await` condition (the wake-gate gap
//! NS-A6's build disclosed: `await chance(0.5)` / `await pop(a)` escaped
//! E105 because the purity walk only judged resolved callees' rows). Both
//! consumers read this module so there is exactly one list — no second copy
//! to drift.
//!
//! Membership notes (the audits live on `infer_intrinsic`'s original
//! comments, summarized here):
//!
//! - **Faults**: every intrinsic whose VM op has at least one
//! turn-terminating fault path — the conversion faults (`int`/`float`,
//! and the classic uppercase `INT`/`FLOAT` builtins since #955),
//! `char_at`'s OOB/wrong-type faults, the NS-A1 `StdlibWrongType`/
//! `NotOrderable` verbs, the collection ops' `NotIndexable`/key-domain
//! faults, and the NS-A6 rand verbs' wrong-type faults. NOT in the set:
//! `string`/`some` (total over every value), `seed` (the frozen
//! `SeedRandom` op coerces, ink-heritage leniency), the nullary `float()`
//! rand draw (no argument, no fault path), and `call`/`bind` (their
//! dispatch-fault marking lives at `check_value_call`/`check_bind_value`).
//! NS-A5 adds `non_empty` (wrong-typed argument faults, the
//! malformed-question doctrine).
//! - **RNG writes** (draws): the brink draw verbs (`chance`/`pick`/
//! `shuffle`/`shuffled`, nullary `float()`) plus `seed` and the frozen ink
//! spellings (`RANDOM`/`SEED_RANDOM`/`LIST_RANDOM`) — one cell
//! ([`brink_format::DefinitionId::RNG_CELL`]), two surfaces, one entry.
//! NS-A5's `int(range)` draw leg is deliberately NOT here: it is
//! type-directed (range argument → draw, else pure conversion), which a
//! name+arity table cannot express — `infer_intrinsic`'s `"int"` arm
//! records that write inline. `await_purity` still rejects
//! `await int(…)` through this table's fault bit (`int` faults in every
//! shape), so the wake gate has no gap.
/// Effect facts for one intrinsic call shape. `arg_count` participates
/// because `float` is two different call shapes: the nullary rand draw
/// (an RNG write, no fault path) vs the unary conversion (a fault path,
/// no draw).
pub
/// The effect facts for an unresolved single-segment call named `name` with
/// `arg_count` arguments — the intrinsic-dispatch shadow-fallback shape (a
/// resolved def always wins resolution first, so a caller must check the
/// resolution map before consulting this table). A name outside the table
/// returns all-`false`.
pub
/// NS-A4 / **F29(a)** (ruled by delegation 2026-07-19, stdlib-spec §4b):
/// whether an intrinsic call's fault charge is **discharged by local type
/// evidence** — the call is provably total given the arguments' inferred
/// types, so the *refined* faults bit (`EffectRow::faults_refined`) skips
/// it while the conservative bit keeps it.
///
/// The audit, verb by verb (anything not listed keeps its charge):
///
/// - **Wrong-type-only faults** discharge when the container/argument type
/// provably matches: `len` (array/map/string), `keys`/`values`/`clear`/
/// `contains_value` (map), `contains`/`index_of`/`first`/`last`/`pop`/
/// `push` (array — `push` appends at `len`, always in bounds), `find`
/// (two strings), `get` (map with a scalar key type).
/// - **`min`/`max` (one-arg) and `sort`/`sorted`** additionally require a
/// provably NaN-free *element* type — int/string/bool, NOT float: §4b
/// makes float orderings carry `faults` unconditionally
/// (mode-independent rows; the dev-mode NaN fault is real). Nested
/// arrays are conservatively kept (the recursive roster check belongs
/// to a finer rung).
/// - **Never discharged** (value-dependent or parse-domain faults):
/// `insert`/`remove_at` (OOB — issue #1484 split `remove_at` off `remove`
/// for exactly this array-index posture), `remove` (invalid-domain map
/// key), `char_at` (OOB), `int`/`float`/`INT`/`FLOAT` (parse/domain),
/// `chance`/`pick`/`shuffle`/`shuffled` (wrong-type but rand-coupled —
/// kept simple), `non_empty`, the tower family, `sort_by`/`sorted_by`
/// (comparator dispatch + `⊕cmp`), and every fn-value verb —
/// `map`/`filter`/`fold`/`filter_map`/`each`/`map_each` (callback
/// dispatch + `⊕f` — the callback's own faults are never local type
/// evidence, pure or effectful alike).
pub
/// Whether the intrinsic named `name` returns `Option[…]` — the NS-A1
/// absence-shaped verbs plus the `some` constructor and NS-A6's `pick`.
/// Consulted by `option_conditions` (F27/E116) for a direct
/// intrinsic call in condition position; the authoritative per-verb typing
/// rules (element narrowing included) remain `infer_intrinsic`'s arms —
/// this is only the Option-ness bit, kept next to the effect table so the
/// intrinsic facts live in one module.
pub