tatara-process 0.2.631

Process CRD — K8s clusters, workloads, migrations, tests as Unix processes in the tatara convergence lattice
Documentation
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
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
//! Substrate primitive over `Result<T, E>` for any `E: `[`std::fmt::
//! Display`] — the ONE substrate owner of the generic `.map_err(|e|
//! anyhow::anyhow!("<ctx>: {e}"))` display-prefix wrap-shape.
//!
//! Every one of the sibling per-error-type peers ([`crate::kube_error::
//! KubeResultExt`], [`crate::anyhow_flatten::FlattenCtxExt`],
//! [`crate::hostname::HostnameResultExt`]) delegates its body onto
//! this trait's `err_ctx` / `err_ctx_with` — the specialized peers
//! stay for the naming discipline (each name is deliberately DISTINCT
//! from [`anyhow::Context::context`] to prevent silent resolution to
//! the chain-wrap semantics that would drop the source error's
//! `Display` output from every `tracing::error!(error = %e, ...)`
//! log line), but the byte-shape body itself lives at ONE substrate
//! owner here. Pre-lift each peer restated the SAME
//! `.map_err(|e| anyhow::anyhow!("{ctx}: {e}"))` closure by hand,
//! pinned equal only by peer-side byte-shape tests; post-delegation
//! byte-shape agreement holds by CONSTRUCTION and the cross-peer
//! agreement tests in this module ([`tests::err_ctx_agrees_with_kube_ctx_on_kube_error_result`],
//! [`tests::err_ctx_agrees_with_flatten_ctx_on_anyhow_result`],
//! [`tests::err_ctx_agrees_with_hostname_ctx_on_hostname_error_result`],
//! plus the `_with` peers) route the delegation invariant through
//! this substrate.
//!
//! Peer of the type-specific flatten-wrap trait trio already in this
//! crate on the same display-prefix wrap axis, partitioning the space
//! by SPECIFICITY:
//!
//! * [`crate::kube_error::KubeResultExt::kube_ctx`] — the specialized
//!   peer for `Result<T, kube::Error>`, kept because
//!   [`kube::Error`]'s `Display` composes the request URI + status
//!   line in a shape every reconciler-side callsite already greps on.
//! * [`crate::hostname::HostnameResultExt::hostname_ctx`] — the
//!   specialized peer for `Result<T, `[`crate::hostname::HostnameError`]`>`,
//!   kept because the [`thiserror`]-derived `Display` output matches
//!   the pre-lift hand-authored render_routing log stream verbatim.
//! * [`crate::anyhow_flatten::FlattenCtxExt::flatten_ctx`] — the
//!   specialized peer for `anyhow::Result<T>`, kept because it
//!   collides with [`anyhow::Context::context`]'s naming so the
//!   distinct-method-name discipline (flatten-prefix vs. chain-wrap
//!   semantics) is load-bearing at every phase-machine callsite.
//! * [`ErrCtxExt::err_ctx`] (this trait) — the shared substrate body
//!   the three specialized peers delegate onto, AND the reachable
//!   surface for any new consumer whose source error is a fresh
//!   [`crate::tagged_union::declare_tagged_union_error`]-derived
//!   variant (e.g. [`crate::export::ArtifactError`],
//!   [`crate::intent::IntentError`],
//!   [`crate::lifetime::LifetimeError`]). Such a consumer reaches the
//!   display-prefix wrap-shape mechanically at THIS ONE substrate
//!   owner instead of opening a fourth per-error-type peer trait for
//!   every fresh [`thiserror`]-derived enum.
//!
//! Pre-lift the shape was hand-authored at TWO
//! `tatara-export-worker/src/main.rs` sites past the ★★ PRIME-DIRECTIVE
//! ≥ 2 duplication threshold, both restating the SAME closure —
//! capture an [`crate::export::ArtifactError`] returned by the
//! substrate primitive [`crate::export::ArtifactSource::variant`],
//! prepend the identical static context slug `"source"`, delegate
//! the tail to [`std::fmt::Display`] via the `{e}` slot — differing
//! in NOTHING but their line numbers. Post-lift both callsites read
//! `spec.source.variant().err_ctx("source")?` and the wrap-shape
//! lives at ONE substrate owner here.
//!
//! ### Naming — `err_ctx`, not `context`
//!
//! Same discipline as the three specialized peers: the method name
//! `err_ctx` is deliberately DISTINCT from [`anyhow::Context::context`]
//! so a caller with [`anyhow::Context`] in scope can never resolve to
//! the wrong method (which chain-wraps rather than display-prefix-
//! flattens, and would silently drop the underlying error detail from
//! every downstream `tracing::error!(error = %e, ...)` log line whose
//! formatter interpolates `{e}` rather than the chain-walking `{e:#}`).
//!
//! ### Two flavors: `err_ctx` + `err_ctx_with`
//!
//! * [`ErrCtxExt::err_ctx`] takes a `&'static str` context — the
//!   most common shape (`"source"` at the two export-worker
//!   callsites). Static binding keeps the compile-time contract that
//!   the context slug is a bare literal, no allocation, no dynamic
//!   content leaking into an error stream downstream operators grep
//!   on.
//! * [`ErrCtxExt::err_ctx_with`] takes an owned [`String`] context —
//!   the escape hatch for future consumers that compose the slug via
//!   [`format!`] (e.g. a dynamic per-variant-name slug the way
//!   [`crate::anyhow_flatten::FlattenCtxExt::flatten_ctx_with`]
//!   already services for `phase_machine::evaluate_conditions`).
//!
//! ### `#[must_use]`
//!
//! Every consumer threads the `?` short-circuit onto its handler's
//! `anyhow::Result<_>` return — dropping the wrap swallows the
//! underlying failure entirely, which is never the intended
//! semantic.
//!
//! Theory anchor: THEORY.md §VI.1 (generation over composition — the
//! generic display-prefix wrap-shape recurred at two byte-identical
//! hand-authored sites in `tatara-export-worker/src/main.rs` past
//! the ★★ PRIME-DIRECTIVE ≥ 2 duplication trigger, and is lifted to
//! ONE substrate owner here). THEORY.md §II.1 invariant 5
//! (composition preserves proofs — a regression that drifts the
//! display-prefix separator or the byte-shape surfaces here at the
//! substrate pin rather than as silent operator-facing skew across
//! every downstream `err_ctx` consumer).

