01 · Walk the repository
Every YAML file, but only the ones that changed.
Every six hours the scanner lists the YAML files in each configured
repository. A file whose content hash has not changed since the last
pass is skipped, so a quiet repository costs almost nothing.
System namespaces (kube-system, flux-system,
cert-manager) and kinds such as CRDs are excluded by
default, and very large files are skipped rather than half-read.
02 · Rules before models
Deterministic linters go first.
Each manifest is run through kube-score, an in-house
structural rule pack (Flux API versions, HelmRelease
remediation settings, HPA target bands) and Trivy's
misconfiguration checks.
A finding a rule can decide is never left to a model to rediscover.
Findings already proposed and still open are recognised and not
raised again.
03 · Patch what a rule can patch
Known fixes are applied by code, not by prompt.
For a fixed set of rules there is a patcher: image pull
policy, read-only root filesystem, running as a non-root user,
ephemeral-storage requests, rollout strategy, replicas, and new
PodDisruptionBudgets or NetworkPolicies. The patch is made in memory
and becomes its own proposal.
A patcher can also refuse. If a container writes to an unbounded
local cache, picking an ephemeral-storage cap would get the pod
evicted, so the scanner asks you for the size instead of guessing.
04 · Judgement where it is needed
The model sees the patched manifest, and real usage.
Only then does a model read the manifest. It sees the file
after the deterministic patches, so it cannot re-propose
them, plus the linter findings it should skip and, for workloads,
recent CPU and memory usage from your metrics backend.
Each suggestion has to carry a category, a confidence and evidence.
Low-confidence suggestions are dropped.
05 · A minimal patch
The model says what to change. Code makes the change.
The model does not rewrite the file. It returns a short list of
structured edits: an operation, a YAML path, a value. These are
applied by a round-trip YAML editor that touches only that path.
Comments, key order, block scalars and every other document in a
multi-document file stay byte-for-byte as they were. An edit that
names a file outside the scan is rejected. No cosmetic churn.
06 · Safety checks on the diff
Suspicious diffs are held, not shipped.
Every diff is checked before it can become an MR. One that removes
more than half of a file is escalated to high risk and held as
NEEDS_REVIEW. One that looks like a truncated file is
flagged too.
If the live object behind the file is rendered by a Helm chart,
editing the rendered output would fight the chart forever, so the
proposal is escalated with a pointer to the HelmRelease values as the
right place for the fix.
07 · Bundle what belongs together
One MR per concern, not one per line.
Two additive findings on the same file are merged into one diff.
The same additive change across many files (standard labels, say)
becomes one MR listing every file, instead of twenty.
Functional changes such as upgrades or API-version migrations are
never bundled across environments, so dev, staging and production
can still be merged one at a time. Rule-based patches and model
suggestions stay in separate MRs.
08 · The proposal
A small, additive diff with the evidence attached.
For orders-api that means one draft MR: resource
requests sized from observed usage, and a hardened security context,
merged into one file's diff. The full MR is below.