Skip to main content

annotation_body

Function annotation_body 

Source
pub fn annotation_body(key: &str, value: impl Serialize) -> Value
Expand description

Compose the merge-patch wire body {"metadata": {"annotations": {<key>: <value>}}} — the ONE substrate owner of the single-annotation stamp / strip merge-body shape every workspace controller reaches for when it needs to publish exactly ONE operator-visible annotation on the primary resource (or strip one by stamping Value::Null) through the merge-patch semantics of either merge or apply.

Pre-lift the wire-shape recurred at THREE hand-authored consumer sites across TWO active workspace crates past the ★★ PRIME-DIRECTIVE ≥ 2 duplication threshold:

  • tatara-reconciler::signals::ingest — strips the tatara.pleme.io/signal annotation off the Process after ingestion by stamping serde_json::Value::Null (JSON merge patch interprets null as “remove key”). Dispatched through merge on the primary-resource merge-patch axis.
  • tatara-reconciler::phase_machine::transition_to_releasing — stamps the caller-observed tatara.pleme.io/released-from annotation with the current phase string on Attested/Failed → Releasing. Dispatched through apply on the primary-resource SSA axis (SSA Patch::Apply accepts the same {"metadata": {"annotations": …}} body shape as Patch::Merge — the top-level slot naming is what this composer owns).
  • tatara-pool-reconciler::controller_allocation (Release arm) — stamps the tatara.pleme.io/return-trigger annotation with the literal "true" on the member Process to nudge the Pool reconciler into taking the return path. Dispatched through the raw Api::patch call inside the release arm (also with apply_patch_params-composed PatchParams; the wire shape is the same {"metadata": {"annotations": {<one key>: <one value>}}} this composer names).

Post-lift each site reads tatara_process::patch::annotation_body( <key>, <value>) and the merge-body wire-shape composition lives at ONE substrate owner. A future normalization of the single-annotation merge-body posture (a canonicalization pass over the key spelling — a case-fold or a namespace-prefix normalization for a future annotation naming discipline; a stricter serde-failure return in place of the silent Value::Null fallback; a by: sibling slot naming the stamping controller for post-hoc audit; a version-tagged wrap for a future metadata.v2.annotations migration) lands at THIS ONE function and every downstream single-annotation writer inherits the upgrade mechanically. Directly benefits the P3 kenshi-runner library lift (any Job-based observer that stamps a per-suite annotation on its owning Process rides through the same composer as the strip / stamp / return-trigger family) and the P5 shigoto Dag refactor (every phase-machine RecordingJob that stamps an annotation on a transition rides through the same composer).

§Value axis — impl Serialize accepts every pre-lift shape

The value slot is impl Serialize matching the discipline of [phase_status_with] on the extra-key axis: accepts owned or borrowed values of any serde-serialisable type without widening the signature. All three pre-lift consumer sites pass distinct value shapes and this composer serves each verbatim through serde_json::to_value:

  • serde_json::Value::Null (signals::ingest strip) — the primitive serde_json::to_value round-trips a Value::Null back to Value::Null, which JSON merge patch interprets as “remove key”.
  • String (phase_machine::transition_to_releasing) — the primitive serde_json::to_value serializes a String to a JSON string verbatim.
  • &'static str (controller_allocation Release arm) — the primitive serde_json::to_value serializes a &str to a JSON string verbatim, matching the pre-lift "true" literal.

A serialisation failure resolves to Value::Null, matching the existing [phase_status_with] primitive’s posture. In practice serialisation of the shapes this composer accepts (a serde_json::Value, a String, a &str) never fails; the fallback is a defensive guard against a future caller passing a T: Serialize whose Serialize impl signals a runtime error.

§Key axis — &str matches every pre-lift call form

The key slot is &str matching the pre-lift call forms exactly: crate::annotations::SIGNAL via SIGNAL_ANNOTATION: &str at signals.rs, crate::annotations::RELEASED_FROM via a pub const: &str at phase_machine.rs, and a "tatara.pleme.io/return-trigger" literal at controller_allocation.rs. &str accepts both the pre-existing pub const: &str constants in crate::annotations and inline &'static str literals at the same signature.

A future caller composing a String key at runtime (a per-fleet prefix, a runtime-computed annotation name) coerces via &*key or key.as_str() at the call site — the composer stays borrowed so the common const-fed path pays no allocation.

§must_use on the return

The primitive exists to be handed to a wire-side write (merge, apply, or a raw Api::patch call at the pool-reconciler’s release arm), not to probe the merge-body shape. #[must_use] keeps a caller from building the body and dropping it un-passed to a wire dispatcher.

Theory anchor: THEORY.md §VI.1 (generation over composition — the 3-link json!({"metadata": {"annotations": {<key>: <value>}}}) merge- body composition recurred at 3 hand-authored sites past the ★★ PRIME-DIRECTIVE ≥ 2 duplication trigger, spanning two active workspace crates, and is lifted onto ONE substrate owner here). THEORY.md §II.1 invariant 5 (composition preserves proofs — the pin block below binds the composer at fail-before-pass-after granularity, so a regression that drifts the top-level metadata slot, the nested annotations slot, the caller-passed key spelling, or the value-slot pass-through discipline surfaces HERE rather than as silent operator-facing annotation-writer skew across the three consumer sites).