Agent skill

Kopiur Design

by home-operations in home-operations/kopiur

Design norms and locked decisions for the Kopiur Kopia-native Kubernetes backup operator (Rust/kube-rs).

AGPL-3.0Auto-check passedDevOps & Cloud

Install Kopiur Design

skills CLI
$ npx skills add home-operations/kopiur --skill kopiur-design -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install home-operations/kopiur kopiur-design --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/home-operations/kopiur.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/kopiur-design .claude/skills/kopiur-design && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
kopiur-design
GitHub stars
115
Token cost
~2.4k tokens
SKILL.md length
1,125 words
Files
1
Skills in repo
3
Repo updated
First seen
Licence
AGPL-3.0

At a glance

Design norms and locked decisions for the Kopiur Kopia-native Kubernetes backup operator (Rust/kube-rs).

  • Works in 5 steps: Externally-tagged enums for… → No Eq when embedding k8s-openapi types.… → crates/api has no controller-runtime… → …
  • Modifying CRD types
  • SKILL.md covers The thesis you must protect, Hard rules (violating these…, Semantic decisions to honor and Build & verify discipline, plus 1 more section
  • Calls cargo

What it does

Kopiur Design is an agent skill from home-operations/kopiur. Design norms and locked decisions for the Kopiur Kopia-native Kubernetes backup operator (Rust/kube-rs). Use when adding or modifying CRD types, reconcilers, the admission webhook, the kopia client/mover, validators, or codegen in this repo — anything under crates/ or deploy/. Encodes the type-safety thesis, the externally-tagged-enum rule, k8s-openapi Eq constraints, the shared-validator pattern, retention/deletion semantics, and the build/test discipline. The code is the source of truth for current behavior…

Its SKILL.md is about 2.4k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in DevOps & Cloud, covering Container orchestration, Essays and academic help and OpenAPI specifications. It works with Kubernetes, Rust and OpenAPI. The repository describes itself as: A Kopia-native Kubernetes backup operator written in Rust. The licence is AGPL-3.0.

When your agent uses it

  • Modifying CRD types
  • The admission webhook
  • The kopia client/mover
  • Codegen in this repo — anything under crates/

Example prompts

  • “/kopiur-design”

Workflow steps

5 steps, taken from the first numbered list in SKILL.md.

  1. Externally-tagged enums for discriminated unions. backend: { s3: {...} },
  2. No Eq when embedding k8s-openapi types. LabelSelector,
  3. crates/api has no controller-runtime deps. No tokio, no
  4. One validator, two callers. Cross-field rules live in api::validate as
  5. Tests use the cluster's parse path. from_yaml = YAML → serde_json::Value

What it can do on your machine

Read from SKILL.md and the folder at commit 906af4f. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • cargo

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Kopiur Design loads about 2.4k tokens when it runs. Until then it costs about 141 tokens; SKILL.md has 1,125 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~141
When it runs · the whole SKILL.md, loaded when a task matches
~2.4k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from home-operations/kopiur at commit 906af4f, republished under its AGPL-3.0 licence (© home-operations). 1,125 words, ~2,358 tokens.

Download SKILL.mdSave it as .claude/skills/kopiur-design/SKILL.md (or your agent's skills folder).
name
kopiur-design
description
Design norms and locked decisions for the Kopiur Kopia-native Kubernetes backup operator (Rust/kube-rs). Use when adding or modifying CRD types, reconcilers, the admission webhook, the kopia client/mover, validators, or codegen in this repo — anything under crates/ or deploy/. Encodes the type-safety thesis, the externally-tagged-enum rule, k8s-openapi Eq constraints, the shared-validator pattern, retention/deletion semantics, and the build/test discipline. The code is the source of truth for current behavior; this skill summarizes the norms.

Kopiur design norms & decisions

Kopiur is a Kopia-native Kubernetes backup operator in Rust on kube-rs. The source of truth for current behavior is the code: the CRD types live in crates/api/src/, their generated schemas in deploy/crds/. Read docs/dev/api-conventions.md for the encoding rulebook and CLAUDE.md for the quick map. The ADRs (docs/adr/) are historical rationale — reach for one only to recover the why behind a decision, not for current field names or behavior, which they may pre-date.

The thesis you must protect

Invalid states are unrepresentable; reconcilers handle every variant. Concretely:

  • Model every "exactly one of" surface as a Rust enum, never a bag of mutually exclusive Option fields + a runtime check.
  • In reconcile/finalizer paths, use exhaustive match — avoid _ => catch-alls and if let ... else { /* ignore */ }. A new enum variant should fail to compile until handled. This is the entire reason the project is Rust, not Go.

Hard rules (violating these breaks the build or the CRDs)

  1. Externally-tagged enums for discriminated unions. backend: { s3: {...} }, not backend: { kind: S3, ... }. Do NOT use #[serde(tag = "...")]: internally-tagged enums make kube's structural-schema rewriter panic (property "kind" ... must be identical) because each variant needs a distinct tag const. External tagging keeps the type-safety guarantee AND produces valid structural schemas. Provide a kind_str() helper for status/metrics/print-columns. Applies to Backend, AllowedNamespaces, RestoreSource, RestoreTarget, Hook, etc.
  2. No Eq when embedding k8s-openapi types. LabelSelector, ResourceRequirements, SecurityContext, JobSpec, Condition, PodSpec are PartialEq but not Eq. Derive PartialEq only on any struct that contains one (directly or transitively). Reuse these types — never re-declare them. The schemars feature is on for k8s-openapi so they derive JsonSchema.
  3. crates/api has no controller-runtime deps. No tokio, no kube::Client. It's the shared types + pure logic crate. The webhook and controller both import its validators so validation is identical.
  4. One validator, two callers. Cross-field rules live in api::validate as pure functions returning a typed error; the webhook calls them at admission and the controller calls them defensively. Never fork validation logic.
  5. Tests use the cluster's parse path. from_yaml = YAML → serde_json::Value → typed (crates/api/src/lib.rs::testutil). Direct serde_yaml::from_str::<T> mis-encodes externally-tagged enums (serde_yaml 0.9 !Variant syntax) and is not representative of the real wire format.

Semantic decisions to honor

  • Retention is GFS-only. SnapshotPolicy.spec.retention is the sole successful- retention driver (operator prunes Snapshot CRs). Failures use a flat SnapshotSchedule.spec.failedJobsHistoryLimit. There is deliberately no successfulJobsHistoryLimit.
  • Snapshot lifecycle = CR lifecycle. Every Snapshot carries the kopiur.home-operations.com/snapshot-cleanup finalizer. deletionPolicy: Delete (default for produced) / Retain (FORCED for origin: discovered, webhook-rejected otherwise) / Orphan. Match all three exhaustively; the kopiur.home-operations.com/skip-snapshot-cleanup annotation is the repo-offline escape hatch.
  • Identity defaults to username=name, hostname=namespace, sourcePath=/pvc/<name>; ClusterRepository.identityDefaults *Expr fields evaluate as CEL at admission and are pinned to status.resolved.identity — never re-rendered after admission.
  • Scheduling: wall-clock anchor (cron(now)), deterministic jitter seeded by (scheduleUID, slot_start) (no RNG — must be identical across HA replicas and restarts). runOnCreate: false and concurrencyPolicy: Forbid are defaults.
  • Restores fail closed (onMissingSnapshot: Fail) except source.fromConfig, which defaults to Continue for the GitOps deploy-or-restore pattern.

Build & verify discipline

bash
cargo test --workspace                 # hermetic; must be green before claiming done
cargo clippy --workspace --all-targets -- -D warnings
cargo xtask gen-all --check            # generated CRDs/RBAC must match checked-in
scripts/with-kind.sh cargo test --workspace --features integration -- --include-ignored
  • Integration tests are #[ignore] + --features integration, run only on an ephemeral kind cluster via scripts/with-kind.sh. Never point them at a real/homelab cluster.
  • Land one milestone, prove it green, then move on. Show the passing output — don't assert completion without evidence (a T::crd() call doubles as the schema-generation smoke test; it panics if an enum is mis-encoded).
  • Delegating a milestone to a subagent is encouraged when it's well-specified, but always re-run cargo test/clippy yourself before trusting the result.

Every change ships with tests (non-negotiable)

This is data-protection software: an untested path can silently lose backups. So every new feature AND every bug fix ships with tests — you have NOT finished until the work is proven by tests that would fail without it.

Show full SKILL.md (517 more words)Show less
New features: cover every tier the feature touches

A new feature (a CRD field, a backend, a reconciler path, a mover op) is not done until it has, at minimum:

  1. Unit/serde tests for the leaf logic — validators, the externally-tagged wire shape (from_yaml round-trip), pure decision functions, and any match-on-enum mapping. Cheapest tier; catches the most. Also test the controller glue that maps a CRD field to a mover input (e.g. the function that turns source.nfs into a mover volume mount) — extract it so it's callable without a cluster, then assert on its output.
  2. An e2e scenario that exercises the feature end to end against a live operator and asserts the user-visible success condition (a Snapshot reaching Succeeded with a real kopiaSnapshotID, a Repository Ready, a Restore Completed). If the feature needs a new piece of cluster infrastructure to test (an NFS server, an SFTP server, a new backend), stand it up in the e2e World (Need/Fixture) — see [[error-handling-and-e2e]].
  3. Integration tier (#[ignore] + --features integration) when the surface is an API-server interaction (admission, RBAC) that doesn't need the mover images.

No e2e test is "too large" or "too expensive" to include. This tool guards real data; thorough end-to-end proof is the requirement, not a nice-to-have. If a feature can be exercised against a live operator, it gets an e2e scenario — even when that means provisioning a server, building an image, or a multi-minute run. The only acceptable reason to skip an e2e is that the feature genuinely has no runtime-observable behavior (a pure type/refactor) — and then say so explicitly.

Bug fixes: a regression test that fails without the fix

When you fix a bug — especially one a user hit at runtime — you have NOT finished until a test would fail without your fix and passes with it. A fix without a test is an invitation for the same bug to return. Default to writing the test first (reproduce the failure), then fix.

Pick the cheapest tier that actually exercises the broken path:

  1. Hermetic unit test (preferred). If the bug lives in a decision, extract that decision into a pure function and unit-test it — the codebase's "thin IO over a tested pure fn" idiom. Example: the "ClusterRepository refs are ignored" bug (controller resolved every repository ref as a namespaced Repository regardless of kind) became io::repo_lookup(&RepositoryRef, …) -> RepoLookup with unit tests asserting kind: ClusterRepository maps to a cluster-scoped lookup, never a namespaced get. Runs in cargo test, no cluster.
  2. e2e test for whole-pipeline bugs. If the failure only shows up against a live operator (a reconcile that never reaches Succeeded, a missing dependency, an RBAC/SA gap, a dropped option), add a scenario to crates/e2e/tests/lifecycle.rs that reproduces the exact user-visible symptom and asserts the success condition (e.g. a Snapshot reaching Succeeded with a real kopiaSnapshotID). Write the test so it would have timed out / failed on the buggy code. See cluster_repository_backup_lifecycle for the template.
  3. Integration tier (#[ignore] + --features integration) for API-server interactions that don't need the mover images.

Then record the bug + its guard in the operator-bugs-fixed-by-e2e auto-memory so the class of failure stays visible across sessions.

© home-operations, AGPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .claude/skills/kopiur-design of home-operations/kopiur.

Open the folder on GitHubat commit 906af4f

Compare with similar skills

Kopiur Design next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Kopiur Design compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Kopiur Design this skillhome-operations/kopiur115—~2.4kAutomated safety check: PassAGPL-3.0
K8s Openapijinnovation/kele.el108—~171Automated safety check: PassApache-2.0
SpikardGoldziher/spikard124—~799Automated safety check: PassMIT
Helm Chart ScaffoldingCybereason-Public/owLSM28013 repos~381Automated safety check: PassGPL-2.0
Tokf Runmpecan/tokf199—~571Automated safety check: PassMIT
Helm Chart Scaffoldingdiegosouzapw/awesome-omni-skills159—~2.4kAutomated safety check: PassMIT

Similar skills

  • K8s Openapi

    jinnovation/kele.el

    Reference the Kubernetes API. An agent skill from jinnovation/kele.el.

    108 GitHub stars~171 tokensUpdated 7 mo ago
    Backend & APIsAuto-check passed
  • Spikard

    Goldziher/spikard

    Scaffold Spikard projects and generate code from OpenAPI, AsyncAPI, OpenRPC, GraphQL, and Protobuf schemas using the Spikard CLI or its MCP server.

    124 GitHub stars~799 tokensUpdated today
    Backend & APIsAuto-check passed
  • Helm Chart Scaffolding

    Cybereason-Public/owLSM

    Comprehensive guidance for creating, organizing, and managing Helm charts for packaging and deploying Kubernetes applications.

    280 GitHub starsUsed in 13 repos~381 tokens
    DevOps & CloudAuto-check passed
  • Tokf Run

    mpecan/tokf

    Compress verbose CLI output with tokf before returning results.

    199 GitHub stars~571 tokensUpdated yesterday
    DevOps & CloudAuto-check passed
  • Helm Chart Scaffolding

    diegosouzapw/awesome-omni-skills

    Helm Chart Scaffolding workflow skill. An agent skill from diegosouzapw/awesome-omni-skills.

    159 GitHub stars~2.4k tokensUpdated 3 mo ago
    DevOps & CloudAuto-check passed
  • Gitops Cluster Debug

    fluxcd/agent-skills

    Debug and troubleshoot Flux CD on live Kubernetes clusters (not local repo files) via the Flux MCP server — inspects Flux resource status, reads controller logs, traces dependency chains, and…

    231 GitHub stars~4.2k tokensUpdated yesterday
    DevOps & CloudAuto-check passed

More from home-operations/kopiur

  • Documentation

    home-operations/kopiur

    How Kopiur writes and maintains user-facing docs — the MkDocs Material site under docs/ and the example manifests under deploy/examples/.

    115 GitHub stars~2.5k tokensUpdated today
    Auto-check passed
  • Error Handling And E2E

    home-operations/kopiur

    How Kopiur does strongly-typed, actionable error handling and end-to-end testing.

    115 GitHub stars~2.7k tokensUpdated today
    Auto-check passed

Questions about Kopiur Design

What does Kopiur Design do?

Design norms and locked decisions for the Kopiur Kopia-native Kubernetes backup operator (Rust/kube-rs). Kopiur Design is an agent skill from home-operations/kopiur. Design norms and locked decisions for the Kopiur Kopia-native Kubernetes backup operator (Rust/kube-rs).

When should I use Kopiur Design?

Kopiur Design fits situations like: modifying CRD types; the admission webhook; the kopia client/mover; codegen in this repo — anything under crates/.

How do I install Kopiur Design in Claude Code?

Run `npx skills add home-operations/kopiur --skill kopiur-design -a claude-code`. Or copy the skill folder (.claude/skills/kopiur-design in home-operations/kopiur) into .claude/skills/kopiur-design in your project. Claude Code loads it when a task matches its description.

How do I install Kopiur Design in Codex?

Run `npx skills add home-operations/kopiur --skill kopiur-design -a codex`. Or copy the skill folder (.claude/skills/kopiur-design in home-operations/kopiur) into .agents/skills/kopiur-design in your project. Codex loads it when a task matches its description.

Can I use Kopiur Design in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add home-operations/kopiur --skill kopiur-design -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/kopiur-design, .gemini/skills/kopiur-design, .github/skills/kopiur-design and .opencode/skills/kopiur-design in your project.

What does Kopiur Design need to run?

Going by SKILL.md and its folder, Kopiur Design needs the command-line tools its instructions call (cargo).

Does Kopiur Design access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Kopiur Design safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Kopiur Design use?

Kopiur Design is published under the AGPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Kopiur Design use?

About 2.4k tokens (SKILL.md is roughly 9.4k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Kopiur Design?

Skills that share tags, products or a category with Kopiur Design: K8s Openapi (jinnovation/kele.el, 108 stars), Spikard (Goldziher/spikard, 124 stars), Helm Chart Scaffolding (Cybereason-Public/owLSM, 280 stars) and Tokf Run (mpecan/tokf, 199 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Kopiur Design?

home-operations (a GitHub organization) maintains it in home-operations/kopiur, which has 115 GitHub stars. The repository holds 3 skills in this directory. The repository was last updated on October 11, 2026.

Source: home-operations/kopiur on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.