Skip to content

Tell the app pod mutator which app it is mutating - #595

Merged
incognick merged 1 commit into
mainfrom
seam/app-pod-mutator-identity
Aug 21, 2026
Merged

Tell the app pod mutator which app it is mutating#595
incognick merged 1 commit into
mainfrom
seam/app-pod-mutator-identity

Conversation

@incognick

Copy link
Copy Markdown
Contributor

The app-path pod mutator seam of ADR-0061 is a func(*corev1.PodSpec). It reaches every pod the adapter authors for an app — the Deployment's pod template and the one-off run Job — and is told nothing about any of them, so the only policy it can carry is policy true of every app on the cluster. A toleration for a tainted pool usually is. A runtime class is not.

Adapter.WithAppPodMutator(func(kube.PodIdentity, *corev1.PodSpec)) *Adapter. PodIdentity carries the app, the namespace the object is being written into, and which of the two app-image pods it is. All three are already in scope at both call sites; nothing new is threaded through the engine to supply them.

What is deliberately not changed

  • WithPodMutator keeps working, unchanged. It is a public seam an embedder may already be compiled against. It now wires the same single field through a closure that discards the identity, so the two spellings do not stack and the last one wired runs. WithPodMutator(nil) still clears the hook rather than wrapping nil in a closure that would panic on the first deploy.
  • WithPlatformPodMutator is untouched. Its pods run Burrow's own images — add-on instances, collectors, the backup and restore Jobs — and none of them belongs to an app, so the identity has nothing to say there. ADR-0077 §2 states its signature and reach stay as they are.
  • The compile-time pin on both ADR-0073 hook signatures (placement_test.go) is unedited and still passes. The new method carries a pin of its own in the same shape.
  • ADR-0061 §2 and §3 hold. The hook still runs on every write of the pod template, and a nil mutator still leaves every authored object byte-for-byte as it was.

Why namespace and not environment

Neither controlplane.WorkloadSpec nor controlplane.RunSpec carries an environment name; an environment-scoped view is a copy of the adapter with a different namespace (ADR-0035 phase 2); and the namespace is what the pod is actually written into. An embedder that keys its own policy on something else maps the namespace onto it on their side, so the seam does not learn how anyone stores their policy.

The two app-image paths also do not share a request type, so there is no existing value that could be handed over on both. Synthesising one for the path that lacks it is the move ADR-0077 §2 rejects at the controller seam. The three fields of PodIdentity are ones both paths genuinely have.

Tests

controlplane/kube/app_pod_identity_test.go pins the identity on the deploy path and the run path, that it reports the environment's namespace through WithNamespace, that one wired hook applies different policy to two apps, that WithPodMutator still runs and does not stack with the new spelling, and that its nil case clears the hook.

The authored-pod-path guard learns the new helper name alongside the field it already recognised, so a call site applying the hook inline is still visible to the scan.

This is not ready to merge

There is no accepted record for widening this seam yet. The record is being written; this PR should wait for it, and its shape may change if the record decides differently. Opening it now so the code is reviewable alongside the record rather than after it.

The deploy-path mutator seam of ADR-0061 is a func(*corev1.PodSpec). It reaches
every pod this adapter authors for an app -- the Deployment's pod template and
the one-off run Job -- and it is told nothing about any of them, so the only
policy it can carry is policy that is true of every app on the cluster.

For a toleration on a tainted pool that is usually right. For a runtime class it
is not: an operator running one app's image under a sandboxed runtime and
another's under the default has no way to say so. The ways around it are the ones
ADR-0073 §2 already rejected for the platform split -- key off a container image
or a label and reconstruct a classification the engine had in hand -- and a wrong
branch there applies the wrong policy to the wrong workload.

Adapter.WithAppPodMutator takes func(PodIdentity, *corev1.PodSpec). PodIdentity
carries the app, the namespace the object is being written into, and which of the
two app-image pods it is. All three are already in scope at both call sites; no
new plumbing stands behind them.

It says namespace rather than environment on purpose. Neither WorkloadSpec nor
RunSpec carries an environment name, an environment-scoped view is a copy of the
adapter with a different namespace (ADR-0035 phase 2), and the namespace is what
the pod is actually written into. An embedder that keys its own policy on
something else maps the namespace onto it on their side, so the seam does not
learn how anyone stores their policy.

WithPodMutator is retained, unchanged and working, for an embedder already
compiled against it: it wires the same single field through a closure that
discards the identity, so the two spellings do not stack and the last one wired
runs. Its nil case still clears the hook rather than wrapping nil in a closure
that would panic on the first deploy.

WithPlatformPodMutator is untouched. Its pods run Burrow's own images and none of
them belongs to an app, so the identity has nothing to say there; ADR-0077 §2
states its signature and reach stay as they are. The compile-time pin on both
ADR-0073 hook signatures in placement_test.go is unchanged and still passes.

The authored-pod-path guard learns the new helper name alongside the field it
already recognised, so a call site that applies the hook inline is still visible
to the scan.

Signed-off-by: Nicholas Phillips <nsphilli@gmail.com>
@incognick
incognick marked this pull request as draft August 20, 2026 22:46
@incognick
incognick marked this pull request as ready for review August 21, 2026 00:59
@incognick
incognick merged commit 5506915 into main Aug 21, 2026
5 checks passed
@incognick
incognick deleted the seam/app-pod-mutator-identity branch August 21, 2026 00:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant