Skip to content

`diff`

This content is for the v0.1 version. Switch to the latest version for up-to-date documentation.

kix diff evaluates and builds a cluster, then compares the result with an old side: the live cluster by default, or a directory passed with --from. It never changes the cluster.

This page is hand-maintained. Check cli/kix-cli/src/cli.rs and cli/kix-cli/src/commands/diff.rs when in doubt.

kix diff <CLUSTER> [--from <DIR>] [-o text|json|yaml|markdown]
[--flake <FLAKE>] [--context <CONTEXT>] [--no-cache]
Argument or flagMeaning
<CLUSTER>Cluster name to evaluate and build from the flake. This is the new side of the comparison.
--from <DIR>Use a directory as the old side instead of the live cluster. See Old side.
-o, --outputtext (default), json, yaml (the JSON document as YAML), or markdown for pull request comments.
--flake <FLAKE>Flake to evaluate. Defaults to the current directory.
--context <CONTEXT>Kubeconfig context for the live cluster. Ignored with --from.
--no-cacheRe-evaluate from Nix instead of reading the evaluation cache.
Old sideHow to select itNeeds cluster access
Live clusterOmit --fromYes
Previous build--from <DIR> where <DIR> contains kix-packages.json, such as the result of nix build .#cluster-<name>-activationNo
Saved manifests--from <DIR> where <DIR> holds YAML written by kix snapshot save or kix export --for auditNo

For the live cluster, Kix reads only the fields it applied to each managed resource. Kubernetes records which tool set each field through server-side apply, and Kix keeps its own fields and drops the rest: server defaults, status, fields set by controllers or kubectl, and the bookkeeping annotations Kix writes after every apply. A cluster that matches its build reports no differences.

A manifest directory must carry the Kix annotations that name each resource’s package and identity hash. The default kix export mode strips them, so use --for audit when the old side comes from an export.

Every old side goes through the same comparison. The live cluster and a snapshot of it produce the same report.

The report is organised by package. Each package lands in one group:

GroupMeaning
addedThe package is in the build but not on the old side
removedThe package is on the old side but not in the build
changedThe package exists on both sides and at least one resource differs
unchangedEvery resource in the package matches

Within a changed package, each resource is reported as one of:

Resource lineMeaning
+ added or - removedThe resource exists on one side only
~ modifiedThe content differs. Text output shows each differing path with a unified diff of the values.
~ via dependencyOnly the identity hash changed, because a dependency of this resource changed. The content is the same. Text output marks these “via dependency”; JSON and Markdown call them dep-affected.

Two more sections follow the packages:

  • Cluster-level resources groups resources that belong to no package, such as namespaces and custom resource definitions. Text output labels the group cluster-level resources; JSON uses the key _cluster.
  • Activation shows the old and new activation record names when they differ. A build whose content matches the old side keeps the same record name, so this line appears only alongside other changes.

When a stateful resource appears to have moved between packages or names, the report adds a “Stateful migrations detected” section. It is informational; Kix does not migrate data.

A summary line, one block per namespace with each package’s status and resource lines, the cluster-level group, the activation line, then either the migration section or No differences found. Colour follows --no-color and the NO_COLOR environment variable.

One document with a packages object and, when present, a migration_pairs array.

KeyContent
packages.summaryCounts of added, removed, changed, and unchanged packages
packages.added, packages.removedArrays of { key, version, resources }
packages.changedArray of package changes: key, old_version, new_version, added_resources, removed_resources, modified_resources (each { resource, diff_count }), dep_affected_resources
packages.cluster_levelThe same shape as one changed package, with key _cluster, or null
packages.activation{ old, new } record names, or null when unchanged
packages.unchangedNumber of unchanged packages

Resource identifiers have the form Kind/name@namespace. Package keys have the form namespace/name.

GitHub-flavoured Markdown: a plan summary, a <details> block per changed package, the cluster-level and activation sections, and the migration section when present.

CodeMeaning
0No differences
2At least one difference, or a stateful migration was detected
1Evaluation, build, or cluster error

The status is the same for every output format, so a CI job can write Markdown to a file and still branch on the result.