Use whenever the user wants to change data inside a ConfigHub Unit — update an image, adjust replicas, set environment variables, add labels/annotations, change a resource field, apply defaults, or make a bulk edit across many units. This skill enforces the "prefer a function over a hand-edit" rule, composes a proper change description that captures the user's prompt and clarifications, and chooses between `cub function set` (single function, targeted or bulk) and `cub unit update` (whole-unit replacement or restore). Load proactively any time the user says "update the image", "bump the replicas", "change the env var", "set the annotation", "apply defaults", "edit this unit", or any natural request that will end in a write to ConfigHub. Do not load for: creating a brand-new Unit (use config-as-data), reading/inspecting config (use cub-query), or setting up validation (use triggers-and-applygates).
92
92%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Risky
Do not use without reviewing
The get / modify / write-back loop for ConfigHub Units.
Prefer a function over a hand-edit. Functions like set-container-image, set-replicas, set-env-var, the defaults family — hermetic, idempotent, comment-preserving, and produce clean revisions. Hand-editing YAML is the fallback when no function fits.
--where / --where-data — usually inside a ChangeSet (see below).config-as-data).cub-query).triggers-and-applygates).cub organization list succeeds (proves a valid token; cub context get / cub info / cub version don't require one).TriggerFilterID (or its Triggers are otherwise in place) so validation will enforce the change. If not, suggest triggers-and-applygates — but don't block.Does a purpose-built function do this (set-container-image, set-replicas, defaults family, …)?
│
┌────┴────┐
yes no
│ │
▼ ▼
cub function set <fn> Is this a small, surgical path edit (1–3 fields)?
│
┌────┴────┐
yes no
│ │
▼ ▼
cub function set set-bool-path / set-int-path / set-string-path / set-cel
│
no again
▼
cub function set -- yq-i '<yq-i expression>' (catch-all; still via a function)
│
genuinely needs a whole-unit rewrite
▼
cub unit data … → edit locally → cub unit update
│
▼
Restoring history instead? cub unit update --restore <revision-or-tag>yq-i is the escape-hatch mutator: full yq expression power, still invoked via cub function set, still records a proper revision with your --change-desc. Its non-mutating counterpart yq is in cub-query's territory (reading a value out). Don't confuse the two — the -i suffix is the only difference and it's the difference between read and write.
Ask only what you need to compose the mutation:
--where filter, or a --where-data filter.)--space "*" for fleet-wide.)Record answers as condensed clarifications for --change-desc.
Consult references/functions-catalog.md. Examples:
| Change | Function |
|---|---|
| Container image | set-container-image <container> <image> |
| Image tag only | set-container-image-reference <container> <ref> |
| Replicas | set-replicas <replicas> |
| Env var | set-env-var <container> <var> <value> / set-env <container> key=value |
| Resource requests/limits | set-container-resources |
| Probe | set-container-probe-defaults (defaults) or set-starlark (surgical) |
| Annotation / label | set-annotation / set-label |
| Generic path | set-string-path / set-int-path / set-bool-path / set-starlark |
Deprecated — don't reach for: set-image, set-image-reference, set-image-uri, cel-validate, no-placeholders, is-approved.
--space <space> --unit <slug> (bulk-only commands like cub function set / cub run accept --unit as a shortcut for --where "Slug = '<slug>'"; also takes a comma list or UUID).--space <space> --where "Labels.Environment = 'prod'".--space "*" --where ….--where-data "spec.replicas > 5".Always required. Format:
<summary line>
User prompt: <verbatim user prompt, trimmed if very long>
Clarifications: <condensed — one line per resolved ambiguity, or "none">For bulk cub run / cub function set across many Units: phrase the summary so it reads sensibly at the per-unit granularity (the same description is recorded in every affected Unit's head revision).
cub function set \
--space <space> \
--unit <slug> \
--change-desc "<composed description>" \
-o mutations \
-- \
<function-name> [function args]-o mutations prints a diff of the configuration change, so you and the user can see exactly what landed. Include it on mutating calls by default — it's the same diff that will show up in the Unit's revision history, surfaced inline so you don't have to chase it with cub unit diff afterward.
--dry-run will return what the modified data would look like, but without persisting the change. It can be used with -o mutations.
For multi-Unit runs, add --wait so you see completion.
Only when no function composition does the job:
cub unit get <slug> --space <space> -o yaml > /tmp/edit.yaml
# edit /tmp/edit.yaml preserving literal values
cub unit update --space <space> <slug> /tmp/edit.yaml \
--change-desc "<composed description>"cub unit update also supports -o mutations, --dry-run, and --wait.
cub unit update --space <space> <slug> --restore <rev-num-or-tag> \
--change-desc "Restore to rev <N>. User prompt: … Clarifications: …"Valid --restore targets: a number (absolute or negative-relative), LiveRevisionNum, LastAppliedRevisionNum, Tag:<tag>, ChangeSet:<name>, Before:ChangeSet:<name> (pre-open state), a revision UUID.
Any time a logical change touches more than one Unit (a release, a defaults rollout, a cross-Space upgrade, a coordinated secret rotation), wrap it in a ChangeSet. Reasons:
--restore Before:ChangeSet:<name> against the Filter rewinds every affected Unit to its pre-open state.--revision ChangeSet:<name> applies or approves the end-tag revision per Unit as one set.Lifecycle:
# 1. Create the ChangeSet (lives in one home Space; Units can be anywhere).
cub changeset create --space <home-space> <slug> \
--description "<one-line release description>"
# 2. Open: bulk-patch target Units into the ChangeSet via a saved Filter.
cub unit update --patch --space <target-space> \
--filter <home-space>/<filter-slug> \
--changeset <home-space>/<slug> \
--change-desc "Starting <slug> rollout"
# 3. Mutate: every function do / unit update / run must pass --changeset.
cub function set --space <target-space> \
--filter <home-space>/<filter-slug> \
--changeset <home-space>/<slug> \
--change-desc "<summary>. User prompt: <verbatim>. Clarifications: <condensed>" \
-o mutations \
-- set-container-image <container> <image>:<tag>
# 4. Close with the "-" sentinel (empty string does not clear).
cub unit update --patch --space <target-space> \
--filter <home-space>/<filter-slug> \
--changeset -
# 5. Apply / approve as a set.
cub unit apply --space <target-space> \
--filter <home-space>/<filter-slug> \
--revision ChangeSet:<home-space>/<slug> --waitDon't use a ChangeSet for single-Unit edits (overhead without payoff) or for rolling per-Unit releases that need different approvals per Unit. See references/changesets.md for rollback via Before:ChangeSet:<...>, the merge / rebase pattern around a restored ChangeSet, and listing revisions by ChangeSet membership.
Use a named Filter (cub filter create --space <home-space> <slug> Unit --where-field "…") over inlined --where so the same selection flows through open / mutate / close / approve / apply. See references/filters-and-queries.md.
The cub-apply skill goes into the use of apply in more detail.
cub unit / function / run / revision — always with --change-desc when mutating.kubectl apply/edit/patch/delete, argocd app sync as a mutation, editing YAML outside ConfigHub and re-uploading wholesale without a function-composed path when one exists.cub function list for Kubernetes/YAML (wrong name — re-check via CONFIGHUB_AGENT=1 cub function list / cub function explain).--space "*" and the user hasn't confirmed the blast radius.triggers-and-applygates), and fix the data — do not bypass.cub unit get <slug> --space <space> — confirm the field now reflects the intended value.cub revision list <slug> --space <space> — new revision present, --change-desc matches what you composed.cub function vet --space <space> --unit <slug> vet-schemas, vet-placeholders, vet-format, vet-merge-keys (or rely on Triggers) — validation passes.cub unit get <slug> --space <space> --web — opens the Unit's current state.cub revision list <slug> --space <space> --web — shows the revision history and the --change-desc recorded for each.references/functions-catalog.md — the canonical function index.references/cub-cli.md — agent-mode help and flag discipline.references/changesets.md — full ChangeSet lifecycle, rollback, merge / rebase.references/filters-and-queries.md — named Filters (use these with ChangeSets).references/yaml-patterns.md — for hand-edit fallback.59ea831
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.