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
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
//! `RCH_*_INJECT_*` test-injection env-var registry (br-62u24.13 — MVP).
//!
//! This module is the **single source of truth** for the names of every
//! debug/test injection environment variable consumed by RCH binaries.
//! The bead spec for 62u24.13 calls out the foundation problem:
//!
//! > In the cross-agent code-review work (commits `68fcb7c` + d6d086e
//! > and the 21 sibling beads in epics `2s99h`, `62u24`, `zcecy`), every
//! > e2e test script and many unit tests reference debug-only env-var
//! > hooks and `rch debug *` subcommands that don't exist in the
//! > codebase yet. Without a foundational bead defining the contract
//! > for these primitives, each task-bead implementer will arbitrarily
//! > reinvent its own conventions — resulting in inconsistent naming,
//! > duplicate functionality, missing `#[cfg(debug_assertions)]` gates,
//! > and accidental release-build leakage.
//!
//! By defining the canonical names HERE as `pub const NAME_OF_VAR:
//! &str = "RCH_..."` items, downstream tests can write
//! `std::env::var(injection::RCH_DOCTOR_INJECT)` instead of
//! `std::env::var("RCH_DOCTOR_INJECT")` — a typo in the latter is a
//! silent no-op, but the former is a compile error.
//!
//! # Discipline (the contract this module enforces)
//!
//! 1. **All injection env-var names are `pub const NAME: &str` items
//! here.** Adding a new injection point requires adding the const,
//! not coining a new name at the consumer site.
//! 2. **All names match the regex `RCH_[A-Z][A-Z0-9_]*_INJECT(_[A-Z0-9_]+)?`.**
//! The `RCH_` prefix is owned by us; the `_INJECT` segment is the
//! discriminator that lets release-build audits grep for "did any
//! injection name leak into the binary?".
//! 3. **`ALL_INJECTION_VARS` enumerates every defined const.** The
//! unit tests at the bottom of this module assert (a) no duplicate
//! values, (b) every value matches the naming regex, (c) the slice
//! length equals the number of `pub const` items in this file.
//! Adding a new const without updating `ALL_INJECTION_VARS` is a
//! test failure.
//! 4. **Release-build gate is the consumer's responsibility.** This
//! module exports names, not behavior. Each call site that reads
//! one of these env vars must gate the read with
//! `#[cfg(debug_assertions)]` (or document an explicit reason if a
//! release-build read is intentional). This module's name-only
//! surface is itself safe to compile in release.
//!
//! # Scope of this MVP delivery
//!
//! Lands the registry surface (names + enumeration + naming validator)
//! that every other bead can immediately consume. The companion
//! deliverables from 62u24.13 — `rch debug` subcommand convention,
//! `request_id` propagation, tracing-capture test helper, the
//! `#[cfg(debug_assertions)]` gate audit — are filed as follow-up
//! scope. Each is independently substantial; the registry is the
//! minimum that unblocks the rest.
// =============================================================================
// Doctor-domain injections
// =============================================================================
/// Inject a synthetic reliability-doctor diagnostic at the named code
/// path. Value is a free-form discriminator (e.g.,
/// `disk_pressure_warn`, `topology_circuit_open`) interpreted by the
/// consumer; an empty/unset value disables the injection.
pub const RCH_DOCTOR_INJECT: &str = "RCH_DOCTOR_INJECT";
/// Inject a specific status-circuit state for a synthetic worker
/// (e.g., `open_forced`). Used by reliability-doctor tests that need
/// to exercise the partial-outage code path without spinning up a
/// real fleet.
pub const RCH_DOCTOR_INJECT_STATUS_CIRCUIT: &str = "RCH_DOCTOR_INJECT_STATUS_CIRCUIT";
/// Inject artificial latency into a specific reliability probe. Value
/// format: `<probe_name>=<delay_ms>` (e.g., `helpers=10000`). Used to
/// exercise the per-probe timeout path (bd-62u24.8 parallelism).
pub const RCH_DOCTOR_INJECT_SLOW_PROBE: &str = "RCH_DOCTOR_INJECT_SLOW_PROBE";
// `RCH_DOCTOR_FIXTURE` and `RCH_DOCTOR_VERDICT` are STATE PINS, not
// injections — they replace runtime state with a static value rather
// than inserting a synthetic event into a live code path. They are
// scoped to a sibling "fixture-pin registry" in a follow-up bead; the
// naming-policy validator in this module would reject them anyway
// (no `_INJECT` segment). Listing them here as a comment so a future
// reader doesn't re-derive the same separation.
// =============================================================================
// Quick-check / status injections
// =============================================================================
/// Inject a synthetic stall on a specific worker's quick-check probe.
/// Value is the worker ID (e.g., `w1`).
pub const RCH_QC_INJECT_STALL: &str = "RCH_QC_INJECT_STALL";
/// Force every worker's quick-check probe to stall (value `1`). Used
/// by integration tests that need the "everything timing out" branch
/// of the status surface.
pub const RCH_QC_INJECT_STALL_ALL: &str = "RCH_QC_INJECT_STALL_ALL";
// =============================================================================
// Fix-mode injections (consumed by br-2s99h.12 --fix executor follow-up)
// =============================================================================
/// Inject a remediation step whose `dry_run_safe == false` so the
/// `--fix` executor exercises the `SkippedNotSafe` outcome path
/// without a real unsafe remediation in the registry.
pub const RCH_FIX_INJECT_UNSAFE: &str = "RCH_FIX_INJECT_UNSAFE";
/// Force the fix executor's post-validation step to fail even when
/// remediation succeeded, so tests can exercise the
/// `FailedPostValidation` outcome branch.
pub const RCH_FIX_INJECT_POST_FAIL: &str = "RCH_FIX_INJECT_POST_FAIL";
// =============================================================================
// Debug / panic injections
// =============================================================================
/// Force the timing-cache save path to fail (value `1`) so tests can
/// confirm the hook's fail-open behavior under disk-error conditions.
///
/// Naming note: the bead spec referenced this as
/// `RCH_DEBUG_TIMING_SAVE_FAIL` (no `_INJECT` segment). The registry
/// names it with `_INJECT_` per the canonical naming policy so a
/// release-build leak audit can grep for `_INJECT` reliably. No
/// existing consumer reads either name as of this commit, so no
/// migration shim is needed.
pub const RCH_DEBUG_INJECT_TIMING_SAVE_FAIL: &str = "RCH_DEBUG_INJECT_TIMING_SAVE_FAIL";
/// Trigger an intentional panic at a designated code path (value
/// `1`). Used by the hook fail-open regression suite to confirm that
/// classifier panics are caught and the hook still exits 0 (the
/// project's #1 invariant per AGENTS.md).
///
/// Naming note: bead spec used `RCH_PANIC_TEST`; canonical name uses
/// `_INJECT_` per the registry's naming policy.
pub const RCH_DEBUG_INJECT_PANIC: &str = "RCH_DEBUG_INJECT_PANIC";
// =============================================================================
// Registry & validators
// =============================================================================
/// Every injection env-var name registered in this module. Consumed
/// by release-build leak audits, fuzzers, and the `rch debug` (TBD)
/// subcommand's introspection surface.
///
/// **Discipline**: adding a new `pub const RCH_..._INJECT...: &str = "..."`
/// requires appending its identifier here. The unit tests assert the
/// slice length matches the number of `pub const` items, so a
/// forgotten append is a test failure at `cargo test` time.
pub const ALL_INJECTION_VARS: & = &;
/// Returns `true` if `name` is one of the registered RCH injection
/// env-var names. Used by audit tools that scan process environments
/// for stray injection settings and by the (TBD) `rch debug
/// list-injections` introspection surface.
/// Returns `true` if `name` is shape-compatible with the project's
/// injection naming policy: starts with `RCH_`, contains `_INJECT`
/// somewhere after the prefix, and consists only of ASCII uppercase /
/// digits / underscores. Used by the unit tests below to enforce the
/// naming regex without pulling in the `regex` crate (this is a
/// `const`-friendly check on a small alphabet).