Imported from Azure/unbounded (
AGENTS.md). Install upstream withnpx skills add Azure/unbounded. Copyright stays with the author.
Project Overview
Project Unbounded is an open source initiative to enable Kubernetes users to run worker Nodes anywhere and connect them back a running control plane. This allows you to run workloads in any environment, including on-premises, in the cloud, and at the edge, without being limited by the location of your control plane.
Repository Structure
unbounded-kube is organized into several directories:
api/- where API definitions for custom resources are located.machina/v1alpha3/- Machine CRD types (unbounded-cloud.io group).net/v1alpha1/- Net CRD types (net.unbounded-cloud.io group): Site, GatewayPool, SitePeering, etc.unbounded-storage/- shared protobuf schema (config.proto) for the unbounded-storage daemon config, the source of truth for both the daemon's Rust (prost) bindings and the supervisor's Go bindings.
bin/- where generated binary artifacts should be placed.bpf/- eBPF C programs for network encapsulation (compiled with clang).cmd/- where the sources for each binary artifact are located. Each subdirectory corresponds to a binary artifact.agent- sources for the unbounded-agent.gantry- sources for the gantry peer-to-peer OCI distribution agent.inventory- sources for the inventory controller.kubectl-unbounded- sources for thekubectl unboundedplugin (includesnetsubcommand).machina- sources for the machina controller.metalman- sources for the metalman controller.racer- standalone Rust crate for the RACER peer-to-peer distributed block device. Readcmd/racer/README.mdandcmd/racer/ARCHITECTURE.mdbefore making changes; its Cargo-based build and testing conventions differ from the Go components.unbounded-net-controller- sources for the unbounded-net network controller.unbounded-net-node- sources for the unbounded-net node agent.unbounded-net-routeplan-debug- debugging tool for route plans.unbounded-storage- sources for the Rust unbounded-storage daemon. It has its own conventions for layout, build, and testing (in particular a deterministic simulation testing harness undercmd/unbounded-storage/tests/). Agents working on anything undercmd/unbounded-storage/must readcmd/unbounded-storage/AGENTS.mdfirst; the Go-oriented rules in this file largely do not apply there.unping- health check probe utility.unroute- eBPF route inspection utility.
deploy/- component manifests for deploying on a Kubernetes cluster.machina/- machina controller manifest templates (*.yaml.tmpl) plus generated CRDs undercrd/; rendered output lives undermachina/rendered/(gitignored, produced bymake machina-manifests).gantry/- gantry DaemonSet, ConfigMap, and ServiceAccount manifests.net/- unbounded-net controller and node manifest templates (*.yaml.tmpl); rendered output lives undernet/rendered/(gitignored, produced bymake net-manifests).
designs/- design documents, proposals, and internal planning documentation for the project.docs/- public web site documentation only. Do not place design documents, plans, or ad-hoc internal docs here.frontend/- React/TypeScript web UI for network topology visualization (built with Vite).hack/- where development tools and scripts are located.cmd/- development tools that are built as Go binaries (forge, render-manifests).render-manifestsis a generic Go template renderer driven by repeatable--set key=valueflags; templates rely on sprig'sdefaultfor fallbacks.scripts/- operational and development shell scripts.scratch/- scratch space for quick go experiments.
images/- where OCI image definitions and related assets for building container images are located.e2e/- end-to-end integration test suites.gantry/- kind-based e2e tests for gantry (guarded by//go:build e2e).
internal/- where shared but internal to this project packages are located.gantry/- gantry shared packages (21 sub-packages: config, mirror, transfer, discovery, coord, hrw, coldstart, members, metrics, etc.). Includesinternal/gantry/proto/coord/v1/for the libp2p coordination RPC messages (pull intent, please-pull); kept under internal/ so the wire schema isn't an exported API surface.net/- unbounded-net shared packages (APIs, controllers, networking, metrics, webhooks, etc.).
tmp/- project local temporary directory for intermediate stuff that will be cleaned up quickly.
Building and Testing
makebuilds all binaries (kubectl-unbounded, forge, machina, and all net binaries).- To build
machinausemake machinawhich runs formatters, lint, tests, and go build. - To build
machinawithout lint/test usemake machina-build(used in Containerfiles). - To build
metalmanusemake metalmanwhich runs formatters, lint, tests, and builds the binary. - To build
metalmanwithout lint/test usemake metalman-build(used in Containerfiles). - To build individual net binaries:
make unbounded-net-controller,make unbounded-net-node,make unbounded-net-routeplan-debug,make unping,make unroute. - To build
gantryusemake gantrywhich runs tests and builds the binary. - To build
gantrywithout lint/test usemake gantry-build(used in Containerfiles). - To test
racer, installliburing-devandprotobuf-compiler, then runcargo test --locked --all-targetsandcargo test --locked --all-targets --features simfromcmd/racer/. - Net-specific build tasks (container images, frontend, eBPF, render) are exposed via
net-prefixed targets in the mainMakefile(e.g.,make net-frontend,make net-ebpf-build,make net-ebpf-generate,make net-manifests). Cluster deploy/undeploy targets live separately underhack/net/and are invoked viamake -C hack/net <target>(e.g.,make -C hack/net deploy). Runmake helpandmake -C hack/net helpfor the full lists. make generaterunsgo generate ./...to regenerate deepcopy, CRDs, and protobuf for all packages.make buildcompiles all Go packages (go build ./...).make vulncheckrunsgovulncheckand fails only on vulnerabilities that are both reachable from our code and have a published fix, since those are the ones a module bump resolves. Reachable ones with no fix available are reported and allowed through; acting on those means dropping or replacing the dependency, which is a judgment call rather than a build failure.make fmtformats Go source (gofumpt + wsl_v5 blank-line rules);make lintruns golangci-lint;make testruns all tests.make lintruns the same checks locally and in CI and does NOT auto-fix. Always runmake fmtbefore committing to satisfy the linter (gofumpt and wsl_v5 are enforced bymake lint/CI); do not hand-format.- Locally
testimplieslint. In CI (CI=1), each runs independently.
Coding Standards
- Do not cross cmd/ package boundaries. For example,
cmd/agentshould not import fromcmd/machina. If you need to share code between these packages, put it ininternal/. - Do not use em-dashes (
—) in comments, strings, or any source/config files. Use a plain ASCII hyphen (-) or rephrase the sentence instead. - Write American English, not British. Use
behavior,initialize,labeled,catalog,defense,judgment, notbehaviour,initialise,labelled,catalogue,defence,judgement. This applies to comments, doc strings, identifiers, user-facing strings, and Markdown, in every language in the repo.make lintcatches the common cases in Go viamisspell, but its dictionary is not exhaustive: it missesjudgementandacknowledgement, and it does not look at Rust, shell, TLA+, or Markdown at all. Treat it as a backstop, not the rule.make fmtrunsgolangci-lint --fix, somisspellrewrites Go sources in place. When a British spelling is deliberate, it needs an exclusion in.golangci.yamlor the nextmake fmtwill silently undo it. Exceptions are external contracts only, such as the GitHub Actionscancelled()expression and theLICENCEfilename patterns inhack/cmd/noticethat match upstream third-party files.
Testing Standards
- Add tests for new behavior. Cover success, failure, and edge cases.
Sources of Truth
- Code is authoritative. Design docs (
designs/), site docs (docs/), comments, commit messages, and PR or issue text describe intent and drift from the code over time. Treat them as leads to verify, not as evidence. - Establish what the code does before reading what it is said to do: the implementation first, then its tests for the contract as actually enforced, then the prose for intent. Read the prose too; do not skip it, and do not trust it.
- Verify before asserting:
- Read a test's assertions before citing it as a constraint. A test named for a resource may assert a floor ("must grant") rather than a ceiling ("must not grant").
- Read the enclosing block, not the matched line. A container in a pod spec may be an init container; a flag default may be unreachable.
- Confirm a symbol is reachable before assuming it takes effect. An
-Xldflag on a package the binary never imports is silently ignored.
- Cite
file:linefor any claim about behavior that a decision rests on. If a claim cannot be cited, say it is an inference. - When code and prose disagree, report both with citations rather than silently following either. The doc may be stale, or the code may be the bug, and which it is changes the work. Ask when the answer would change what gets built; offer to fix it when it is merely stale.
Boundaries
- Ask first
- Large cross-package refactors.
- New dependencies with broad impact.
- Destructive data or migration changes.
- Removal of _test.go or Test* functions or subtests.
- Proceeding when a design doc or comment contradicts the code.
- Never
- Commit secrets, credentials, or tokens.
- Edit generated files by hand when a generation workflow exists.
- Use destructive git operations unless explicitly requested.
- Go outside the project boundary, for example, DO NOT edit files in user's home directories, add or edit files in /tmp or anywhere else on the host filesystem.
Miscellaneous
- DO NOT give time or effort estimates for work in this project. For example, do not say "this is a half day project" or "this will take a week". You are a computer. You are not a person with a concept of human scheduling and time.