Skip to content

Check the type a CRD declares, not just presence and shape - #205

Merged
stxkxs merged 1 commit into
mainfrom
walker-type-checking
Aug 11, 2026
Merged

Check the type a CRD declares, not just presence and shape#205
stxkxs merged 1 commit into
mainfrom
walker-type-checking

Conversation

@stxkxs

@stxkxs stxkxs commented Aug 10, 2026

Copy link
Copy Markdown
Member

The walker asked whether every required property was present, whether any property was excess, and whether list identities were unique. It never asked whether a value carried the type the CRD declares — and YAML decides that for you.

The live cost

portal's Platform declared:

minACU: 0.5
maxACU: 4

which reads as obviously correct and is not. The CRD types both as strings, because Kubernetes serialises fractional quantities that way. The API server refused the whole object:

The Platform "portal" is invalid:
* spec.datastores[0].relational.minACU: Invalid value: "number":
    ... in body must be of type string: "number"
* spec.datastores[0].relational.maxACU: Invalid value: "integer":
    ... in body must be of type string: "integer"

Every property was present, none was excess, no list repeated an identity — so this walker had already declared that manifest admissible, and the install failed applying it after the cluster and its substrate were built.

Two details that matter

  • A Python bool is an int, so true would otherwise satisfy integer. Tested for first, in both directions.
  • The message reports the value's own type in Invalid value, the way the API server does, so it can be searched for verbatim after a failed apply. A number where a string is wanted also says to quote it, because that is the fix and it is not obvious from the type names alone.

Verified

Twelve new self-test cases: a number and an integer where a string is wanted, the same value quoted, a string where an integer is wanted, a bool against integer and against boolean.

Every hand-written Platform, Tenant, BudgetPolicy, ModelGateway, AgentFleet and EvalSuite in the org — 31 documents across eight files — still passes with the rule on, so it adds no false positives.

The walker asked whether every required property was present, whether any
property was excess, and whether list identities were unique. It never asked
whether a value carried the type the CRD declares — and YAML decides that for
you.

That gap has a live cost. portal's Platform declared

    minACU: 0.5
    maxACU: 4

which reads as obviously correct and is not: the CRD types both as STRINGS,
because Kubernetes serialises fractional quantities that way. The API server
refused the whole object:

    spec.datastores[0].relational.minACU: Invalid value: "number":
      ... in body must be of type string: "number"

Every property was present, none was excess, no list repeated an identity —
so this walker had already declared that manifest admissible, and the install
failed applying it after the cluster and its substrate were built.

The check covers scalars and containers, with two details that matter:

  - a Python bool is an int, so `true` would otherwise satisfy `integer`. It is
    tested for first, in both directions.
  - the message reports the value's OWN type in `Invalid value`, the way the API
    server does, so it can be searched for verbatim after a failed apply. A
    number where a string is wanted also says to quote it, because that is the
    fix and it is not obvious from the type names alone.

Twelve self-test cases: a number and an integer where a string is wanted, the
same value quoted, a string where an integer is wanted, a bool against integer
and against boolean. Every hand-written Platform, Tenant, BudgetPolicy,
ModelGateway, AgentFleet and EvalSuite in the org still passes with the rule
on — thirty-one documents — so it adds no false positives.
@github-actions

Copy link
Copy Markdown

CI Results

Check Status
Zero-placeholder gate ✅ success
YAML Lint ✅ success
Dashboard gate (live grafana.com ids + AMG-saveable) ✅ success
Kyverno policy tests (+ verify-images contract) ✅ success
Fork-safety gate (no hardcoded org, blocking) ✅ success
Helm-render (every addon × every env) ✅ success
Policy-admission (Enforce-tier Kyverno vs the fleet) ✅ success
ApplicationSet schema + sync waves ✅ success
Appset render (Karpenter subnet selector) ✅ success
Secret scan (gitleaks) ✅ success
Render + assert + schema + misconfig (all environments) ✅ success

All checks passed.

@stxkxs
stxkxs merged commit d63b143 into main Aug 11, 2026
23 checks passed
@stxkxs
stxkxs deleted the walker-type-checking branch August 11, 2026 17:18
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