All infrastructure and application state MUST be declared in Git.
No manual kubectl apply or helm install outside of bootstrap.
- Git is the single source of truth for all Kubernetes resources
- All changes MUST flow through Git commits, never ad-hoc CLI commands
- ArgoCD reconciles desired state from Git to the OrbStack cluster
- Configuration drift triggers automatic detection and self-heal
- Every manifest, Helm values file, and Kustomize overlay MUST be version-controlled in this repository
- Bootstrap scripts (initial ArgoCD install) are the only exception to the "no manual apply" rule and MUST be idempotent
Rationale: Git history provides full audit trail, rollback capability, and reproducibility for the entire local platform.
AI agent manages all Kubernetes manifests — users never write YAML manually.
- Agent generates all Kubernetes resources (Deployments, Services, Ingress, ConfigMaps, Secrets references, etc.)
- Agent selects appropriate deployment strategy (Helm vs Kustomize vs raw manifests) based on the decision flow below
- Agent discovers Helm charts from artifact registries before generating custom YAML
- Agent creates ArgoCD Application definitions automatically
- User describes intent in natural language; agent translates to infrastructure
- All generated manifests stored in Git for GitOps reconciliation
Decision Flow for Deployments:
- Check if a Helm chart exists (ArtifactHub, Bitnami, official repos)
- If Helm exists → ArgoCD Application + Helm chart + values overlay
- If no Helm → ArgoCD Application + Kustomize with base manifests
- Custom apps → Kustomize with environment overlays
Every infrastructure change MUST pass validation gates before being applied to the cluster.
kubectl difforkubectl apply --dry-run=clientfor all manifestshelm template+kubeconformfor Helm-based deploymentskustomize build+kubeconformfor Kustomize-based deployments- ArgoCD sync preview (diff) before manual sync approval
- Shell scripts MUST use
shellcheckbefore commit - No direct applies without reviewing the diff output
Rationale: Catching errors before they reach the cluster prevents downtime and reduces debugging time in local development.
Namespace-based isolation MUST be enforced for all projects running on the local OrbStack cluster.
- Each project gets its own namespace:
<project-name>(e.g.,myapp,backend-api,ml-pipeline) - Kubernetes NetworkPolicies: default deny-all ingress, explicit allows per project
- ResourceQuotas enforced per namespace to prevent resource starvation
- LimitRanges set default CPU/memory requests and limits
- Cross-project communication MUST be explicitly documented and allowed via NetworkPolicy
- Shared infrastructure components (ingress, monitoring) run in dedicated system namespaces
Rationale: Even in local development, isolation prevents accidental interference between projects and enforces good habits that carry forward to production.
Mandatory validation MUST occur after each deployment phase.
- Cluster Bootstrap: OrbStack Kubernetes running, all system pods healthy, DNS resolution working
- GitOps Platform: ArgoCD accessible via port-forward or ingress, all ArgoCD components healthy
- Infrastructure Components: Ingress controller responding, cert-manager ready, monitoring stack collecting metrics
- Application Deployments: Pods running, health checks passing, services reachable, ingress routes functional
Validation failure MUST stop the deployment pipeline and require investigation before proceeding.
Metrics collection and visualization MUST be available for the local cluster and all deployed projects.
- Prometheus scrapes all namespaces and system components
- Grafana dashboards: cluster overview + per-project resource usage
- Alert rules for critical conditions (node pressure, pod crash loops, PVC near full)
- Container logs accessible via
kubectl logsand optionally Loki - ArgoCD sync status visible in ArgoCD UI dashboard
- Resource usage monitoring to prevent local machine overload
Rationale: Observability in local development catches issues early and builds familiarity with monitoring tools used in production.
Security best practices MUST be followed even in local development.
- Secrets MUST NOT be committed to Git (use Sealed Secrets or external-secrets-operator with local backend)
- Container images MUST specify exact tags (no
:latest) - Pods MUST NOT run as root unless explicitly justified
- NetworkPolicies MUST be applied to all project namespaces
- RBAC: Use namespace-scoped roles, avoid cluster-admin for workloads
- TLS for ingress endpoints via cert-manager (self-signed for local)
Rationale: Enforcing security in local dev prevents bad habits and ensures manifests are production-ready from the start.
The entire local infrastructure MUST be reproducible from a clean macOS ARM machine with OrbStack installed.
- All cluster state derivable from this Git repository
- Bootstrap script MUST be idempotent (safe to run multiple times)
- Helm chart versions pinned explicitly (no floating versions)
- Container image tags pinned (no
:latest) - OrbStack Kubernetes version documented and tracked
- README documents all prerequisites and setup steps
- Cluster teardown and rebuild MUST complete in under 15 minutes
Rationale: Any team member MUST be able to clone this repo, run the bootstrap, and have a fully functional local platform.
Runtime: OrbStack (macOS ARM native, Apple Silicon optimized) Kubernetes Version: 1.31.x (OrbStack managed) Architecture: Single-node cluster (local development) CNI: Flannel (OrbStack default — does NOT enforce NetworkPolicies) DNS: CoreDNS (OrbStack managed) Storage: OrbStack local PV provisioner (hostpath) Container Runtime: containerd (OrbStack managed) CLI Tools Required:
kubectl1.31.xhelm3.16.xkustomize5.5.x (or kubectl built-in)kubeconformfor manifest validationshellcheckfor script validation
OrbStack-Specific Notes:
- Kubernetes enabled via
orbCLI or OrbStack preferences - Cluster accessible via standard kubeconfig (
~/.kube/config) - OrbStack provides automatic DNS for
*.k8s.orb.localdomains - Resource limits configurable in OrbStack settings
- Recommend allocating 4+ CPU cores and 8+ GiB RAM to OrbStack
Tool: ArgoCD 3.1.x
Installation: Helm chart from https://argoproj.github.io/argo-helm
Namespace: argocd
Access: Port-forward (kubectl port-forward svc/argocd-server -n argocd 8080:443) or Ingress via argocd.k8s.orb.local
Repository: This Git repository (local or remote)
Sync Policy:
- Local development: Auto-sync enabled with self-heal
- Prune: Enabled (removes resources deleted from Git)
- Self-heal: Enabled (reverts manual changes) Projects: One ArgoCD AppProject per project/tenant namespace App-of-Apps: Root Application manages all child Applications RBAC: Admin access for local development (single user)
Helm Chart Discovery:
- Primary sources: ArtifactHub, Bitnami, official vendor repositories
- Agent MUST check for existing Helm charts before generating custom manifests
- Prefer community-maintained charts with active maintenance and regular releases
- Pin chart versions explicitly (no
latestor floating versions) - Store Helm values overrides in
helm-values/<component>/values.yaml
ArgoCD Application Patterns:
Helm-based Application:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: <component-name>
namespace: argocd
spec:
project: infrastructure
source:
repoURL: <helm-repo-url>
targetRevision: <chart-version>
chart: <chart-name>
helm:
valueFiles:
- values.yaml
destination:
server: https://kubernetes.default.svc
namespace: <target-namespace>
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=trueKustomize-based Application:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: <app-name>
namespace: argocd
spec:
project: <project-name>
source:
repoURL: <git-repo-url>
targetRevision: HEAD
path: kubernetes/apps/<app-name>/overlays/local
destination:
server: https://kubernetes.default.svc
namespace: <target-namespace>
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=trueKustomize Structure:
kubernetes/apps/<app-name>/
├── base/
│ ├── kustomization.yaml
│ ├── deployment.yaml
│ ├── service.yaml
│ └── ingress.yaml
└── overlays/
└── local/
├── kustomization.yaml
└── patches/
└── replicas.yaml
Starter Infrastructure Components (Agent provisions automatically):
| Component | Helm Chart | Repository | Purpose |
|---|---|---|---|
| nginx-ingress | ingress-nginx | https://kubernetes.github.io/ingress-nginx | Ingress controller |
| cert-manager | cert-manager | https://charts.jetstack.io | TLS certificates (self-signed) |
| external-secrets | external-secrets | https://charts.external-secrets.io | Secret management |
| prometheus-stack | kube-prometheus-stack | https://prometheus-community.github.io/helm-charts | Monitoring & alerting |
| argocd | argo-cd | https://argoproj.github.io/argo-helm | GitOps controller |
| sealed-secrets | sealed-secrets | https://bitnami-labs.github.io/sealed-secrets | Git-safe secrets |
Tool: Helm 3.16.x Chart Sources:
- ArtifactHub (primary discovery)
- Official vendor Helm repositories
- Bitnami (curated community charts) Conventions:
- All Helm releases managed via ArgoCD (not
helm installCLI) - Values files stored in Git:
helm-values/<component>/values.yaml - Chart versions pinned in ArgoCD Application specs
- Use
helm template+kubeconformfor pre-commit validation - Helm secrets via Sealed Secrets or external-secrets-operator
Metrics: Prometheus (via kube-prometheus-stack Helm chart) Visualization: Grafana (bundled with kube-prometheus-stack) Logging: kubectl logs + optional Loki stack Alerting: AlertManager with local notification (webhook/stdout) Dashboards:
- Cluster overview (node resources, pod status)
- Per-namespace resource consumption
- ArgoCD sync status
- Ingress request rates and latency
Retention: Metrics 7d (local development, storage-conscious)
Access: Grafana via port-forward or ingress at
grafana.k8s.orb.local
Namespace Naming: <project-name> (e.g., myapp, api-service)
System Namespaces (managed by platform):
argocd— GitOps controlleringress-nginx— Ingress controllercert-manager— Certificate managementmonitoring— Prometheus, Grafana, AlertManagersealed-secrets— Secret encryption controllerexternal-secrets— External secrets operator Naming Convention: Lowercase alphanumeric + hyphens only, max 63 chars Metadata Labels (applied to all resources):app.kubernetes.io/managed-by: argocdproject: <project-name>environment: local
Default Quotas per Project Namespace:
- CPU requests: 2 cores
- CPU limits: 4 cores
- Memory requests: 2 GiB
- Memory limits: 4 GiB
- Pods: 20 maximum
- Persistent volume claims: 5 maximum, 10 GiB total
- Services: 10 maximum
- ConfigMaps: 20 maximum
- Secrets: 20 maximum Quota Adjustment: Modify in Git, ArgoCD auto-syncs Enforcement: Hard limits to protect local machine resources LimitRange Defaults:
- Default CPU request: 100m, limit: 500m
- Default memory request: 128Mi, limit: 512Mi
Default Policy: Deny-all ingress (applied per project namespace) Allowed Traffic:
- DNS: Allow egress to
kube-system(CoreDNS) on port 53 - Ingress: Allow from
ingress-nginxnamespace - Monitoring: Allow from
monitoringnamespace (Prometheus scrape) - Egress: Allow all egress by default (local development convenience) Cross-Project: Prohibited unless explicitly allowed via NetworkPolicy in both source and destination namespaces Implementation: Kubernetes NetworkPolicy (defined for portability; Flannel on OrbStack does NOT enforce — policies will take effect on production clusters with Calico/Cilium CNI)
Local Development Model: Single-user with full cluster access
kubectl Context: OrbStack default context (orbstack)
ArgoCD Access: Admin role (local development, single user)
Service Accounts: Per-application, namespace-scoped
Best Practice: Even locally, avoid default service account
for workloads — create dedicated service accounts
Future Extension: When moving to shared clusters, implement
proper RBAC with RoleBindings per namespace
Scope: Best-practice security for local development No Formal Compliance: SOC2/HIPAA/PCI-DSS not required for local Audit Logging: Kubernetes audit logs via OrbStack (if enabled) Image Policy:
- Prefer official images from Docker Hub, gcr.io, quay.io
- Pin image tags to specific versions (no
:latest) - Scan images with Trivy before deployment (recommended)
Pod Security Standards: Enforce
restrictedprofile where possible, fallback tobaselinewith justification
Primary Tool: Sealed Secrets (kubeseal) for Git-safe secrets Alternative: external-secrets-operator with local file backend Workflow:
- Create secret with
kubectl create secret(temporary) - Seal with
kubeseal→ SealedSecret YAML - Commit SealedSecret to Git
- ArgoCD syncs SealedSecret → controller decrypts in-cluster
Never in Git: Plain-text secrets, credentials, API keys, certificates
Local Development Convenience:
.envfiles in.gitignorefor quick iteration, but production-path MUST use Sealed Secrets
Registry: Docker Hub, ghcr.io, gcr.io, quay.io (public registries)
Private Registry: Optional — OrbStack supports local registry
Tag Policy: Always use specific version tags, never :latest
Scanning: Trivy CLI scan recommended before deployment
Base Images: Prefer distroless or Alpine-based images
Image Pull Policy: IfNotPresent for local development (reduces
network traffic and speeds up restarts)
Phases (sequential execution):
- Prerequisites: OrbStack installed, Kubernetes enabled, CLI tools
- Bootstrap: ArgoCD installed via Helm (idempotent script)
- Infrastructure: Starter components deployed via ArgoCD
- Applications: Project workloads deployed via ArgoCD
- Validation: All health checks pass, services reachable
Bootstrap Script (scripts/bootstrap.sh):
- Verify OrbStack and Kubernetes are running
- Install ArgoCD via Helm
- Wait for ArgoCD to be ready
- Apply root App-of-Apps Application
- Output access information (URLs, credentials)
All Subsequent Changes: Via Git commit → ArgoCD auto-sync
Application Rollback:
- ArgoCD UI: Click "History" → select previous revision → "Rollback"
- Git:
git revert <commit>→ push → ArgoCD auto-syncs Infrastructure Component Rollback: - Revert Helm values in Git → ArgoCD re-syncs with previous values
- Pin to previous chart version in ArgoCD Application spec Full Cluster Reset:
orb delete k8s && orb start k8s— recreate OrbStack cluster- Re-run bootstrap script (idempotent)
- ArgoCD reconciles all state from Git RTO Target: 15 minutes for full cluster rebuild from scratch Decision Authority: Developer (single-user local environment)
Critical Conditions (check manually or via Grafana):
- Node NotReady status
- Pod CrashLoopBackOff in any namespace
- PersistentVolumeClaim pending (storage issue)
- ArgoCD sync failed or degraded Warning Conditions:
- CPU/memory usage > 80% on OrbStack node
- PersistentVolume usage > 85%
- Certificate expiring < 7 days
Alert Routing: Grafana alerts to local webhook or stdout
(no PagerDuty/Slack for local development)
Dashboard Access:
grafana.k8s.orb.localor port-forward 3000
Backup Scope:
- Git repository (contains all desired state — primary backup)
- Sealed Secrets encryption key (MUST be backed up separately)
- Persistent volume data (application-specific, optional)
Git as Backup: All Kubernetes manifests, Helm values, Kustomize
overlays, and ArgoCD Applications are in Git — the cluster is
fully reconstructible from the repository
Sealed Secrets Key: Export and store securely:
kubectl get secret -n sealed-secrets -l sealedsecrets.bitnami.com/sealed-secrets-key -o yaml > sealed-secrets-key-backup.yamlRecovery: Clone repo → bootstrap script → ArgoCD reconciles RTO: 15 minutes (cluster rebuild + ArgoCD sync) RPO: Last Git commit (zero data loss for infrastructure state)
Local Development Model: Self-review (single developer) Recommended Practice (even for solo work):
- Use feature branches for significant changes
- Review diff before merge (
git diff main..feature-branch) - Run validation before commit (dry-run, kubeconform) Review Checklist (self-check):
- Manifests pass
kubeconformvalidation - Helm values render correctly (
helm template) - No plain-text secrets in committed files
- Documentation updated if architecture changes
- Constitution compliance verified Merge Strategy: Squash merge to main for clean history
Pre-Commit:
kustomize buildsucceeds for all overlayshelm templaterenders without errorskubeconformvalidates all generated manifestsshellcheckpasses for all shell scripts Post-Merge:- ArgoCD detects change and syncs automatically
- All Application sync status transitions to "Healthy"
- Pod readiness checks pass
- Ingress endpoints respond (HTTP 200)
Validation Script:
scripts/validate.shruns all pre-commit checks
Mandatory Documentation:
README.md: Prerequisites, quickstart, architecture overviewdocs/architecture.md: Component diagram, network topologydocs/runbook.md: Common operations, troubleshooting- Inline comments in Kustomize overlays and Helm values Update Trigger: Any new component, namespace, or architecture change Format: Markdown, diagrams in Mermaid or ASCII art Location: Co-located with infrastructure code in this repository
Provisioning Time:
- OrbStack Kubernetes start: < 30 seconds
- ArgoCD bootstrap: < 3 minutes
- Full infrastructure sync: < 10 minutes
- Single application deployment: < 2 minutes Resource Budget (recommended OrbStack allocation):
- CPU: 4-8 cores for OrbStack
- Memory: 8-16 GiB for OrbStack
- Disk: 20+ GiB available for container images and PVs Scalability (local limits):
- Maximum pods: ~100 (depending on machine resources)
- Maximum namespaces: ~20 project namespaces
- Maximum PVCs: Limited by disk space
Availability: Best-effort (local development, not 24/7) Pod Startup Time: < 30 seconds for standard workloads Ingress Response: < 100ms p95 latency for local services ArgoCD Sync Latency: < 3 minutes from Git push to cluster state Cluster Rebuild Time: < 15 minutes from scratch RTO: 15 minutes (full cluster rebuild) RPO: Last Git commit (infrastructure as code)
Infrastructure Cost: $0/month (runs on local macOS machine) OrbStack License: Free for personal use, $8/month for commercial Resource Optimization:
- Stop OrbStack when not in use (
orb stop) - Use resource quotas to prevent runaway containers
- Set appropriate CPU/memory limits on workloads
- Prune unused images periodically:
docker image prune - Monitor disk usage for PersistentVolumes Power & Battery: OrbStack is optimized for Apple Silicon — minimal battery impact compared to Docker Desktop or minikube
Precedence: This constitution supersedes all ad-hoc decisions about local infrastructure setup and deployment patterns Enforcement: All infrastructure changes MUST follow the principles defined here — validated via pre-commit checks and ArgoCD Non-Compliance: Changes that violate this constitution MUST be corrected before merge to main branch Exceptions: Any deviation MUST be documented as a comment in the relevant manifest with rationale and expected resolution date
Proposal: Open a Git issue or create a branch with proposed changes to this constitution file Review: Self-review the impact on existing infrastructure Versioning:
- MAJOR: Backward-incompatible changes (e.g., replacing ArgoCD with Flux, switching from OrbStack to minikube)
- MINOR: New principle or section added, material guidance expansion
- PATCH: Clarifications, typo fixes, version bumps Implementation: Migration plan required for MAJOR changes Notification: Update README.md with change summary
Automated Checks:
- Pre-commit hooks run validation (kubeconform, shellcheck)
- ArgoCD enforces desired state (self-heal ON)
- ResourceQuotas prevent resource abuse
- NetworkPolicies enforce namespace isolation Manual Checks:
- Periodic review of ArgoCD Application health
- Review resource usage in Grafana dashboards
- Verify Sealed Secrets key is backed up Audit Trail: Git history provides complete change audit trail
┌─────────────────────────────────────────────────┐
│ OrbStack (macOS ARM) │
│ ┌───────────────────────────────────────────┐ │
│ │ Kubernetes Cluster │ │
│ │ │ │
│ │ ┌─────────┐ ┌────────────────────┐ │ │
│ │ │ ArgoCD │───→│ Infrastructure │ │ │
│ │ │ (GitOps)│ │ ├─ ingress-nginx │ │ │
│ │ └────┬────┘ │ ├─ cert-manager │ │ │
│ │ │ │ ├─ sealed-secrets │ │ │
│ │ │ │ ├─ external-secrets│ │ │
│ │ │ │ └─ prometheus-stack│ │ │
│ │ │ └────────────────────┘ │ │
│ │ │ │ │
│ │ │ ┌────────────────────┐ │ │
│ │ └────────→│ Your Applications │ │ │
│ │ │ ├─ myapp │ │ │
│ │ │ ├─ api-service │ │ │
│ │ │ └─ ... │ │ │
│ │ └────────────────────┘ │ │
│ └───────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
▲
│ Git Sync
│
┌────┴────┐
│ This │
│ Git Repo│
└─────────┘
- macOS on Apple Silicon (M1/M2/M3/M4)
- OrbStack installed (
brew install orbstack) - Kubernetes enabled in OrbStack
- CLI tools:
kubectl,helm,kustomize,kubeseal
/specops.specify— Create infrastructure specification/specops.clarify— Clarify requirements (optional)/specops.plan— Create implementation plan/specops.tasks— Generate tasks/specops.implement— Deploy infrastructure/specops.deploy— Deploy your application
# 1. Verify OrbStack Kubernetes is running
kubectl get nodes
# 2. Run bootstrap script
./scripts/bootstrap.sh
# 3. Access ArgoCD UI
kubectl port-forward svc/argocd-server -n argocd 8080:443
# 4. Get ArgoCD admin password
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -dUsers never write: Deployment YAML, Service YAML, Ingress YAML, NetworkPolicy YAML, ArgoCD Application YAML, Helm values from scratch
Users only describe: "Deploy my API with 3 replicas", "Add monitoring to my app", "Expose my service on myapp.k8s.orb.local"
Agent handles: Helm chart discovery, manifest generation, ArgoCD Application setup, Kustomize overlay creation, Git commits
Version: 1.2.0 | Ratified: 2026-02-10 | Last Amended: 2026-02-10
Project: Local Test Infrastructure Maintainer: Platform Team Contact: Repository Issues