Agent skill

Kubernetes Operator

by alirezarezvani in alirezarezvani/claude-skills

A skill your agent uses when building a Kubernetes Operator — custom controllers that reconcile CRD state.

MITAuto-check passedDevOps & Cloud

Install Kubernetes Operator

skills CLI
$ npx skills add alirezarezvani/claude-skills --skill kubernetes-operator -a claude-code

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

GitHub CLI
$ gh skill install alirezarezvani/claude-skills kubernetes-operator --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/alirezarezvani/claude-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/engineering/skills/kubernetes-operator .claude/skills/kubernetes-operator && 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
kubernetes-operator
GitHub stars
28k
Token cost
~2.8k tokens
SKILL.md length
960 words
Files
10 (incl. scripts, references, assets)
Skills in repo
342
Repo updated
First seen
Licence
MIT

At a glance

A skill your agent uses when building a Kubernetes Operator — custom controllers that reconcile CRD state.

  • Works in 7 steps: Treat reconcile as imperative (do this,… → Don't requeue transient failures → Don't use finalizers, leaving orphan… → …
  • Building a Kubernetes Operator — custom controllers that reconcile CRD state
  • SKILL.md covers When to use, When NOT to use, Core principle: an operator is… and Quick start, plus 10 more sections
  • Runs Python and Go scripts from its folder; calls python and kubectl

What it does

Kubernetes Operator is an agent skill from alirezarezvani/claude-skills. Use when building a Kubernetes Operator — custom controllers that reconcile CRD state. Triggers on "build an operator", "CRD design", "reconcile loop", "controller-runtime", "kubebuilder", "operator-sdk", "metacontroller", "KOPF", "operator capability levels", or "custom resource". Ships CRD validator, reconcile-loop linter, and OperatorHub capability auditor (all stdlib Python), 4 references on the operator pattern + CRD design + reconcile patterns + tooling landscape, and a /operator-audit slash command. NOT a…

Its SKILL.md is about 2.8k tokens, which your agent loads only when the skill is triggered. The skill folder holds 12 other files, including scripts, reference files and assets (for example `assets/crd_template.yaml`, `references/crd_design.md` and `references/operator_pattern.md`).

It sits in DevOps & Cloud, covering Container orchestration. It works with Kubernetes and Python. The repository describes itself as: 380 Claude Code skills & agent skills & plugins (30+ Agents, 70+ custom commands, 380+ skills, customizable references, scripts)for Claude Code, Codex, Gemini CLI, Cursor, and 8… The licence is MIT.

When your agent uses it

  • Building a Kubernetes Operator — custom controllers that reconcile CRD state
  • Build an operator
  • Controller-runtime
  • Operator capability levels

Example prompts

  • “build an operator”
  • “CRD design”
  • “reconcile loop”
  • “/kubernetes-operator”

Requirements

  • Python 3

Workflow steps

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

  1. Treat reconcile as imperative (do this, then this, then this) instead of declarative (make actual=desired, idempotently)
  2. Don't requeue transient failures
  3. Don't use finalizers, leaving orphan resources
  4. Mutate spec instead of status
  5. Don't use the status subresource (status updates trigger spec reconciles → loop)
  6. Block in reconcile (long HTTP calls, locks)
  7. Forget leader election → split-brain on multi-replica deploys

What it can do on your machine

Read from SKILL.md and the folder at commit 19392f7. 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

    Ships 3 files in scripts/ (Python and Go), which the agent can run.

    Shell commands in SKILL.md call:

    • python
    • kubectl

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

  • Network

    No URLs in SKILL.md. Its commands use kubectl, which can reach the network depending on how they are called.

    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

Kubernetes Operator loads about 2.8k tokens when it runs, and up to ~10k if it reads all its reference files. Until then it costs about 148 tokens; SKILL.md has 960 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~148
When it runs · the whole SKILL.md, loaded when a task matches
~2.8k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~10k

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); the scripts in this folder are not scanned.

SKILL.md

The full file from alirezarezvani/claude-skills at commit 19392f7, republished under its MIT licence (© alirezarezvani). 960 words, ~2,787 tokens.

