This file provides guidance to AI coding agents (including Claude Code) when working with code in this repository. It is an index; depth lives in docs/.
Meshery Operator is a Kubebuilder go/v4 Kubernetes
operator. Meshery Server installs one per managed cluster and thereafter manages its
health/config. It owns two CRDs and reconciles each into concrete workloads:
Broker(brokers.meshery.io) - a NATS message broker →StatefulSet, clientService, andnats.conf/accountsConfigMaps.MeshSync(meshsyncs.meshery.io) - the cluster-state synchronizer →Deployment.
Every build/test/lint workflow is Makefile-driven (make help for the full
categorized list). The Makefile installs controller-gen, kustomize, setup-envtest,
kind, golangci-lint, and opm on demand into ./bin at pinned versions - none need
to be on PATH. Go version is pinned in go.mod (CI resolves it via go-version-file).
| Command | Purpose |
|---|---|
make build |
Compile cmd/main.go into bin/manager. |
make test |
manifests generate fmt vet, then unit + envtest suites (auto-resolves KUBEBUILDER_ASSETS via setup-envtest). |
go test ./pkg/... |
Just the fast unit tests (resource builders, pure helpers) - no control plane. |
go test ./controllers/... ./pkg/broker/... |
Just the Ginkgo/Gomega envtest suites. |
go test ./pkg/broker/... -run TestXxx |
Run a single Go test. |
make lint / make lint-fix |
Run / auto-fix golangci-lint. |
make manifests generate |
Regenerate CRDs, the RBAC ClusterRole, and zz_generated.deepcopy.go from +kubebuilder markers. Required after any API type or marker change - CI fails on drift. |
make nats-manifests |
Re-render pkg/broker/manifests/nats.gen.yaml from the pinned official NATS Helm chart (NATS_CHART_VERSION) + pkg/broker/chart/values.yaml. CI has a drift gate for this too. |
make error |
Read-only MeshKit error-registry check (uniqueness, deprecated NewDefault usage). Run after touching any error.go. |
make error-util |
Assign codes to new error placeholders and bump next_error_code in helpers/component_info.json. |
make run / make install / make deploy |
Run the manager locally against the current kube-context / install CRDs / deploy the operator into the cluster. |
make integration-tests |
Full kind e2e cycle: build image, load into kind, deploy, assert Broker/MeshSync become ready. Needs Docker + kind. |
make bundle |
Regenerate and validate the OLM bundle (needs operator-sdk on PATH). |
Component map - full detail in docs/architecture.md and the modernization plan:
api/v1alpha1/,api/v1alpha2/- CRD Go types;v1alpha2is the conversion hub (storage version),v1alpha1a spoke served via the conversion webhook.controllers/- Broker/MeshSync reconcilers: finalizer → create-or-sync owned objects → health check → statusConditionpatch;pkg/metricsrecorded via named returns.pkg/broker/+pkg/meshsync/- hand-authored resource builders; the NATS topology is rendered from the vendored chart (make nats-manifests).pkg/client/v1alpha1/- typed clientset consumed by Meshery Server; anyv1alpha1change must preserve this surface.config/- Kustomize bases;bundle/- the OLM bundle generated fromconfig/manifests.
Nothing this repo ships may reference a moving channel tag (stable-latest,
edge-latest, latest) - not the manager image in config//bundle/, not the
managed-component defaults in pkg/meshsync and the vendored NATS chart. A
moving tag is re-pointed in place, so an artifact a user applied months ago
silently starts pulling a build it was never rendered against. Each pin has its
own automation that advances it; do not hand-edit them. CI greps the rendered
artifacts and TestDefaultMeshSyncVersionIsPinned guards the Go default.
Mechanisms and the failure this closes: docs/release-process.md § Pinned
images.
All errors are MeshKit structured errors (github.com/meshery/meshkit/errors), never
fmt.Errorf/errors.New: one exported Err...Code constant plus one constructor per
error, with codes unique across the whole component and allocated from
helpers/component_info.json. Run make error after touching any error.go.
Full convention and example: docs/errors.md.
Three tiers: unit (go test ./pkg/...), envtest (make test), and kind e2e
(make integration-tests). The release scripts in hack/ are covered by Go tests in
that same directory (go test ./hack/...), driven against a fixture copy of
meshery/meshery's chart tree - refresh hack/testdata/ when that chart's shape
changes. New behavior gets a case added to the existing suite file
for its package, not a new test file. envtest caveats and e2e knobs: docs/testing.md.
Wire is camelCase everywhere; DB is snake_case; Go fields follow Go idiom; the ORM layer is the sole translation boundary.
- Authoritative source:
meshery/schemas/AGENTS.md § Casing rules at a glance - Reader-friendly directory: https://github.com/meshery/schemas/blob/master/docs/identifier-naming-contributor-guide.md
- The contract is not optional; deviations block PRs via the schemas consumer-audit CI gate. On any conflict, schemas wins - file discrepancies as issues against
meshery/schemas, not locally. Id(camelCase), neverID, in URL params, JSON tags, and TypeScript properties.- meshery-operator: Go types follow Go idiom; CRD serialized field names are camelCase per Kubernetes API conventions, which coincides with the ecosystem wire contract. The consumer audit applies wherever operator types cross the wire to Meshery Server.
- Tests accompany every behavioral change. Run every locally-runnable test before requesting review; never defer runnable coverage to reviewers or follow-up PRs.
- Documentation accompanies every behavioral change, in both forms:
- External, user-facing: docs.meshery.io (source: meshery/meshery docs) - update whenever the change is user-visible.
- Internal, developer-facing: this repo's
docs/- update whenever architecture, workflows, or contracts change.
- Schema-aware changes: run
cd ../schemas && make validate-schemas && make consumer-auditbefore pushing. - Sign off every commit (
git commit -s). - No AI attribution in commits, PR descriptions, comments, or code.
No AI attribution means: no "Co-Authored-By" trailers naming an AI vendor, no
"Generated with/by" boilerplate naming an AI tool, and no links to an AI vendor's share
domains. A hook registered in the tracked .claude/settings.json blocks any Bash command
(including git commit) or file write matching these patterns, so it applies to a fresh
clone with no further setup. Shared agent configuration belongs in that tracked file;
.claude/settings.local.json is per-developer state and is git-ignored.
Cloned this repo before that split? Pulling that change deletes your local file and leaves the promoted hooks firing twice - recover it and prune them with docs/development.md.
- docs/architecture.md - CRDs, conversion hub/webhook, controller shape, resource builders, vendored NATS chart, typed client, packaging, known structural debt. Read before structural changes.
- docs/development.md - local setup,
.claude/agent configuration, Makefile targets, tool pinning, CRD release artifacts. - docs/testing.md - the three test tiers in detail, envtest caveats, kind e2e environment knobs.
- docs/errors.md - the full MeshKit error convention, example constructor, and per-file code registries.
- docs/metrics.md - reconciliation metrics and why named returns are required.
- docs/release-process.md - release flow, downstream chart/CRD sync into
meshery/meshery, and the mechanisms behind No moving image tags above. - docs/proposals/operator-modernization-plan.md - the active roadmap; code comments referencing
WS-N(e.g.WS-3) point at that plan's workstreams.
Keep this file for knowledge useful to almost every future agent session in this project. Do not repeat what the codebase already shows; point to the authoritative file or command instead. Prefer rewriting or pruning existing entries over appending new ones. When updating this file, preserve this bar for all agents and keep entries concise.