Bootstraps the empty repo into a kubebuilder go/v4 project: group crawl.example.com, version v1alpha1, kind Proxy (namespaced). Keeps the existing module path and preserves the repo's Go/testing/changelog conventions from CLAUDE.md untouched. Drops the scaffolded GitHub Actions workflows since the remote is Gitea, not GitHub. Everything else is default kubebuilder output, unmodified, so later diffs stay reviewable against a known baseline. Full implementation plan: docs/plans/2026-08-07-1747-proxy-operator.md Co-Authored-By: Claude <noreply@anthropic.com>
6.1 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
What this is
A Kubernetes operator for managing egress proxies — currently an empty scaffold with no controller code yet. Intended shape: a controller-runtime manager reconciling custom resources (or existing workload types) to provision/configure egress proxy infrastructure. TODO: confirm the actual CRD(s)/API group once implemented.
Commands
No Makefile, linter, or entrypoint exists yet. Verified state as of bootstrap:
go build ./... # nothing to build yet — no .go source files exist
go test ./... # no test files exist yet
No linting or formatting tools are configured in this project yet — golangci-lint
and gofumpt are pre-approved in .claude/settings.json for when they're wired up,
but neither has a config file or CI step yet. There is no main.go or cmd/
entrypoint yet, so there's nothing to run locally.
Architecture
Not yet built. TODO: once the controller-runtime manager and reconcile loop exist, document the data-flow diagram and package/role table here, following the standard reconcile-loop shape: fetch → resolve → list related → compute desired state → merge → patch only on diff.
Conventions
Go Conventions
- Use the latest stable Go version (check https://go.dev/dl/ before starting a new feature).
- Use
slogfor structured logging. context.Contextis the first parameter of every function that does I/O or can be cancelled.- No
init()unless there is no other option. - Error wrapping:
fmt.Errorf("...: %w", err)for single errors;errors.Joinfor multiple. - Prefer stdlib over third-party dependencies where reasonable.
- No vendoring unless explicitly requested.
- Fail fast, return early.
- No obvious comments.
Testing
All new Go code must have corresponding tests.
- Use stdlib
testing— no testify unless already present in the module. - Table-driven tests are the default pattern.
- Test files live next to source:
foo.go→foo_test.go. - Name tests
Test<Function>_<scenario>(e.g.TestParseRoster_emptyInput). - Use
t.Parallel()where safe. - Use subtests for table entries:
t.Run(tc.name, func(t *testing.T) { ... }). - Test behaviour, not implementation.
- Guard slow tests with
testing.Short():if testing.Short() { t.Skip() }. - Integration tests that need real infra (DB, network) go behind
//go:build integrationand usetestcontainers-gorather than mocking the infra away.
Useful test commands
go test ./... # all unit tests
go test -v ./... # verbose
go test -cover ./... # with coverage
go test -short ./... # skip slow/integration tests
go test -v ./internal/... # specific package tree
go test -race -v -run TestName ./path/to/package # single test, race detector on
go test -tags=integration ./... # integration tests (requires infra)
Plans
When Claude Code's plan mode is used, save the plan file inside the repo at
docs/plans/YYYY-MM-DD-HHMM-<slug>.md instead of the default ~/.claude/plans/
location. Get the timestamp with date "+%Y-%m-%d-%H%M". The <slug> is a short
kebab-case summary of the plan's topic.
Include the same timestamp in the plan's header, e.g.:
# Plan: <title>
**Created:** 2026-08-07 15:30
Create docs/plans/ on first use. Plan files are committed to the repo so other
contributors can review historical decisions.
Changelog
Maintain a running changelog in CHANGELOG.md at the repo root. After every
significant change, fix, or update — once the user confirms it works — append a new
entry at the top of the file in this format:
## YYYY-MM-DD HH:MM TZ — short title
- One-line summary of what changed and why.
- Key files touched (optional, only if useful for traceability).
Get the timestamp with date "+%Y-%m-%d %H:%M %Z". Never write a literal placeholder
like HH:MM — always run date first to get the real current time. Skip trivial edits
(typos, formatting, comment tweaks); only log changes a future reader would care about.
Branching & Merge Requests
The remote is Gitea (gitea.home.hrajfrisbee.cz/kacerr/egress-proxies-operator). For
features, do not commit to main directly. Use a branch + merge request flow:
-
Create a branch off
mainbefore starting work:feat/<slug>for features (e.g.feat/roster-import)fix/<slug>for bug-fix branches the user explicitly asks for<slug>is short kebab-case
-
Commit on the branch following the commit conventions below.
-
Push the branch to
originwith-uso it tracks. -
Open the MR with
tearather than printing a compare URL:tea pr create \ --title "<short title>" \ --description "<body>" \ --base main \ --head <branch>teais already authenticated against the Gitea instance; just run it. Print the resulting PR URL for the user. Ifteais unavailable, fall back to printing the compare URL (gitea.home.hrajfrisbee.cz/kacerr/egress-proxies-operator/compare/main...<branch>) and let the user open the MR manually. -
Do not merge or delete the branch from the CLI — neither via
tea,gh, norgit push --delete. The user does that in Gitea.
Exceptions — committing straight to main is fine for:
- Small bug fixes / hotfixes the user describes as such.
- Typo / comment / formatting tweaks.
- Edits the user explicitly says to push to
main.
When uncertain whether something is a feature or a small fix, ask before branching.
Git Commits
Always append a Co-Authored-By trailer to indicate AI assistance:
Co-Authored-By: Claude <noreply@anthropic.com>
TODO: no .gitea/workflows/ CI pipeline exists yet — add a CI/CD subsection here once
one is set up.
Gotchas
- This repo currently contains only
go.mod(modulegitea.home.hrajfrisbee.cz/kacerr/egress-proxies-operator) — no controller code,main.go, Dockerfile, k8s manifests, Makefile, or CI config exist yet. Nothing in this file describes working software; it's the convention scaffold to build against.