pub async fn merge<K, B>(api: &Api<K>, name: &str, body: &B) -> Result<K, Error>where
K: Resource + DeserializeOwned + Clone + Debug,
K::DynamicType: Default,
B: Serialize + Debug + ?Sized,Expand description
Merge-patch the PRIMARY resource endpoint of any kube Resource
with a caller-composed wire body.
Primary-resource sibling to merge_status on the (wire-endpoint ×
wrap-posture) pair: merge_status owns the /status subresource
axis (api.patch_status(...)) AND wraps the caller’s typed value
into {"status": <typed>} before dispatching; this primitive owns
the primary-resource axis (api.patch(...)) and passes the caller’s
body through verbatim — the caller composes the top-level spec:,
metadata:, data:, or other merge-patch slot before hand-off.
The wrap asymmetry between the two primitives matches the pre-lift
callsite discipline exactly: every /status writer built a typed
status value (an AllocationStatus, a ProcessStatus, a raw
Value) and delegated the {"status": …} wrap uniformly, so
merge_status owns that wrap; every primary-resource writer
composed a task-specific body (a spec: slot for a spec patch, a
metadata: slot for a finalizer / annotation edit, a data: slot
for a ConfigMap edit) with no shared top-level shape, so this
primitive dispatches the caller’s body verbatim rather than
speculating a wrap. A future normalization that WOULD apply to every
primary-resource writer (a hardcoded field-manager pass-through for
primary-resource merge writes, a strategic-merge escape hatch, a
dry-run gate, a resourceVersion precondition slot) lands at THIS
ONE function and every downstream consumer inherits the upgrade
mechanically.
Pre-lift the 3-link chain
api.patch(name, &PatchParams::default(), &Patch::Merge(&body)) was
hand-authored at SIX consumer sites past the ★★ PRIME-DIRECTIVE ≥ 2
duplication threshold, spanning TWO workspace crates:
tatara-reconciler::patch::patch_process_table_spec— the{"spec": ...}merge that stampsnext_sequencebumps on the ProcessTable singleton.tatara-reconciler::patch::apply_finalizer_transform— the{"metadata": {"finalizers": [...]}}merge that owns finalizer ensure / remove on the Process (shared by both public wrappers).tatara-reconciler::signals::ingest— the{"metadata": {"annotations": {SIGNAL: null}}}merge that strips the tatara-pleme-io/signal annotation off the Process after ingestion.tatara-reconciler::signals::consume_effect(SignalEffect::Suspendarm) — the{"spec": {"suspended": true}}merge that stamps SIGSTOP-persistent suspend state on the Process.tatara-reconciler::signals::consume_effect(SignalEffect::Resumearm) — the{"spec": {"suspended": false}}merge that lifts suspend state on SIGCONT.tatara-closed-loop-probe::main::write_receipt_configmap(409 already-exists retry path) — the{"data": <receipt payload>}merge that updates the receipt ConfigMap in-place when the create arm loses the race with a prior probe emission.
Post-lift each callsite reads patch::merge(&api, name, &body) and
the 3-link chain lives at ONE substrate owner. The pin block below
binds the primitive at fail-before-pass-after granularity so a
regression that drops Patch::Merge for Patch::Strategic, drifts
the PatchParams::default() slot, or reorders the 3-arg positional
slots surfaces here rather than as silent primary-resource writer
skew across the two consumer crates.
Theory anchor: THEORY.md §VI.1 (generation over composition — the
3-link primary-resource merge chain recurred at 6 hand-authored
sites past the ★★ PRIME-DIRECTIVE ≥ 2 duplication trigger, and is
lifted onto the ONE workspace-wide substrate owner here). THEORY.md
§II.1 invariant 5 (composition preserves proofs — the pin block
binds the Patch::Merge posture + the default PatchParams slot +
the pass-through body composition + the byte-identical parity with
the pre-lift 3-link chain, so a regression that drifted any surface
surfaces here rather than as silent operator-facing skew across the
six primary-resource writer sites).