Skip to content

feat(primitives): shared WorkloadMutator interface for workload-kind-agnostic mutations#143

Merged
sourcehawk merged 12 commits into
mainfrom
feat/workload-mutator-interface
Jun 1, 2026
Merged

feat(primitives): shared WorkloadMutator interface for workload-kind-agnostic mutations#143
sourcehawk merged 12 commits into
mainfrom
feat/workload-mutator-interface

Conversation

@sourcehawk
Copy link
Copy Markdown
Owner

Description

Closes #142

*statefulset.Mutator, *deployment.Mutator, and *daemonset.Mutator share an almost
identical container/env/podspec/metadata editing surface but are unrelated concrete types,
so a consumer could not write one workload-kind-agnostic mutation against a framework type.
This PR exports primitives.WorkloadMutator, the interface covering exactly that shared
surface, plus a per-kind LiftMutation adapter so a single emitter can be applied to any
pod-workload kind. The motivating case is a set of components that share env-emission
concerns but render as two different workload kinds.

Changes

  • New top-level package pkg/primitives exporting WorkloadMutator, the editing-surface
    intersection of the three pod-workload mutators (container, init-container, pod-spec,
    pod-template-metadata, object-metadata, env, and arg methods).
  • LiftMutation(feature.Mutation[primitives.WorkloadMutator]) Mutation on each of the
    statefulset, deployment, and daemonset packages, carrying Name and Feature gating
    through unchanged and preserving a nil Mutate.
  • Compile-time conformance guards (var _ primitives.WorkloadMutator = (*Mutator)(nil)) in
    each mutator package, so a future rename or removal of a shared method breaks the build in
    the framework instead of drifting silently downstream.
  • docs/primitives.md documents the interface and the lift pattern.

Challenges

The interface is the intersection across all three kinds, not just the two named in the
issue. That excludes EnsureReplicas (the daemonset mutator has no replica field) and the
StatefulSet-only VolumeClaimTemplate methods, keeping the contract stable if a future
replica-less workload kind is added. The package must not import its own subpackages (they
already import it for the guards), so the interface depends only on the editor and selector
packages.

Testing

make all (fmt, lint, go test ./...) and make build-examples are green. Each kind has
unit tests for the lift adapter covering name/feature carry-over, gate-enabled apply,
gate-disabled no-op through ApplyIntent, and nil-Mutate preservation (asserting the
named error rather than a panic). A cross-kind test applies one shared emitter to both a
StatefulSet and a Deployment and asserts the env var lands on both. The conformance guards
are the compile-time check that all three mutators satisfy the interface.

🤖 Generated with Claude Code

sourcehawk and others added 9 commits June 1, 2026 20:11
Captures the design for issue #142: a shared primitives.WorkloadMutator
interface plus per-kind LiftMutation adapters, so consumers can write one
workload-kind-agnostic mutation and apply it across StatefulSet, Deployment,
and DaemonSet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…uards

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Move LiftMutation to end-of-file in the deployment and daemonset mutators
to match the statefulset layout, so the three adapters read identically.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 1, 2026 19:23
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a shared, workload-kind-agnostic mutation surface to the framework so consumers can write a single emitter against a common interface and apply it to multiple pod-workload primitives (StatefulSet/Deployment/DaemonSet) via per-kind adapters.

Changes:

  • Introduces primitives.WorkloadMutator, an exported interface representing the shared editing surface across StatefulSet/Deployment/DaemonSet mutators.
  • Adds per-kind LiftMutation adapters plus compile-time conformance guards in statefulset, deployment, and daemonset.
  • Adds unit + cross-kind tests and documents the new interface/lift pattern in docs/primitives.md (plus additional design/plan docs under docs/superpowers/).

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
pkg/primitives/workload_mutator.go Adds the shared WorkloadMutator interface in the new top-level primitives package.
pkg/primitives/workload_mutator_test.go Cross-kind test proving one emitter can target multiple workload kinds via LiftMutation.
pkg/primitives/statefulset/mutator.go Adds conformance guard and LiftMutation adapter for StatefulSets.
pkg/primitives/statefulset/mutator_test.go Adds tests covering lift adapter behavior (carry-over, gating, nil mutate).
pkg/primitives/deployment/mutator.go Adds conformance guard and LiftMutation adapter for Deployments.
pkg/primitives/deployment/mutator_test.go Adds tests covering lift adapter behavior (carry-over, gating, nil mutate).
pkg/primitives/daemonset/mutator.go Adds conformance guard and LiftMutation adapter for DaemonSets.
pkg/primitives/daemonset/mutator_test.go Adds tests covering lift adapter behavior (carry-over, gating, nil mutate).
docs/primitives.md Documents workload-kind-agnostic mutations using WorkloadMutator + LiftMutation.
docs/superpowers/specs/2026-06-01-workload-mutator-interface-design.md Adds a design note for the interface and lifting approach.
docs/superpowers/plans/2026-06-01-workload-mutator-interface.md Adds an implementation plan for the change.

Comment thread pkg/primitives/workload_mutator.go Outdated
Comment thread docs/superpowers/specs/2026-06-01-workload-mutator-interface-design.md Outdated
Comment thread docs/superpowers/plans/2026-06-01-workload-mutator-interface.md Outdated
Comment thread docs/superpowers/plans/2026-06-01-workload-mutator-interface.md Outdated
Comment thread docs/superpowers/plans/2026-06-01-workload-mutator-interface.md Outdated
Comment thread docs/superpowers/plans/2026-06-01-workload-mutator-interface.md Outdated
sourcehawk and others added 3 commits June 1, 2026 21:30
Add the import block (matching the doc's example convention), a DaemonSet
lift call, an explicit statement of what LiftMutation returns and why the
lift is needed, and name the excluded spec editors while clarifying that
EnsureReplicas is excluded because the DaemonSet mutator has no replica field.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Name StatefulSet/Deployment/DaemonSet as the explicit set the interface
spans, rather than implying it covers every pod-based primitive (pod, job,
cronjob, replicaset also expose pod-template editing methods).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…uctions

Remove the design spec and implementation plan from version control (kept
local via .gitignore) so internal planning artifacts stay out of the published
diff. Add the new pkg/primitives top-level package to the "Source to read"
list in the committed instruction files.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 1, 2026 20:02
@sourcehawk sourcehawk requested review from Copilot and removed request for Copilot June 1, 2026 20:04
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 12 changed files in this pull request and generated no new comments.

@sourcehawk sourcehawk merged commit 6f3c796 into main Jun 1, 2026
5 checks passed
@sourcehawk sourcehawk deleted the feat/workload-mutator-interface branch June 1, 2026 20:16
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.

No shared interface across statefulset.Mutator / deployment.Mutator blocks workload-kind-agnostic mutations

2 participants