/// Substrate extension trait over `Result<T, E>` for any `E: `
/// [`std::fmt::Display`] — the ONE substrate owner of the generic
/// `.map_err(|e| anyhow::anyhow!("<ctx>: {e}"))` display-prefix
/// wrap-shape for consumers whose source error is a bare `Display`
/// type NOT already covered by a per-error-type flatten-wrap peer.
/// See the module docs for the specialized-peer partition + the
/// naming rationale (why `err_ctx` and not `context`).
pub trait ErrCtxExt<T>: Sized {
    /// Wrap the source error (if any) with a static context prefix,
    /// producing an [`anyhow::Result`] whose error `Display` reads
    /// exactly `"<context>: <source display>"`.
    #[must_use = "an error wrap that isn't threaded via `?` swallows the underlying failure"]
    fn err_ctx(self, context: &'static str) -> anyhow::Result<T>;

    /// Owned-string peer of [`Self::err_ctx`] — the escape hatch for
    /// consumers that compose the context slug via [`format!`].
    #[must_use = "an error wrap that isn't threaded via `?` swallows the underlying failure"]
    fn err_ctx_with(self, context: String) -> anyhow::Result<T>;
}

impl<T, E> ErrCtxExt<T> for Result<T, E>
where
    E: std::fmt::Display,
{
    #[inline]
    fn err_ctx(self, context: &'static str) -> anyhow::Result<T> {
        self.map_err(|e| anyhow::anyhow!("{context}: {e}"))
    }

    #[inline]
    fn err_ctx_with(self, context: String) -> anyhow::Result<T> {
        self.map_err(|e| anyhow::anyhow!("{context}: {e}"))
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    // A representative bare-`Display` error type — matches the shape
    // of [`crate::export::ArtifactError`] (the concrete
    // [`thiserror`]-derived error whose two pre-lift callsites drove
    // this lift) without pulling the whole export module into the
    // test surface. A regression that promotes the trait bound to
    // e.g. `E: std::error::Error` would surface HERE (this type
    // doesn't impl `Error`) rather than as a silent narrowing of the
    // substrate's admissibility surface.
    #[derive(Debug)]
    struct DisplayErr(&'static str);
    impl std::fmt::Display for DisplayErr {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            f.write_str(self.0)
        }
    }

    // ─── ErrCtxExt::err_ctx substrate pins ───────────────────────────
    //
    // Fail-before-pass-after granularity: the `ErrCtxExt::err_ctx`
    // trait method did not exist before this commit, so each test
    // below fails to compile pre-lift. Post-lift they collectively
    // pin the display-prefix wrap-shape at ONE substrate owner — a
    // regression that drifts the separator, swaps the two slots,
    // narrows the trait bound (`E: Error` in place of `E: Display`,
    // ruling out today's `ArtifactError` and similar bare-Display
    // enums that don't derive `Error`), or promotes the pass-through
    // arm to a synthesis surfaces HERE rather than as silent
    // operator-facing skew across the two export-worker pre-lift
    // consumers whose log output already encoded the flat
    // `"source: <ArtifactError display>"` shape.

    #[test]
    fn err_ctx_static_str_context_matches_pre_lift_format_bytewise() {
        // Byte-shape parity pin: the wrap output of
        // `err_ctx("<slug>")` MUST be `Display`-identical to the
        // pre-lift hand-authored `.map_err(|e| anyhow!("<slug>:
        // {e}"))` chain. A regression that inserted a separator
        // character (`"<slug>:: <err>"`), dropped the space after
        // the colon, or swapped the two slots (`"<err>: <slug>"`)
        // surfaces HERE rather than as silent drift at every
        // downstream log-output consumer.
        let raw: Result<(), DisplayErr> = Err(DisplayErr("bad slot"));
        let via_trait = raw.err_ctx("source").unwrap_err();
        assert_eq!(format!("{via_trait}"), "source: bad slot");
    }

    #[test]
    fn err_ctx_ok_arm_is_a_pure_passthrough() {
        // Ok-arm invariant: `err_ctx` on `Ok(t)` MUST return `Ok(t)`
        // verbatim — no side-effect on the payload, no synthesis of
        // a context-tagged error. Peer to the Err-arm byte-shape
        // pin; a regression that promoted the Ok arm to ALWAYS
        // produce a synthesis Error would silently break every
        // successful downstream primitive call in the pre-lift
        // consumer set.
        let raw: Result<i32, DisplayErr> = Ok(42);
        assert_eq!(raw.err_ctx("noop").unwrap(), 42);
    }

    #[test]
    fn err_ctx_with_owned_string_matches_pre_lift_format_bytewise() {
        // Owned-string peer's byte-shape pin — same discipline as
        // the static-`&str` peer above. Future consumers that
        // compose the context slug via `format!` route through this
        // method and inherit the SAME display-prefix discipline as
        // the static-slug peer, so mixing the two forms across a
        // consumer's log stream never surfaces as a format-string
        // skew.
        let raw: Result<(), DisplayErr> = Err(DisplayErr("bad slot"));
        let dynamic_slug = format!("evaluate {:?}", "SomeVariant");
        let via_trait = raw.err_ctx_with(dynamic_slug.clone()).unwrap_err();
        assert_eq!(format!("{via_trait}"), format!("{dynamic_slug}: bad slot"));
    }

    #[test]
    fn err_ctx_with_ok_arm_is_a_pure_passthrough() {
        // Ok-arm invariant on the owned-string peer — sibling to
        // the static-slug pin above.
        let raw: Result<&'static str, DisplayErr> = Ok("variant resolved");
        assert_eq!(
            raw.err_ctx_with("dynamic".to_string()).unwrap(),
            "variant resolved"
        );
    }

    #[test]
    fn err_ctx_static_and_owned_peers_produce_identical_output_for_the_same_slug() {
        // Cross-peer coherence pin: given the SAME context slug via
        // both peers, the wrapped [`anyhow::Error`] MUST have
        // byte-identical `Display` output.
        let slug = "source";
        let a: Result<(), DisplayErr> = Err(DisplayErr("bad slot"));
        let b: Result<(), DisplayErr> = Err(DisplayErr("bad slot"));
        assert_eq!(
            format!("{}", a.err_ctx(slug).unwrap_err()),
            format!("{}", b.err_ctx_with(slug.to_string()).unwrap_err()),
            "static-str and owned-string peers must produce identical Display output"
        );
    }

    #[test]
    fn err_ctx_threads_the_underlying_display_verbatim() {
        // Display-tail invariant: the wrapped [`anyhow::Error`]'s
        // `Display` output MUST contain the source error's own
        // `Display` output verbatim as the tail past `"<ctx>: "`.
        let underlying_display = format!("{}", DisplayErr("bad slot"));
        let raw: Result<(), DisplayErr> = Err(DisplayErr("bad slot"));
        let wrapped = raw.err_ctx("source").unwrap_err();
        let wrapped_display = format!("{wrapped}");
        assert!(
            wrapped_display.ends_with(&underlying_display),
            "wrapped Display `{wrapped_display}` must end with underlying Display `{underlying_display}`"
        );
        assert!(
            wrapped_display.starts_with("source: "),
            "wrapped Display `{wrapped_display}` must start with `\"<ctx>: \"`"
        );
    }

    #[test]
    fn err_ctx_admits_thiserror_derived_tagged_union_error() {
        // Substrate coverage pin: the trait's `E: Display` bound
        // MUST admit the concrete error type both pre-lift
        // export-worker callsites captured — a
        // [`crate::tagged_union::declare_tagged_union_error`]-
        // derived variant whose `Display` is [`thiserror`]-generated.
        // This test exercises `ArtifactError` specifically (the two
        // pre-lift consumers' source error) so a regression that
        // dropped its `Display` impl, narrowed the trait bound, or
        // otherwise made the primitive inapplicable to the very
        // callsites it was opened for surfaces HERE.
        use crate::export::{ArtifactError, ARTIFACT_KIND_LIST};
        let raw: Result<(), ArtifactError> = Err(ArtifactError::Empty(ARTIFACT_KIND_LIST));
        let wrapped = raw.err_ctx("source").unwrap_err();
        let wrapped_display = format!("{wrapped}");
        assert!(
            wrapped_display.starts_with("source: "),
            "wrapped Display `{wrapped_display}` must start with `\"source: \"`"
        );
        assert!(
            wrapped_display.contains(ARTIFACT_KIND_LIST),
            "wrapped Display `{wrapped_display}` must thread ArtifactError's Display body verbatim"
        );
    }

    #[test]
    fn err_ctx_agrees_with_flatten_ctx_on_anyhow_result() {
        // Cross-substrate coherence pin: on the specific input shape
        // `anyhow::Result<T>`, the generic `err_ctx` and the
        // specialized peer
        // [`crate::anyhow_flatten::FlattenCtxExt::flatten_ctx`] MUST
        // produce byte-identical `Display` output. Post-delegation
        // (both bodies routed onto this substrate owner) byte-shape
        // agreement holds by CONSTRUCTION rather than by two
        // independent hand-authored `.map_err(|e| anyhow!)` closures
        // pinned equal by convention; a regression that re-open-coded
        // the specialized peer's body surfaces HERE rather than as
        // silent operator-facing skew between the consumers migrated
        // onto the generic and consumers still routed through the
        // specialized peer.
        use crate::anyhow_flatten::FlattenCtxExt;
        let a: anyhow::Result<()> = Err(anyhow::anyhow!("underlying failure"));
        let b: anyhow::Result<()> = Err(anyhow::anyhow!("underlying failure"));
        assert_eq!(
            format!("{}", a.err_ctx("source").unwrap_err()),
            format!("{}", b.flatten_ctx("source").unwrap_err()),
            "generic err_ctx and specialized flatten_ctx must agree on anyhow::Result"
        );
    }

    #[test]
    fn err_ctx_with_agrees_with_flatten_ctx_with_on_dynamic_slug() {
        // Owned-string peer coherence pin: sibling to the static-slug
        // pin above, walking the `_with` peer instead. Pre-delegation
        // the two owned-string bodies were byte-identical by
        // convention (each restating the SAME
        // `.map_err(|e| anyhow!("{ctx}: {e}"))` chain); post-
        // delegation the specialized `flatten_ctx_with` routes onto
        // this substrate's `err_ctx_with`, and byte-shape agreement
        // holds by CONSTRUCTION. A regression that re-open-coded
        // `flatten_ctx_with`'s body — dropping the delegation and
        // restoring the pre-lift inline closure with a drifted
        // separator or a swapped-slots typo — surfaces HERE rather
        // than as silent skew between the four static-slug consumers
        // and the one `format!`-slug consumer in the reconciler's
        // phase-machine log stream.
        use crate::anyhow_flatten::FlattenCtxExt;
        let slug = format!("evaluate {:?}", "HelmReleaseReleased");
        let a: anyhow::Result<()> = Err(anyhow::anyhow!("underlying failure"));
        let b: anyhow::Result<()> = Err(anyhow::anyhow!("underlying failure"));
        assert_eq!(
            format!("{}", a.err_ctx_with(slug.clone()).unwrap_err()),
            format!("{}", b.flatten_ctx_with(slug).unwrap_err()),
            "generic err_ctx_with and specialized flatten_ctx_with must agree on anyhow::Result"
        );
    }

    #[test]
    fn err_ctx_agrees_with_kube_ctx_on_kube_error_result() {
        // Cross-substrate coherence pin: on the specific input shape
        // `Result<T, kube::Error>`, the generic `err_ctx` and the
        // specialized peer
        // [`crate::kube_error::KubeResultExt::kube_ctx`] MUST produce
        // byte-identical `Display` output. Post-delegation (the
        // specialized peer's body routes onto this substrate) byte-
        // shape agreement holds by CONSTRUCTION — `kube::Error:
        // Display` so the generic `err_ctx` impl applies to the same
        // input type. A regression that re-open-coded `kube_ctx`'s
        // body — dropping the delegation and restoring the pre-lift
        // inline closure — surfaces HERE rather than as silent
        // operator-facing skew between the 25+ K8s-round-trip
        // consumers and the sibling peer families.
        use crate::kube_error::KubeResultExt;
        use kube::core::ErrorResponse;
        let mk = || {
            kube::Error::Api(ErrorResponse {
                status: "Failure".into(),
                message: "test code 404".into(),
                reason: "NotFound".into(),
                code: 404,
            })
        };
        let a: Result<(), kube::Error> = Err(mk());
        let b: Result<(), kube::Error> = Err(mk());
        assert_eq!(
            format!("{}", a.err_ctx("install finalizer").unwrap_err()),
            format!("{}", b.kube_ctx("install finalizer").unwrap_err()),
            "generic err_ctx and specialized kube_ctx must agree on Result<_, kube::Error>"
        );
    }

    #[test]
    fn err_ctx_with_agrees_with_kube_ctx_with_on_dynamic_slug() {
        // Owned-string peer coherence pin on the Kube axis: sibling
        // to the static-slug pin above, walking the `_with` peer
        // instead. Post-delegation the specialized `kube_ctx_with`
        // routes onto this substrate's `err_ctx_with`, and byte-
        // shape agreement holds by CONSTRUCTION.
        use crate::kube_error::KubeResultExt;
        use kube::core::ErrorResponse;
        let mk = || {
            kube::Error::Api(ErrorResponse {
                status: "Failure".into(),
                message: "test code 409".into(),
                reason: "AlreadyExists".into(),
                code: 409,
            })
        };
        let slug = format!("patch (releasing→{})", "Exiting");
        let a: Result<(), kube::Error> = Err(mk());
        let b: Result<(), kube::Error> = Err(mk());
        assert_eq!(
            format!("{}", a.err_ctx_with(slug.clone()).unwrap_err()),
            format!("{}", b.kube_ctx_with(slug).unwrap_err()),
            "generic err_ctx_with and specialized kube_ctx_with must agree on Result<_, kube::Error>"
        );
    }

    #[test]
    fn err_ctx_agrees_with_hostname_ctx_on_hostname_error_result() {
        // Cross-substrate coherence pin: on the specific input shape
        // `Result<T, HostnameError>`, the generic `err_ctx` and the
        // specialized peer
        // [`crate::hostname::HostnameResultExt::hostname_ctx`] MUST
        // produce byte-identical `Display` output. Post-delegation
        // the specialized peer's body routes onto this substrate;
        // [`crate::hostname::HostnameError`] impls `Display` via
        // `thiserror` so the generic `err_ctx` impl applies to the
        // same input type. A regression that re-open-coded
        // `hostname_ctx`'s body surfaces HERE rather than as silent
        // operator-facing skew between `render_routing`'s
        // hostname-format consumer and the sibling peer families.
        use crate::hostname::{HostnameError, HostnameResultExt};
        let mk = || HostnameError::ReservedApp("auth".to_string());
        let a: Result<(), HostnameError> = Err(mk());
        let b: Result<(), HostnameError> = Err(mk());
        assert_eq!(
            format!("{}", a.err_ctx("render routing").unwrap_err()),
            format!("{}", b.hostname_ctx("render routing").unwrap_err()),
            "generic err_ctx and specialized hostname_ctx must agree on Result<_, HostnameError>"
        );
    }
}