feat(swarm): add swarm self-improvement loop infrastructure

Adds complete k8s manifests, ArgoCD app, and Terraform namespace
resources for the Neuron swarm self-improvement loop system.

Each variant (alpha, beta, gamma) gets its own isolated namespace,
PVC, MCP/REST deployments, ExternalSecrets from Vault, RBAC for CI,
and a SQLite clone Job template for session startup.
This commit is contained in:
Will Anderson
2026-04-26 00:58:43 -05:00
parent 89a0209637
commit 74dd054a36
22 changed files with 1420 additions and 0 deletions
+52
View File
@@ -0,0 +1,52 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: neuron-swarm
namespace: argocd
spec:
project: default
source:
repoURL: http://10.43.1.53:3000/will/infrastructure.git
targetRevision: main
path: servers/legion/k8s/neuron-technologies/swarm
destination:
server: https://kubernetes.default.svc
# No single namespace — resources span swarm-alpha/beta/gamma.
# Each resource declares its own namespace.
namespace: swarm-alpha
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
# Don't track Jobs created dynamically by swarm.sh
ignoreDifferences:
- group: batch
kind: Job
namespace: swarm-alpha
jsonPointers: [""]
- group: batch
kind: Job
namespace: swarm-beta
jsonPointers: [""]
- group: batch
kind: Job
namespace: swarm-gamma
jsonPointers: [""]
# Session ConfigMaps are created/deleted by swarm.sh — ignore drift
- group: ""
kind: ConfigMap
name: swarm-alpha-session
namespace: swarm-alpha
jsonPointers: [""]
- group: ""
kind: ConfigMap
name: swarm-beta-session
namespace: swarm-beta
jsonPointers: [""]
- group: ""
kind: ConfigMap
name: swarm-gamma-session
namespace: swarm-gamma
jsonPointers: [""]
@@ -0,0 +1,48 @@
# Swarm variant ConfigMaps — base config per variant
# The swarm-{variant}-session ConfigMap is created dynamically by swarm.sh
# at session start and deleted at session end.
---
apiVersion: v1
kind: ConfigMap
metadata:
name: swarm-alpha-config
namespace: swarm-alpha
data:
SPRING_PROFILES_ACTIVE: "swarm"
NEURON_DATA_DIR: "/data"
NEURON_DB_PATH: "/data/neuron.db"
NEURON_STORAGE_PATH: "/data"
SERVER_TOMCAT_ACCESSLOG_ENABLED: "true"
MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: "health,info,metrics"
MANAGEMENT_ENDPOINT_HEALTH_SHOW_DETAILS: "always"
MANAGEMENT_OTLP_METRICS_EXPORT_ENABLED: "false"
---
apiVersion: v1
kind: ConfigMap
metadata:
name: swarm-beta-config
namespace: swarm-beta
data:
SPRING_PROFILES_ACTIVE: "swarm"
NEURON_DATA_DIR: "/data"
NEURON_DB_PATH: "/data/neuron.db"
NEURON_STORAGE_PATH: "/data"
SERVER_TOMCAT_ACCESSLOG_ENABLED: "true"
MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: "health,info,metrics"
MANAGEMENT_ENDPOINT_HEALTH_SHOW_DETAILS: "always"
MANAGEMENT_OTLP_METRICS_EXPORT_ENABLED: "false"
---
apiVersion: v1
kind: ConfigMap
metadata:
name: swarm-gamma-config
namespace: swarm-gamma
data:
SPRING_PROFILES_ACTIVE: "swarm"
NEURON_DATA_DIR: "/data"
NEURON_DB_PATH: "/data/neuron.db"
NEURON_STORAGE_PATH: "/data"
SERVER_TOMCAT_ACCESSLOG_ENABLED: "true"
MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: "health,info,metrics"
MANAGEMENT_ENDPOINT_HEALTH_SHOW_DETAILS: "always"
MANAGEMENT_OTLP_METRICS_EXPORT_ENABLED: "false"
@@ -0,0 +1,155 @@
# Swarm variants share the same secrets as prod.
# Each variant gets its own ExternalSecret object pointing at the same Vault paths.
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: swarm-alpha-secrets
namespace: swarm-alpha
spec:
refreshInterval: 1h
secretStoreRef:
name: vault
kind: ClusterSecretStore
target:
name: swarm-alpha-secrets
creationPolicy: Owner
data:
- secretKey: NEURON_API_KEY
remoteRef:
key: secret/data/neuron-technologies/prod
property: api_key
- secretKey: NEURON_WEBHOOK_SECRET
remoteRef:
key: secret/data/neuron-technologies/prod
property: gitea_webhook_secret
- secretKey: NEURON_LICENSE_ADMIN_TOKEN
remoteRef:
key: secret/data/neuron-technologies/license
property: admin_token
- secretKey: UNKEY_ROOT_KEY
remoteRef:
key: secret/data/neuron-technologies/unkey
property: root_key
- secretKey: UNKEY_API_ID
remoteRef:
key: secret/data/neuron-technologies/unkey
property: api_id
- secretKey: NEURON_R2_ENDPOINT
remoteRef:
key: secret/data/r2
property: endpoint
- secretKey: NEURON_R2_ACCESS_KEY
remoteRef:
key: secret/data/r2
property: access_key_id
- secretKey: NEURON_R2_SECRET_KEY
remoteRef:
key: secret/data/r2
property: secret_access_key
- secretKey: NEURON_R2_BUCKET
remoteRef:
key: secret/data/r2
property: neuron_bucket
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: swarm-beta-secrets
namespace: swarm-beta
spec:
refreshInterval: 1h
secretStoreRef:
name: vault
kind: ClusterSecretStore
target:
name: swarm-beta-secrets
creationPolicy: Owner
data:
- secretKey: NEURON_API_KEY
remoteRef:
key: secret/data/neuron-technologies/prod
property: api_key
- secretKey: NEURON_WEBHOOK_SECRET
remoteRef:
key: secret/data/neuron-technologies/prod
property: gitea_webhook_secret
- secretKey: NEURON_LICENSE_ADMIN_TOKEN
remoteRef:
key: secret/data/neuron-technologies/license
property: admin_token
- secretKey: UNKEY_ROOT_KEY
remoteRef:
key: secret/data/neuron-technologies/unkey
property: root_key
- secretKey: UNKEY_API_ID
remoteRef:
key: secret/data/neuron-technologies/unkey
property: api_id
- secretKey: NEURON_R2_ENDPOINT
remoteRef:
key: secret/data/r2
property: endpoint
- secretKey: NEURON_R2_ACCESS_KEY
remoteRef:
key: secret/data/r2
property: access_key_id
- secretKey: NEURON_R2_SECRET_KEY
remoteRef:
key: secret/data/r2
property: secret_access_key
- secretKey: NEURON_R2_BUCKET
remoteRef:
key: secret/data/r2
property: neuron_bucket
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: swarm-gamma-secrets
namespace: swarm-gamma
spec:
refreshInterval: 1h
secretStoreRef:
name: vault
kind: ClusterSecretStore
target:
name: swarm-gamma-secrets
creationPolicy: Owner
data:
- secretKey: NEURON_API_KEY
remoteRef:
key: secret/data/neuron-technologies/prod
property: api_key
- secretKey: NEURON_WEBHOOK_SECRET
remoteRef:
key: secret/data/neuron-technologies/prod
property: gitea_webhook_secret
- secretKey: NEURON_LICENSE_ADMIN_TOKEN
remoteRef:
key: secret/data/neuron-technologies/license
property: admin_token
- secretKey: UNKEY_ROOT_KEY
remoteRef:
key: secret/data/neuron-technologies/unkey
property: root_key
- secretKey: UNKEY_API_ID
remoteRef:
key: secret/data/neuron-technologies/unkey
property: api_id
- secretKey: NEURON_R2_ENDPOINT
remoteRef:
key: secret/data/r2
property: endpoint
- secretKey: NEURON_R2_ACCESS_KEY
remoteRef:
key: secret/data/r2
property: access_key_id
- secretKey: NEURON_R2_SECRET_KEY
remoteRef:
key: secret/data/r2
property: secret_access_key
- secretKey: NEURON_R2_BUCKET
remoteRef:
key: secret/data/r2
property: neuron_bucket
@@ -0,0 +1,30 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
# Namespaces
- namespace-alpha.yaml
- namespace-beta.yaml
- namespace-gamma.yaml
# Persistent volumes
- pvc-alpha.yaml
- pvc-beta.yaml
- pvc-gamma.yaml
# Base config
- configmaps.yaml
# Shared secrets from Vault
- externalsecrets.yaml
# MCP deployments
- mcp-deployment-alpha.yaml
- mcp-deployment-beta.yaml
- mcp-deployment-gamma.yaml
# REST deployments
- rest-deployment-alpha.yaml
- rest-deployment-beta.yaml
- rest-deployment-gamma.yaml
# Services
- services.yaml
# RBAC for CI runner
- rbac.yaml
# SQLite clone Jobs (applied by swarm.sh at session start, not auto-synced by ArgoCD)
# These are listed here for reference but excluded from ArgoCD automated sync
# via the ignoreDifferences config in the ArgoCD app.
@@ -0,0 +1,121 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: neuron-mcp
namespace: swarm-alpha
labels:
app: neuron-mcp
env: swarm
variant: alpha
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: neuron-mcp
template:
metadata:
labels:
app: neuron-mcp
env: swarm
variant: alpha
spec:
terminationGracePeriodSeconds: 30
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
initContainers:
- name: wait-for-sqlite-clone
image: busybox:1.36
command: ["sh", "-c", "until [ -f /data/neuron.db ]; do echo 'waiting for SQLite clone...'; sleep 2; done; echo 'SQLite ready'"]
volumeMounts:
- name: data
mountPath: /data
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
containers:
- name: neuron-mcp
# Image is updated by swarm CI on each loop iteration
image: registry.neuralplatform.ai/neuron-technologies/neuron-mcp:v0.15.3
imagePullPolicy: Always
ports:
- name: http
containerPort: 8080
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: false
runAsNonRoot: true
capabilities:
drop: ["ALL"]
env:
- name: NEURON_SWARM_VARIANT
value: "alpha"
- name: NEURON_SWARM_SESSION
valueFrom:
configMapKeyRef:
name: swarm-alpha-session
key: session_id
optional: true
- name: NEURON_SWARM_GOAL
valueFrom:
configMapKeyRef:
name: swarm-alpha-session
key: goal
optional: true
- name: NEURON_SWARM_LOOP_MAX
valueFrom:
configMapKeyRef:
name: swarm-alpha-session
key: loop_max
optional: true
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://alloy-otlp.monitoring.svc.cluster.local:4318"
- name: JAVA_TOOL_OPTIONS
value: "-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -XX:+ExitOnOutOfMemoryError"
envFrom:
- configMapRef:
name: swarm-alpha-config
- secretRef:
name: swarm-alpha-secrets
volumeMounts:
- name: data
mountPath: /data
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 1500m
memory: 1536Mi
lifecycle:
preStop:
exec:
command: ["sh", "-c", "sleep 5"]
startupProbe:
httpGet:
path: /actuator/health/liveness
port: http
failureThreshold: 30
periodSeconds: 5
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: http
periodSeconds: 30
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: http
initialDelaySeconds: 5
periodSeconds: 10
failureThreshold: 3
volumes:
- name: data
persistentVolumeClaim:
claimName: swarm-alpha-data
@@ -0,0 +1,120 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: neuron-mcp
namespace: swarm-beta
labels:
app: neuron-mcp
env: swarm
variant: beta
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: neuron-mcp
template:
metadata:
labels:
app: neuron-mcp
env: swarm
variant: beta
spec:
terminationGracePeriodSeconds: 30
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
initContainers:
- name: wait-for-sqlite-clone
image: busybox:1.36
command: ["sh", "-c", "until [ -f /data/neuron.db ]; do echo 'waiting for SQLite clone...'; sleep 2; done; echo 'SQLite ready'"]
volumeMounts:
- name: data
mountPath: /data
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
containers:
- name: neuron-mcp
image: registry.neuralplatform.ai/neuron-technologies/neuron-mcp:v0.15.3
imagePullPolicy: Always
ports:
- name: http
containerPort: 8080
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: false
runAsNonRoot: true
capabilities:
drop: ["ALL"]
env:
- name: NEURON_SWARM_VARIANT
value: "beta"
- name: NEURON_SWARM_SESSION
valueFrom:
configMapKeyRef:
name: swarm-beta-session
key: session_id
optional: true
- name: NEURON_SWARM_GOAL
valueFrom:
configMapKeyRef:
name: swarm-beta-session
key: goal
optional: true
- name: NEURON_SWARM_LOOP_MAX
valueFrom:
configMapKeyRef:
name: swarm-beta-session
key: loop_max
optional: true
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://alloy-otlp.monitoring.svc.cluster.local:4318"
- name: JAVA_TOOL_OPTIONS
value: "-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -XX:+ExitOnOutOfMemoryError"
envFrom:
- configMapRef:
name: swarm-beta-config
- secretRef:
name: swarm-beta-secrets
volumeMounts:
- name: data
mountPath: /data
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 1500m
memory: 1536Mi
lifecycle:
preStop:
exec:
command: ["sh", "-c", "sleep 5"]
startupProbe:
httpGet:
path: /actuator/health/liveness
port: http
failureThreshold: 30
periodSeconds: 5
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: http
periodSeconds: 30
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: http
initialDelaySeconds: 5
periodSeconds: 10
failureThreshold: 3
volumes:
- name: data
persistentVolumeClaim:
claimName: swarm-beta-data
@@ -0,0 +1,120 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: neuron-mcp
namespace: swarm-gamma
labels:
app: neuron-mcp
env: swarm
variant: gamma
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: neuron-mcp
template:
metadata:
labels:
app: neuron-mcp
env: swarm
variant: gamma
spec:
terminationGracePeriodSeconds: 30
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
initContainers:
- name: wait-for-sqlite-clone
image: busybox:1.36
command: ["sh", "-c", "until [ -f /data/neuron.db ]; do echo 'waiting for SQLite clone...'; sleep 2; done; echo 'SQLite ready'"]
volumeMounts:
- name: data
mountPath: /data
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
containers:
- name: neuron-mcp
image: registry.neuralplatform.ai/neuron-technologies/neuron-mcp:v0.15.3
imagePullPolicy: Always
ports:
- name: http
containerPort: 8080
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: false
runAsNonRoot: true
capabilities:
drop: ["ALL"]
env:
- name: NEURON_SWARM_VARIANT
value: "gamma"
- name: NEURON_SWARM_SESSION
valueFrom:
configMapKeyRef:
name: swarm-gamma-session
key: session_id
optional: true
- name: NEURON_SWARM_GOAL
valueFrom:
configMapKeyRef:
name: swarm-gamma-session
key: goal
optional: true
- name: NEURON_SWARM_LOOP_MAX
valueFrom:
configMapKeyRef:
name: swarm-gamma-session
key: loop_max
optional: true
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://alloy-otlp.monitoring.svc.cluster.local:4318"
- name: JAVA_TOOL_OPTIONS
value: "-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -XX:+ExitOnOutOfMemoryError"
envFrom:
- configMapRef:
name: swarm-gamma-config
- secretRef:
name: swarm-gamma-secrets
volumeMounts:
- name: data
mountPath: /data
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 1500m
memory: 1536Mi
lifecycle:
preStop:
exec:
command: ["sh", "-c", "sleep 5"]
startupProbe:
httpGet:
path: /actuator/health/liveness
port: http
failureThreshold: 30
periodSeconds: 5
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: http
periodSeconds: 30
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: http
initialDelaySeconds: 5
periodSeconds: 10
failureThreshold: 3
volumes:
- name: data
persistentVolumeClaim:
claimName: swarm-gamma-data
@@ -0,0 +1,9 @@
apiVersion: v1
kind: Namespace
metadata:
name: swarm-alpha
labels:
app: neuron-technologies
tier: swarm
variant: alpha
managed-by: argocd
@@ -0,0 +1,9 @@
apiVersion: v1
kind: Namespace
metadata:
name: swarm-beta
labels:
app: neuron-technologies
tier: swarm
variant: beta
managed-by: argocd
@@ -0,0 +1,9 @@
apiVersion: v1
kind: Namespace
metadata:
name: swarm-gamma
labels:
app: neuron-technologies
tier: swarm
variant: gamma
managed-by: argocd
@@ -0,0 +1,12 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: swarm-alpha-data
namespace: swarm-alpha
spec:
storageClassName: local-path
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
@@ -0,0 +1,12 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: swarm-beta-data
namespace: swarm-beta
spec:
storageClassName: local-path
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
@@ -0,0 +1,12 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: swarm-gamma-data
namespace: swarm-gamma
spec:
storageClassName: local-path
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
@@ -0,0 +1,97 @@
# RBAC for swarm variant namespaces
# Grants the CI runner ServiceAccount permission to deploy to swarm-* namespaces.
# Mirrors the pattern used for neuron-dev/stage deployments.
# The CI runner runs in the `ci` namespace as the `default` ServiceAccount.
---
# swarm-alpha
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: swarm-deployer
namespace: swarm-alpha
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["configmaps", "services", "pods", "pods/log"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["batch"]
resources: ["jobs"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: ci-runner-swarm-alpha
namespace: swarm-alpha
subjects:
- kind: ServiceAccount
name: default
namespace: ci
roleRef:
kind: Role
name: swarm-deployer
apiGroup: rbac.authorization.k8s.io
---
# swarm-beta
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: swarm-deployer
namespace: swarm-beta
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["configmaps", "services", "pods", "pods/log"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["batch"]
resources: ["jobs"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: ci-runner-swarm-beta
namespace: swarm-beta
subjects:
- kind: ServiceAccount
name: default
namespace: ci
roleRef:
kind: Role
name: swarm-deployer
apiGroup: rbac.authorization.k8s.io
---
# swarm-gamma
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: swarm-deployer
namespace: swarm-gamma
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["configmaps", "services", "pods", "pods/log"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["batch"]
resources: ["jobs"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: ci-runner-swarm-gamma
namespace: swarm-gamma
subjects:
- kind: ServiceAccount
name: default
namespace: ci
roleRef:
kind: Role
name: swarm-deployer
apiGroup: rbac.authorization.k8s.io
@@ -0,0 +1,99 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: neuron-rest
namespace: swarm-alpha
labels:
app: neuron-rest
env: swarm
variant: alpha
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: neuron-rest
template:
metadata:
labels:
app: neuron-rest
env: swarm
variant: alpha
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: neuron-rest
image: registry.neuralplatform.ai/neuron-technologies/neuron-rest:v0.15.3
imagePullPolicy: Always
ports:
- name: http
containerPort: 8081
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: false
runAsNonRoot: true
capabilities:
drop: ["ALL"]
env:
- name: NEURON_SWARM_VARIANT
value: "alpha"
- name: NEURON_SWARM_SESSION
valueFrom:
configMapKeyRef:
name: swarm-alpha-session
key: session_id
optional: true
- name: NEURON_SWARM_GOAL
valueFrom:
configMapKeyRef:
name: swarm-alpha-session
key: goal
optional: true
- name: NEURON_SWARM_LOOP_MAX
valueFrom:
configMapKeyRef:
name: swarm-alpha-session
key: loop_max
optional: true
envFrom:
- configMapRef:
name: swarm-alpha-config
- secretRef:
name: swarm-alpha-secrets
volumeMounts:
- name: data
mountPath: /data
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
startupProbe:
httpGet:
path: /actuator/health/liveness
port: http
failureThreshold: 30
periodSeconds: 5
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: http
periodSeconds: 30
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: http
initialDelaySeconds: 5
periodSeconds: 10
failureThreshold: 3
volumes:
- name: data
persistentVolumeClaim:
claimName: swarm-alpha-data
@@ -0,0 +1,99 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: neuron-rest
namespace: swarm-beta
labels:
app: neuron-rest
env: swarm
variant: beta
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: neuron-rest
template:
metadata:
labels:
app: neuron-rest
env: swarm
variant: beta
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: neuron-rest
image: registry.neuralplatform.ai/neuron-technologies/neuron-rest:v0.15.3
imagePullPolicy: Always
ports:
- name: http
containerPort: 8081
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: false
runAsNonRoot: true
capabilities:
drop: ["ALL"]
env:
- name: NEURON_SWARM_VARIANT
value: "beta"
- name: NEURON_SWARM_SESSION
valueFrom:
configMapKeyRef:
name: swarm-beta-session
key: session_id
optional: true
- name: NEURON_SWARM_GOAL
valueFrom:
configMapKeyRef:
name: swarm-beta-session
key: goal
optional: true
- name: NEURON_SWARM_LOOP_MAX
valueFrom:
configMapKeyRef:
name: swarm-beta-session
key: loop_max
optional: true
envFrom:
- configMapRef:
name: swarm-beta-config
- secretRef:
name: swarm-beta-secrets
volumeMounts:
- name: data
mountPath: /data
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
startupProbe:
httpGet:
path: /actuator/health/liveness
port: http
failureThreshold: 30
periodSeconds: 5
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: http
periodSeconds: 30
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: http
initialDelaySeconds: 5
periodSeconds: 10
failureThreshold: 3
volumes:
- name: data
persistentVolumeClaim:
claimName: swarm-beta-data
@@ -0,0 +1,99 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: neuron-rest
namespace: swarm-gamma
labels:
app: neuron-rest
env: swarm
variant: gamma
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: neuron-rest
template:
metadata:
labels:
app: neuron-rest
env: swarm
variant: gamma
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: neuron-rest
image: registry.neuralplatform.ai/neuron-technologies/neuron-rest:v0.15.3
imagePullPolicy: Always
ports:
- name: http
containerPort: 8081
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: false
runAsNonRoot: true
capabilities:
drop: ["ALL"]
env:
- name: NEURON_SWARM_VARIANT
value: "gamma"
- name: NEURON_SWARM_SESSION
valueFrom:
configMapKeyRef:
name: swarm-gamma-session
key: session_id
optional: true
- name: NEURON_SWARM_GOAL
valueFrom:
configMapKeyRef:
name: swarm-gamma-session
key: goal
optional: true
- name: NEURON_SWARM_LOOP_MAX
valueFrom:
configMapKeyRef:
name: swarm-gamma-session
key: loop_max
optional: true
envFrom:
- configMapRef:
name: swarm-gamma-config
- secretRef:
name: swarm-gamma-secrets
volumeMounts:
- name: data
mountPath: /data
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
startupProbe:
httpGet:
path: /actuator/health/liveness
port: http
failureThreshold: 30
periodSeconds: 5
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: http
periodSeconds: 30
failureThreshold: 3
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: http
initialDelaySeconds: 5
periodSeconds: 10
failureThreshold: 3
volumes:
- name: data
persistentVolumeClaim:
claimName: swarm-gamma-data
@@ -0,0 +1,103 @@
# Services for swarm variants — ClusterIP only, no external exposure needed
---
apiVersion: v1
kind: Service
metadata:
name: neuron-mcp
namespace: swarm-alpha
labels:
app: neuron-mcp
variant: alpha
spec:
selector:
app: neuron-mcp
ports:
- name: http
port: 8080
targetPort: 8080
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
name: neuron-rest
namespace: swarm-alpha
labels:
app: neuron-rest
variant: alpha
spec:
selector:
app: neuron-rest
ports:
- name: http
port: 8081
targetPort: 8081
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
name: neuron-mcp
namespace: swarm-beta
labels:
app: neuron-mcp
variant: beta
spec:
selector:
app: neuron-mcp
ports:
- name: http
port: 8080
targetPort: 8080
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
name: neuron-rest
namespace: swarm-beta
labels:
app: neuron-rest
variant: beta
spec:
selector:
app: neuron-rest
ports:
- name: http
port: 8081
targetPort: 8081
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
name: neuron-mcp
namespace: swarm-gamma
labels:
app: neuron-mcp
variant: gamma
spec:
selector:
app: neuron-mcp
ports:
- name: http
port: 8080
targetPort: 8080
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
name: neuron-rest
namespace: swarm-gamma
labels:
app: neuron-rest
variant: gamma
spec:
selector:
app: neuron-rest
ports:
- name: http
port: 8081
targetPort: 8081
type: ClusterIP
@@ -0,0 +1,66 @@
# SQLite clone Job for swarm-alpha
# Creates a snapshot of the prod neuron.db into swarm-alpha's PVC.
# This Job is created by swarm.sh at session start; it is NOT static.
# This file is the template — swarm.sh applies it via kubectl after substituting SESSION_ID.
#
# The Job mounts both the prod PVC (read-only) and the variant PVC (read-write).
# It uses a simple cp to snapshot the database before the variant MCP starts.
#
# NOTE: The prod MCP must be scaled down to 0 OR the Job must use SQLite's backup API
# (via sqlite3 .backup command) to ensure consistency. swarm.sh handles the hot-backup
# approach using the sqlite3 CLI, so the prod pod does NOT need to stop.
apiVersion: batch/v1
kind: Job
metadata:
name: sqlite-clone-alpha
namespace: swarm-alpha
labels:
app: swarm-clone
variant: alpha
spec:
ttlSecondsAfterFinished: 3600
backoffLimit: 3
template:
metadata:
labels:
app: swarm-clone
variant: alpha
spec:
restartPolicy: OnFailure
securityContext:
runAsNonRoot: false # sqlite3 needs to run as root to access both PVCs
containers:
- name: sqlite-clone
image: keinos/sqlite3:latest
command:
- sh
- -c
- |
set -e
echo "Starting SQLite hot-backup from prod to swarm-alpha..."
# Use SQLite's .backup command for a consistent online backup
sqlite3 /prod-data/neuron.db ".backup /variant-data/neuron.db"
echo "Backup complete. Verifying..."
sqlite3 /variant-data/neuron.db "PRAGMA integrity_check;"
echo "SQLite clone complete for swarm-alpha."
volumeMounts:
- name: prod-data
mountPath: /prod-data
readOnly: true
- name: variant-data
mountPath: /variant-data
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
volumes:
- name: prod-data
persistentVolumeClaim:
claimName: neuron-prod-data
readOnly: true
- name: variant-data
persistentVolumeClaim:
claimName: swarm-alpha-data
@@ -0,0 +1,54 @@
apiVersion: batch/v1
kind: Job
metadata:
name: sqlite-clone-beta
namespace: swarm-beta
labels:
app: swarm-clone
variant: beta
spec:
ttlSecondsAfterFinished: 3600
backoffLimit: 3
template:
metadata:
labels:
app: swarm-clone
variant: beta
spec:
restartPolicy: OnFailure
securityContext:
runAsNonRoot: false
containers:
- name: sqlite-clone
image: keinos/sqlite3:latest
command:
- sh
- -c
- |
set -e
echo "Starting SQLite hot-backup from prod to swarm-beta..."
sqlite3 /prod-data/neuron.db ".backup /variant-data/neuron.db"
echo "Backup complete. Verifying..."
sqlite3 /variant-data/neuron.db "PRAGMA integrity_check;"
echo "SQLite clone complete for swarm-beta."
volumeMounts:
- name: prod-data
mountPath: /prod-data
readOnly: true
- name: variant-data
mountPath: /variant-data
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
volumes:
- name: prod-data
persistentVolumeClaim:
claimName: neuron-prod-data
readOnly: true
- name: variant-data
persistentVolumeClaim:
claimName: swarm-beta-data
@@ -0,0 +1,54 @@
apiVersion: batch/v1
kind: Job
metadata:
name: sqlite-clone-gamma
namespace: swarm-gamma
labels:
app: swarm-clone
variant: gamma
spec:
ttlSecondsAfterFinished: 3600
backoffLimit: 3
template:
metadata:
labels:
app: swarm-clone
variant: gamma
spec:
restartPolicy: OnFailure
securityContext:
runAsNonRoot: false
containers:
- name: sqlite-clone
image: keinos/sqlite3:latest
command:
- sh
- -c
- |
set -e
echo "Starting SQLite hot-backup from prod to swarm-gamma..."
sqlite3 /prod-data/neuron.db ".backup /variant-data/neuron.db"
echo "Backup complete. Verifying..."
sqlite3 /variant-data/neuron.db "PRAGMA integrity_check;"
echo "SQLite clone complete for swarm-gamma."
volumeMounts:
- name: prod-data
mountPath: /prod-data
readOnly: true
- name: variant-data
mountPath: /variant-data
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
volumes:
- name: prod-data
persistentVolumeClaim:
claimName: neuron-prod-data
readOnly: true
- name: variant-data
persistentVolumeClaim:
claimName: swarm-gamma-data
+40
View File
@@ -50,3 +50,43 @@ resource "kubernetes_namespace" "neuron_tim" {
}
}
}
# Swarm variant namespaces — isolated execution environments for swarm self-improvement loops
resource "kubernetes_namespace" "swarm_alpha" {
metadata {
name = "swarm-alpha"
labels = {
managed-by = "terraform"
tier = "swarm"
environment = "swarm"
app = "neuron-technologies"
variant = "alpha"
}
}
}
resource "kubernetes_namespace" "swarm_beta" {
metadata {
name = "swarm-beta"
labels = {
managed-by = "terraform"
tier = "swarm"
environment = "swarm"
app = "neuron-technologies"
variant = "beta"
}
}
}
resource "kubernetes_namespace" "swarm_gamma" {
metadata {
name = "swarm-gamma"
labels = {
managed-by = "terraform"
tier = "swarm"
environment = "swarm"
app = "neuron-technologies"
variant = "gamma"
}
}
}