Thank you for your interest in contributing to Agent Control Plane (formerly known as vTeam)! This document provides guidelines and instructions for contributing to the project.
- Code of Conduct
- Ways to Contribute
- Getting Started
- Development Workflow
- Code Standards
- Testing Requirements
- Pull Request Process
- Local Development Setup
- Troubleshooting
- Getting Help
- License
By participating in this project, you agree to maintain a respectful and inclusive environment for all contributors. We expect:
- Respectful and constructive communication
- Welcoming and inclusive behavior
- Focus on what is best for the community
- Showing empathy towards other community members
There are many ways to contribute to Agent Control Plane:
If you find a bug, please create an issue with:
- Clear, descriptive title
- Steps to reproduce the problem
- Expected vs actual behavior
- Environment details (OS, cluster version, etc.)
- Relevant logs or screenshots
We welcome feature suggestions! Please:
- Check if the feature has already been suggested
- Provide a clear use case and rationale
- Consider implementation approaches
- Be open to discussion and feedback
Documentation improvements are always appreciated:
- Fix typos or clarify unclear sections
- Add examples or tutorials
- Document undocumented features
- Improve error messages
Code contributions should:
- Follow our code standards (see below)
- Include tests where applicable
- Update documentation as needed
- Pass all CI/CD checks
Before contributing, ensure you have:
- Go 1.25+ (for API server and control plane development)
- Node.js 20+ and npm (for UI development)
- Python 3.12+ (for runner development)
- Podman or Docker (for building containers)
- Kind and kubectl (for local development)
- Git for version control
- Fork the repository on GitHub
- Clone your fork locally:
git clone https://github.com/YOUR_USERNAME/agent-control-plane.git cd agent-control-plane - Add the upstream repository:
git remote add upstream https://github.com/openshift-online/agent-control-plane.git
We use the pre-commit framework to run linters and branch protection checks automatically on every commit. Install with:
make setup-hooksOr run the installation script directly:
./scripts/install-git-hooks.shWhat runs on every commit:
- File hygiene - trailing whitespace, EOF fixer, YAML validation, large file check, merge conflict markers, private key detection
- Python -
ruff format+ruff check --fix(runners and scripts) - Go -
gofmt,go vet,golangci-lint(API server, control plane, CLI) - Branch protection - blocks commits to
main/master/production
What runs on push:
- Push protection - blocks pushes to
main/master/production
Run all hooks manually:
make lint
# or: pre-commit run --all-filesIf you need to override the hooks (e.g., for hotfixes):
git commit --no-verify -m "hotfix: critical fix"
git push --no-verify origin mainSee scripts/git-hooks/README.md for more details.
Always work on a feature branch, not main:
git checkout main
git pull upstream main
git checkout -b feature/your-feature-nameBranch naming conventions:
feature/- New featuresfix/- Bug fixesdocs/- Documentation changesrefactor/- Code refactoringtest/- Test improvements
- Follow the existing code patterns and style
- Write clear, descriptive commit messages
- Keep commits focused and atomic
- Test your changes locally
Use conventional commit messages:
git commit -m "feat: add multi-repo session support"
git commit -m "fix: resolve PVC mounting issue in kind cluster"
git commit -m "docs: update local development setup instructions"
git commit -m "test: add integration tests for operator"Commit message prefixes:
feat:- New featurefix:- Bug fixdocs:- Documentation changesstyle:- Code style changes (formatting, etc.)refactor:- Code refactoringtest:- Adding or updating testschore:- Maintenance tasks
Regularly sync with upstream:
git fetch upstream
git rebase upstream/maingit push origin feature/your-feature-nameThen create a Pull Request on GitHub.
Formatting:
# Auto-format your code
gofmt -w components/ambient-api-server components/ambient-control-planeQuality Checks:
# API Server
cd components/ambient-api-server
gofmt -l . # Check formatting (should output nothing)
go vet ./... # Detect suspicious constructs
golangci-lint run # Run comprehensive linting
# Control Plane
cd components/ambient-control-plane
gofmt -l .
go vet ./...
golangci-lint runInstall golangci-lint:
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latestBest Practices:
- Use explicit error handling, never
panic()in production code - Always use user-scoped Kubernetes clients for API operations
- Implement proper RBAC checks before resource access
- Never log sensitive data (tokens, API keys)
- Use
unstructured.Nested*helpers for type-safe CR access - Set OwnerReferences on child resources for automatic cleanup
See CLAUDE.md for comprehensive backend/operator development standards.
cd components/ambient-ui
npm run lint # ESLint checks
npm run build # Ensure builds without errors/warningsBest Practices:
- Zero
anytypes (use proper TypeScript types) - Use Shadcn UI components only (no custom UI from scratch)
- Use React Query for ALL data operations (no manual
fetch()) - Use
typeoverinterface - Colocate single-use components with their pages
- All buttons must show loading states
- All lists must have empty states
- All nested pages must have breadcrumbs
cd components/runners/ambient-runner
# Format code
ruff format .
# Lint (with auto-fix)
ruff check --fix .Standards:
- Use
ruff formatfor formatting - Use
ruff checkfor linting - Follow PEP 8 conventions
- Add type hints where appropriate
cd components/ambient-api-server
make testcd components/ambient-control-plane
go test ./... -vcd components/ambient-ui
npx vitest runTesting Guidelines:
- Add tests for new features
- Ensure tests pass locally before pushing
- Aim for meaningful test coverage
- Write clear test descriptions
- Use table-driven tests in Go
- Run all quality checks for the components you modified
- Run tests and ensure they pass
- Update documentation if you changed functionality
- Rebase on latest main to avoid merge conflicts
- Test locally with Kind if possible
Your PR should include:
- Clear title describing the change
- Description of what changed and why
- Related issues (use "Fixes #123" or "Relates to #123")
- Testing performed - how you verified the changes
- Screenshots (if UI changes)
- Breaking changes (if any)
- All PRs require at least one approval
- GitHub Actions will automatically run:
- Go linting checks (gofmt, go vet, golangci-lint)
- Component builds
- Tests
- Address review feedback promptly
- Keep discussions focused and professional
- Be open to suggestions and alternative approaches
- Squash commits will happen automatically on merge
- Your PR will be merged to
main - Delete your feature branch after merge
The recommended way to develop and test Agent Control Plane locally is using Kind (Kubernetes in Docker). This provides a lightweight Kubernetes environment that matches our CI/CD setup.
# Install using Homebrew
brew install kind kubectl docker# Install kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
# Install Kind
curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
# Install Docker
# Follow: https://docs.docker.com/engine/install/Once Kind and prerequisites are installed, you can start the complete development environment with a single command:
make kind-upThis command will:
- Create Kind cluster (~30 seconds)
- Deploy all components (API server, control plane, UI)
- Deploy Keycloak with a pre-configured dev realm
- Set up port forwarding
- Load container images
The setup takes ~2 minutes on first run.
make kind-port-forward # In another terminal
# Open the frontend URL shown in the outputYou'll be redirected to Keycloak for login. Use developer / developer.
Stop and delete the Kind cluster:
make kind-downRestart:
make kind-upCheck status:
kubectl get pods -n ambient-code
kubectl get svc -n ambient-codeView logs:
kubectl logs -n ambient-code deployment/ambient-api-server -f
kubectl logs -n ambient-code deployment/ambient-ui -f
kubectl logs -n ambient-code deployment/ambient-control-plane -fCleanup:
make kind-down # Delete Kind clusterRun tests:
make test-e2e-local # Run E2E tests with Kind# Check Docker is running
docker ps
# Delete and recreate cluster
make kind-down
make kind-up# Check pod status
kubectl get pods -n ambient-code
# View pod details
kubectl describe pod <pod-name> -n ambient-code
# Check logs
kubectl logs <pod-name> -n ambient-code# Check if port 8080 is in use
lsof -i :8080
# Restart port forwarding
make kind-down
make kind-upIf Kind cluster is broken:
# Delete cluster
kind delete cluster --name ambient-code
# Recreate
make kind-upFor testing OpenShift-specific features like Routes, you can use CRC (CodeReady Containers / OpenShift Local).
# Install CRC (Fedora/RHEL)
sudo dnf install crc
# macOS
brew install --cask red-hat-openshift-local
# Start CRC (first run downloads the VM image)
crc setup
crc start
# Configure shell and login
eval $(crc oc-env)
oc login -u kubeadmin https://api.crc.testing:6443make crc-up # Build, deploy, and configure ACP on CRC
make crc-reload-images # Rebuild and push changed images (like kind-rebuild)
make crc-reload-component CRC_COMPONENT=ambient-api-server # Reload single component
make crc-down # Remove ACP from CRC (leaves CRC running)CRC uses self-signed CAs for TLS. After make crc-up, download both CA certificates and install them into your system trust store. This is only needed on CRC — production clusters use a real CA whose certs are already trusted.
Two CAs are required:
- Gateway CA (
acpgw-ca) — for*.acpgw.apps-crc.testing(openshell gateway connections via Gateway API) - CRC router CA (
router-ca) — for*.apps-crc.testing(Keycloak, API server, UI)
# Download both CAs into a single bundle
oc get secret acpgw-ca -n openshift-ingress -o jsonpath='{.data.ca\.crt}' | base64 -d > crc-ca-bundle.crt
oc get secret router-ca -n openshift-ingress-operator -o jsonpath='{.data.tls\.crt}' | base64 -d >> crc-ca-bundle.crtLinux (Fedora/RHEL):
sudo cp crc-ca-bundle.crt /etc/pki/ca-trust/source/anchors/crc-ca-bundle.crt
sudo update-ca-trustLinux (Debian/Ubuntu):
sudo cp crc-ca-bundle.crt /usr/local/share/ca-certificates/crc-ca-bundle.crt
sudo update-ca-certificatesmacOS:
sudo security add-trusted-cert -d -r trustRoot \
-k /Library/Keychains/System.keychain crc-ca-bundle.crtAfter installing the bundle, HTTPS connections to *.apps-crc.testing and *.acpgw.apps-crc.testing will work without TLS verification flags.
Resource starvation (pods in CrashLoopBackOff):
# Increase CRC memory (default 9216 MiB may not be enough)
crc stop
crc config set memory 14336
crc startImage pull errors (ImagePullBackOff):
Images must be pushed to the CRC internal registry. Use make crc-reload-images instead of just building locally.
SCC (Security Context Constraint) errors:
OpenShift's restricted SCC blocks containers that run as a fixed UID. Use Red Hat base images (e.g., registry.redhat.io/rhel10/postgresql-16:10.1) that support arbitrary UIDs.
Pods not starting:
kubectl get pods -n ambient-code
kubectl describe pod <pod-name> -n ambient-code
kubectl logs <pod-name> -n ambient-codeImage issues:
# Check if images are loaded
docker exec -it ambient-code-control-plane crictl images | grep ambientService not accessible:
# Check services
kubectl get services -n ambient-code
# Check ingress
kubectl get ingress -n ambient-code
# Test directly
kubectl port-forward -n ambient-code svc/ambient-ui-service 3000:3000Networking issues:
# Check ingress controller
kubectl get pods -n ingress-nginx
# Restart port forwarding
make kind-down
make kind-upIf you're stuck or have questions:
-
Check existing documentation:
- CLAUDE.md - Comprehensive development standards
- README.md - Project overview and quick start
- BOOKMARKS.md - Developer bookmarks and reference index
- docs/internal/ - Architecture, design, and developer docs
-
Search existing issues:
- Check if your issue has already been reported
- Look for solutions in closed issues
-
Create a new issue:
- Provide clear description and reproduction steps
- Include relevant logs and error messages
- Tag with appropriate labels
By contributing to Agent Control Plane, you agree that your contributions will be licensed under the same license as the project (MIT License).