Skip to content

feat(podspec): find PodSpecs by reflecting over the decoded object (option A) - #81

Open
MPV wants to merge 1 commit into
masterfrom
claude/podspec-a-scheme-reflection
Open

feat(podspec): find PodSpecs by reflecting over the decoded object (option A)#81
MPV wants to merge 1 commit into
masterfrom
claude/podspec-a-scheme-reflection

Conversation

@MPV

@MPV MPV commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Option A of four candidate answers to #26, raised side by side so they can be compared. Scope feat(podspec) finds the set — #81 #82 #83 #84. Only one should be merged.

Rebased onto 2abd515 (0.4.3) — Kubernetes v0.36.3, Go 1.26. All numbers re-measured on that base.

master A · reflection ← this B · structural C · CUE D · config
Custom resource (Argo Rollout) ✓ automatic ✓ automatic ✓ via --config
Custom resource holding bare containers (Argo Workflow) ✓ via --config
ReplicationController, PodTemplate
Rejects a containers lookalike ✓ strict decode ✓ closed CUE def ✓ path-exact
1000 documents 105 ms 110 ms 133 ms 2163 ms 76 ms
Binary 27.2 MB 27.2 MB 12.4 MB 25.4 MB 4.1 MB
go.sum lines 74 74 72 109 42
Code generation make schema
New CLI surface --schema --config

All four keep the existing goldens green and produce byte-identical output on the shared 1000-document corpus. Timings are best-of-7 in a single run on one machine.

Approach

Keep typed decoding; replace the lookup with a search. k8s.FindPodSpecs walks the decoded Go value and collects every field of type corev1.PodSpec, wherever it sits.

Kinds and paths both disappear — the seven-case type switch, and the supportedKinds allow-list that List items were checked against.

What it buys

Two built-in kinds the type switch omitted now work, with no code naming them:

$ kir approvals/kir_test.TestKind.ReplicationController.input.yaml   # before: nothing
nginx:1.27
$ kir approvals/kir_test.TestKind.PodTemplate.input.yaml             # before: nothing
worker:3.1

Both are checked-in fixtures with goldens, so the examples can't drift. A workload kind added to k8s.io/api in future needs no change here — the Kubernetes v0.32.3 → v0.36.3 bump in the rebase is a small demonstration: no code change, no golden moved.

What it doesn't

Custom resources remain invisible — reflection only sees what the scheme can decode, so an Argo Rollout still yields nothing. This addresses #26's "less hardcoded kinds/structures" but not "easier to use with other (custom) resources". That is the reason to weigh it against B and C.

Notes for review

  • Precision is unchanged: only real corev1.PodSpec values match, so no false positives are possible and no lookalike guard is needed.
  • No measurable cost — decoding dominates. This is the only option that leaves master's goldens and dependency set completely untouched, which is worth something if the answer to Dynamically find PodSpec in manifests #26 turns out to be "not yet".
  • The walk is depth-bounded (20) purely as a guard; CronJob's PodSpec, the deepest in the built-in API, sits at 4.

gofmt, go vet, go mod tidy no-op, go test -race ./... green. ADR 0009 records the decision as proposed, superseding ADR 0001 only if merged.

Option A of four candidate answers to #26, raised side by side for
comparison. Keeps typed decoding; replaces the lookup with a search.

k8s.FindPodSpecs walks the decoded Go value and collects every field of
type corev1.PodSpec, wherever it sits. Kinds and paths both disappear:
the seven-case type switch goes, and so does the kind allow-list in
yamlparser that List items were checked against.

Two built-in kinds the type switch omitted now work with no code
dedicated to them:

  $ kir replicationcontroller.yaml   # before: nothing
  nginx:1.27
  $ kir podtemplate.yaml             # before: nothing
  worker:3.1

Both are added to the golden kind table. Precision is unchanged — only
real corev1.PodSpec values match, so no false positives — and there is
no measurable cost, since decoding dominates (169ms -> 165ms over 1000
documents, within noise).

The inherited limit is that reflection only sees what the scheme can
decode, so custom resources embedding a PodSpec remain invisible. That
is the half of #26 this option does not address; see ADR 0008.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013RYRsLAGHPcRuwhodXXmWP
@MPV
MPV force-pushed the claude/podspec-a-scheme-reflection branch from 5990e9f to a56e43c Compare August 13, 2026 07:49
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.

2 participants