Download SKILL.mdSave it as .claude/skills/kubernetes-operator/SKILL.md (or your agent's skills folder). This skill also uses 9 other files; get the full folder from GitHub.
name
kubernetes-operator
description
Use when building a Kubernetes Operator — custom controllers that reconcile CRD state. Triggers on "build an operator", "CRD design", "reconcile loop", "controller-runtime", "kubebuilder", "operator-sdk", "metacontroller", "KOPF", "operator capability levels", or "custom resource". Ships CRD validator, reconcile-loop linter, and OperatorHub capability auditor (all stdlib Python), 4 references on the operator pattern + CRD design + reconcile patterns + tooling landscape, and a /operator-audit slash command. NOT a generic k8s skill — specifically the Operator pattern.
context
fork
version
2.9.0
author
claude-code-skills
license
MIT
tags
kubernetes, operator, crd, controller-runtime, kubebuilder, operator-sdk, metacontroller, kopf, reconcile, devops
compatible_tools
claude-code, codex-cli, cursor, antigravity, opencode, gemini-cli

Kubernetes Operator

Build operators that reconcile correctly. Most operator bugs are not Kubernetes bugs — they are reconcile-loop bugs: missing finalizers, blocking calls, no requeue on transient errors, status drift, RBAC over-grants. This skill catches them deterministically before they reach a cluster.

When to use

  • Building a new Kubernetes Operator (controller for a CRD)
  • Reviewing an existing operator for capability-level gaps
  • Auditing a CRD spec for status/conditions/finalizer correctness
  • Choosing a framework (controller-runtime / kubebuilder / operator-sdk / metacontroller / KOPF)
  • Designing the API surface of a Custom Resource
  • Hardening RBAC, leader election, or webhook validation

When NOT to use

  • Plain Helm chart packaging → use helm-chart-builder
  • Standard kubectl operations / blue-green deploys → use senior-devops
  • General k8s security posture → use cloud-security
  • "I want to run a workload" — that's a Deployment / Job, not an operator

Core principle: an operator is a reconcile loop, not a script

observe(actual) → desired = read(spec) → diff(actual, desired) → act → update(status)
                                                                          ↓
                                                                   requeue / done

Operators that fail are the ones that:

  1. Treat reconcile as imperative (do this, then this, then this) instead of declarative (make actual=desired, idempotently)
  2. Don't requeue transient failures
  3. Don't use finalizers, leaving orphan resources
  4. Mutate spec instead of status
  5. Don't use the status subresource (status updates trigger spec reconciles → loop)
  6. Block in reconcile (long HTTP calls, locks)
  7. Forget leader election → split-brain on multi-replica deploys

The 3 tools below catch each of these.

Quick start

bash
SKILL=engineering/kubernetes-operator/skills/kubernetes-operator

# Validate a CRD design
python "$SKILL/scripts/crd_validator.py" --crd config/crd/myapp.yaml

# Lint a Go reconcile function
python "$SKILL/scripts/reconcile_lint.py" --controller controllers/myapp_controller.go

# Score against OperatorHub Capability Levels (1-5)
python "$SKILL/scripts/operator_capability_audit.py" --operator-dir .

The 3 Python tools

All stdlib-only. Run with --help.

crd_validator.py

Validates a CRD YAML against operator-pattern best practices.

bash
python scripts/crd_validator.py --crd config/crd/myapp.yaml
python scripts/crd_validator.py --crd config/crd/ --format json

Checks:

  • spec.versions[*].subresources.status is set (status subresource)
  • spec.scope is Namespaced (not Cluster) unless explicitly justified
  • Singular and listKind defined
  • spec.versions[*].schema.openAPIV3Schema has type definitions (no x-kubernetes-preserve-unknown-fields: true at top level)
  • A version is marked served: true AND storage: true
  • Conditions array is in the schema (allows metav1.Conditions)
  • Printer columns include Age and Status/Phase
reconcile_lint.py

Lints a Go controller reconcile function for anti-patterns.

bash
python scripts/reconcile_lint.py --controller controllers/myapp_controller.go

Checks (regex-based heuristics):

  • Returns are (ctrl.Result, error) shape
  • Errors trigger a non-zero requeue (return ctrl.Result{Requeue: true}, err)
  • client.Update() on the spec object is flagged (controllers should update only status)
  • time.Sleep inside reconcile is flagged (use RequeueAfter)
  • HTTP calls without context cancellation are flagged
  • Missing defer after a finalizer add
  • No IsConditionTrue / SetCondition calls when conditions present in CRD
  • Reconcile function exceeds 80 lines (extract subroutines)
operator_capability_audit.py

Scores an operator against OperatorHub's 5 Capability Levels.

bash
python scripts/operator_capability_audit.py --operator-dir .

Levels:

  • L1 — Basic Install: CRD defined, controller deploys it
  • L2 — Seamless Upgrades: PDBs, conversion webhooks, version skew strategy
  • L3 — Full Lifecycle: backups, restores, failure recovery
  • L4 — Deep Insights: metrics endpoint, Prometheus rules, alerts
  • L5 — Auto Pilot: auto-scaling, auto-tuning, anomaly detection

Reports current level + concrete next steps to advance one level.

Tooling landscape

Pick a framework based on language and complexity. See references/tooling_landscape.md.

FrameworkLanguageBest forMaintenance
controller-runtimeGoProduction-grade, low-level controlActive (sig-api-machinery)
kubebuilderGoStandard scaffolding, opinionatedActive (Kubernetes SIGs)
operator-sdkGo / Helm / AnsibleOpenShift / mixed-paradigm teamsActive (Red Hat)
metacontrollerAny (webhook-based)Polyglot teams, avoiding GoLess active
KOPFPythonPython shops, async-firstActive (community)
java-operator-sdkJavaJVM shopsActive (Red Hat / Java SIG)

Decision rules:

  • New operator + Go shop → kubebuilder
  • New operator + Python shop → KOPF
  • New operator + can't pick a language → metacontroller
  • OpenShift target → operator-sdk

CRD design principles

See references/crd_design.md for full detail. Quick rules:

  1. status is the source of truth for the controller's view of the world. Spec is what the user wants; status is what the controller observed.
  2. Use the status subresource. Without it, status updates re-trigger reconcile (loop).
  3. Use Conditions. Ready, Reconciling, Degraded. Each carries a reason and message.
  4. Add finalizers. Without finalizers, deletion races the controller and orphans external resources.
  5. Version your CRD from day 1. v1alpha1 → v1beta1 → v1. Plan a conversion webhook.
  6. Validate via OpenAPI v3 schema. Don't rely on the controller for validation that should fail at admission.
  7. Use additionalPrinterColumns for kubectl get. Show Age, Phase, Ready at minimum.
  8. Namespace your CRDs unless they manage cluster-scoped resources.
Show full SKILL.md (326 more words)Show less

Reconcile loop principles

See references/reconcile_loop.md for full detail. Quick rules:

  1. Idempotent. Reconciling the same state twice → same result, zero side effects.
  2. Read once, decide, act. Don't observe the world repeatedly during reconcile.
  3. Update status, not spec. Spec belongs to the user.
  4. Return errors that requeue. Use ctrl.Result{RequeueAfter: ...} for known transient cases.
  5. Never block. No time.Sleep. No long HTTP calls without context.
  6. Use the cache. Read via the controller's cached client; only escape the cache for a specific reason.
  7. Leader-elect when running >1 replica. Otherwise enable single-replica mode.
  8. Set OwnerReferences. Cascading deletion is the operator pattern's free gift.

Workflows

Workflow 1: Bootstrap a new operator (Go + kubebuilder)
1. Pick a Group/Version/Kind: e.g., apps.example.com/v1alpha1, kind=MyApp
2. kubebuilder init --domain example.com --repo github.com/org/myapp-operator
3. kubebuilder create api --group apps --version v1alpha1 --kind MyApp
4. Run crd_validator.py on config/crd/bases/apps.example.com_myapps.yaml
   → Fix every WARN before writing controller code
5. Implement the reconcile function (Karpathy principle 2: simplest correct version first)
6. Run reconcile_lint.py on controllers/myapp_controller.go
7. Run operator_capability_audit.py --operator-dir . — confirm L1
8. Test in a kind cluster: kubectl apply -f config/samples/
9. Add status conditions; aim for L2 in the same PR
Workflow 2: Audit an existing operator
1. Run operator_capability_audit.py --operator-dir <path>
2. Run crd_validator.py --crd config/crd/
3. Run reconcile_lint.py --controller controllers/
4. Triage findings:
   - FAIL → block release; fix before next deploy
   - WARN → file an issue; fix in next 30 days
5. Document current capability level in README; commit
6. Plan one capability level advancement per quarter
Workflow 3: Choose a framework
1. Identify primary language constraint (team skill)
2. Identify deployment target (vanilla k8s vs OpenShift)
3. Identify operator complexity (single CRD vs multi-CRD vs cluster-wide)
4. Cross-reference with references/tooling_landscape.md
5. Build a 1-week proof-of-concept before committing

References

  • references/operator_pattern.md — what an operator IS, when to use vs alternatives
  • references/crd_design.md — CRD design principles, versioning, conversion webhooks
  • references/reconcile_loop.md — reconcile patterns, error handling, idempotency
  • references/tooling_landscape.md — framework comparison + decision tree

Slash command

/operator-audit — Run all 3 tools on an operator repo and produce a markdown report.

Asset templates

  • assets/crd_template.yaml — CRD with status subresource, conditions, finalizer hint, printer columns
  • assets/reconcile_skeleton.go — Go controller reconcile function with idempotency, conditions, finalizers, requeue patterns

Anti-patterns

  • time.Sleep(30 * time.Second) inside reconcile — block other reconciles. Use RequeueAfter.
  • r.Client.Update(ctx, obj) to set status — use r.Status().Update(ctx, obj) instead.
  • No leader election + 2+ replicas — split-brain.
  • No finalizer — external resources orphan on deletion.
  • CRD without status subresource — status updates trigger spec reconciles (infinite loop).
  • Reconcile function > 200 lines — extract reconcileXxx subroutines per condition.
  • x-kubernetes-preserve-unknown-fields: true on spec root — defeats validation.
  • Imperative reconcile — "if creating, do A; if updating, do B; if deleting, do C". Wrong shape. Reconcile = make actual=desired, regardless of how we got here.

Verifiable success

A team using this skill should achieve:

  • 100% of new CRDs pass crd_validator.py before merge
  • All reconcile functions pass reconcile_lint.py strict mode
  • Operators reach OperatorHub Capability Level 3 (Full Lifecycle) before public release
  • Mean time to fix a reconcile bug: <1 day (no infinite loops in production)

© alirezarezvani, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 9 other files (scripts, references, assets) in engineering/skills/kubernetes-operator of alirezarezvani/claude-skills.

  • SKILL.md
  • assets/crd_template.yaml
  • assets/reconcile_skeleton.go
  • references/crd_design.md
  • references/operator_pattern.md
  • references/reconcile_loop.md
  • references/tooling_landscape.md
  • scripts/crd_validator.py
  • scripts/operator_capability_audit.py
  • scripts/reconcile_lint.py

Open the folder on GitHubat commit 19392f7

Compare with similar skills

Kubernetes Operator 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.

Kubernetes Operator compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Kubernetes Operator this skillalirezarezvani/claude-skills28k—~2.8kAutomated safety check: PassMIT
Vetatilladeniz/Kubeli3873 repos~1.6kAutomated safety check: PassMIT
Alibabacloud Ecs Sec Userspacealiyun/alibabacloud-ecs-troubleshoot-skills1481 repos~2.6kAutomated safety check: NotesApache-2.0
Dstack Presetsdstackai/dstack2.3k—~403Automated safety check: PassMPL-2.0
Toolsastronomer/astronomer491—~1.1kAutomated safety check: PassCustom licence
Dstackdstackai/dstack2.3k—~6.2kAutomated safety check: WarnMPL-2.0

Similar skills

  • Vet

    atilladeniz/Kubeli

    Run vet immediately after ANY logical unit of code changes. An agent skill from atilladeniz/Kubeli.

    387 GitHub starsUsed in 3 repos~1.6k tokens
    DevOps & CloudAuto-check passed
  • Alibabacloud Ecs Sec Userspace

    aliyun/alibabacloud-ecs-troubleshoot-skills

    Linux 用户态安全入侵检测与取证工具,专为 AI Agent 设计。自动判断服务器是否被入侵, 提供完整证据链和可执行修复建议。51 个安全分析器覆盖进程/网络/认证/持久化/Rootkit/ 恶意软件/内存取证/容器逃逸等 12 类检测维度,10 个数据采集器全面采集系统状态, 映射 103+ MITRE ATT&CK 技术,支持 standalone/docker/k8s 三种部署模式。

    148 GitHub starsUsed in 1 repo~2.6k tokens
    DevOps & CloudAuto-check: notes
  • Dstack Presets

    dstackai/dstack

    Create and manage dstack presets: a toolkit that streamlines model inference optimization with agents, and a portable preset format.

    2.3k GitHub stars~403 tokensUpdated yesterday
    DevOps & CloudAuto-check passed
  • Tools

    astronomer/astronomer

    A skill your agent uses when writing, editing, or reviewing command-line tools and helper scripts in this repo (things in bin/).

    491 GitHub stars~1.1k tokensUpdated today
    DevOps & CloudAuto-check passed
  • Dstack

    dstackai/dstack

    dstack is an open-source control plane for GPU provisioning and orchestration across GPU clouds, Kubernetes, and on-prem clusters.

    2.3k GitHub stars~6.2k tokensUpdated yesterday
    DevOps & CloudAuto-check: warnings
  • Asdf

    jjmartres/opencode

    A skill your agent uses whenever the user wants to install, configure, or use asdf (asdf-vm), the universal version manager.

    133 GitHub starsUsed in 1 repo~2.1k tokens
    DevOps & CloudAuto-check: notes

More from alirezarezvani/claude-skills

All 342 skills in this repo
  • Agile Product Owner

    alirezarezvani/claude-skills

    Writes INVEST-checked user stories with acceptance criteria, splits epics, plans sprints from velocity and ranks the backlog with a weighted score.

    28k GitHub starsUsed in 3 repos~3.2k tokens
    Auto-check passed
  • Product Strategist

    alirezarezvani/claude-skills

    OKR cascade toolkit for product leaders: generates aligned company-to-team OKRs from five strategy types and scores how well they line up.

    28k GitHub starsUsed in 2 repos~1.8k tokens
    Auto-check passed
  • App Store Optimization

    alirezarezvani/claude-skills

    App Store Optimization (ASO) toolkit for researching keywords, analyzing competitor rankings, generating metadata suggestions, and improving app visibility on Apple App Store and Google Play Store.

    28k GitHub starsUsed in 1 repo~4.2k tokens
    Auto-check passed
  • AWS Solution Architect

    alirezarezvani/claude-skills

    Design AWS architectures for startups using serverless patterns and IaC templates.

    28k GitHub starsUsed in 1 repo~2.5k tokens
    Auto-check passed
  • Campaign Analytics

    alirezarezvani/claude-skills

    Calculates attribution, funnel and ROI figures for marketing campaigns with three Python scripts that need only the standard library.

    28k GitHub starsUsed in 1 repo~2.1k tokens
    Auto-check passed
  • Code to PRD

    alirezarezvani/claude-skills

    Reverse-engineers a frontend, backend or fullstack codebase into a product requirements document with per-page docs, an enum dictionary and an API inventory.

    28k GitHub starsUsed in 1 repo~4.9k tokens
    Auto-check passed

Categories

Questions about Kubernetes Operator

What does Kubernetes Operator do?

A skill your agent uses when building a Kubernetes Operator — custom controllers that reconcile CRD state. Kubernetes Operator is an agent skill from alirezarezvani/claude-skills. Use when building a Kubernetes Operator — custom controllers that reconcile CRD state.

When should I use Kubernetes Operator?

Kubernetes Operator fits situations like: building a Kubernetes Operator — custom controllers that reconcile CRD state; build an operator; controller-runtime; operator capability levels.

How do I install Kubernetes Operator in Claude Code?

Run `npx skills add alirezarezvani/claude-skills --skill kubernetes-operator -a claude-code`. Or copy the skill folder (engineering/skills/kubernetes-operator in alirezarezvani/claude-skills) into .claude/skills/kubernetes-operator in your project. Claude Code loads it when a task matches its description.

How do I install Kubernetes Operator in Codex?

Run `npx skills add alirezarezvani/claude-skills --skill kubernetes-operator -a codex`. Or copy the skill folder (engineering/skills/kubernetes-operator in alirezarezvani/claude-skills) into .agents/skills/kubernetes-operator in your project. Codex loads it when a task matches its description.

Can I use Kubernetes Operator 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 alirezarezvani/claude-skills --skill kubernetes-operator -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/kubernetes-operator, .gemini/skills/kubernetes-operator, .github/skills/kubernetes-operator and .opencode/skills/kubernetes-operator in your project.

What does Kubernetes Operator need to run?

Going by SKILL.md and its folder, Kubernetes Operator needs Python and Go for the scripts in its folder and the command-line tools its instructions call (python and kubectl). Our summary lists: Python 3.

Does Kubernetes Operator 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 Kubernetes Operator 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. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.

What licence does Kubernetes Operator use?

Kubernetes Operator is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Kubernetes Operator use?

About 2.8k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 7.3k tokens, read only when the agent opens those files.

What are the alternatives to Kubernetes Operator?

Skills that share tags, products or a category with Kubernetes Operator: Vet (atilladeniz/Kubeli, 387 stars), Alibabacloud Ecs Sec Userspace (aliyun/alibabacloud-ecs-troubleshoot-skills, 148 stars), Dstack Presets (dstackai/dstack, 2.3k stars) and Tools (astronomer/astronomer, 491 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Kubernetes Operator?

alirezarezvani (a GitHub user) maintains it in alirezarezvani/claude-skills, which has 27,829 GitHub stars. The repository holds 342 skills in this directory. The repository was last updated on August 30, 2026.

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