From d1896fcf25cb66d56bd278f434267eafc33da7de Mon Sep 17 00:00:00 2001 From: Steven Welch Date: Sat, 19 Sep 2026 21:36:35 -0600 Subject: [PATCH 1/7] chore(retire-sms-bridge): delete opencode-sms-bridge/Chart.yaml --- opencode-sms-bridge/Chart.yaml | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 opencode-sms-bridge/Chart.yaml diff --git a/opencode-sms-bridge/Chart.yaml b/opencode-sms-bridge/Chart.yaml deleted file mode 100644 index 5864bc4..0000000 --- a/opencode-sms-bridge/Chart.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v2 -name: opencode-sms-bridge -description: Signed Twilio SMS and MMS bridge for fixed primary OpenCode agents -type: application -version: 0.1.4 -appVersion: "1" -deprecated: true From 396c6b486d166f1f1144e60973ac8f223fde040a Mon Sep 17 00:00:00 2001 From: Steven Welch Date: Sat, 19 Sep 2026 21:36:44 -0600 Subject: [PATCH 2/7] chore(retire-sms-bridge): delete opencode-sms-bridge/values.yaml --- opencode-sms-bridge/values.yaml | 33 --------------------------------- 1 file changed, 33 deletions(-) delete mode 100644 opencode-sms-bridge/values.yaml diff --git a/opencode-sms-bridge/values.yaml b/opencode-sms-bridge/values.yaml deleted file mode 100644 index 27fcda6..0000000 --- a/opencode-sms-bridge/values.yaml +++ /dev/null @@ -1,33 +0,0 @@ -fullnameOverride: opencode-sms-bridge - -image: - repository: ghcr.io/makeitworkcloud/opencode-sms-bridge - # GitOps must replace this with the immutable image commit SHA after publication. - tag: latest - -persistence: - existingClaim: opencode-sms-bridge-state - -secrets: - routing: opencode-sms-bridge-routing - shared: opencode-sms-bridge-shared - worker: opencode-sms-bridge-worker - opencodeServerAuth: opencode-server-auth - -config: - canonicalWebhookUrl: https://sms-opencode.makeitwork.cloud/twilio/inbound - statePath: /state/opencode-sms-bridge.db - mediaAllowedHosts: - - api.twilio.com - # Set only after a Twilio Messaging Service exists and its sender pool is associated with an approved campaign. - # This non-secret identifier is passed to the worker through the ConfigMap; empty preserves direct from_ sending. - messagingServiceSid: "" - # Keep decimal text intact when Helm renders ConfigMap data for the worker's integer parser. - maxMediaBytes: "5242880" - maxAudioSeconds: 120 - imagePartsEnabled: false - # Set only after a local Whisper-compatible service is selected and validated. - whisperUrl: "" - whisperModel: base - opencodeApiBaseUrl: http://opencode.opencode.svc:4096 - opencodeUsername: opencode From 669a4285dc8a0a4164bb5fff1dcad5a9e684c566 Mon Sep 17 00:00:00 2001 From: Steven Welch Date: Sat, 19 Sep 2026 21:36:53 -0600 Subject: [PATCH 3/7] chore(retire-sms-bridge): delete opencode-sms-bridge/templates/_helpers.tpl --- opencode-sms-bridge/templates/_helpers.tpl | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 opencode-sms-bridge/templates/_helpers.tpl diff --git a/opencode-sms-bridge/templates/_helpers.tpl b/opencode-sms-bridge/templates/_helpers.tpl deleted file mode 100644 index 35ef00e..0000000 --- a/opencode-sms-bridge/templates/_helpers.tpl +++ /dev/null @@ -1,13 +0,0 @@ -{{- define "opencode-sms-bridge.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{- define "opencode-sms-bridge.fullname" -}} -{{- default (include "opencode-sms-bridge.name" .) .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{- define "opencode-sms-bridge.labels" -}} -app: {{ include "opencode-sms-bridge.fullname" . }} -app.kubernetes.io/name: {{ include "opencode-sms-bridge.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end }} From 919060eee6a8937d704e9be7567ab2512d04e6f5 Mon Sep 17 00:00:00 2001 From: Steven Welch Date: Sat, 19 Sep 2026 21:37:05 -0600 Subject: [PATCH 4/7] chore(retire-sms-bridge): delete opencode-sms-bridge/templates/configmap.yaml --- opencode-sms-bridge/templates/configmap.yaml | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 opencode-sms-bridge/templates/configmap.yaml diff --git a/opencode-sms-bridge/templates/configmap.yaml b/opencode-sms-bridge/templates/configmap.yaml deleted file mode 100644 index 7aed081..0000000 --- a/opencode-sms-bridge/templates/configmap.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ include "opencode-sms-bridge.fullname" . }}-config - labels: - {{- include "opencode-sms-bridge.labels" . | nindent 4 }} -data: - CANONICAL_WEBHOOK_URL: {{ .Values.config.canonicalWebhookUrl | quote }} - STATE_PATH: {{ .Values.config.statePath | quote }} - TWILIO_MEDIA_ALLOWED_HOSTS: {{ join "," .Values.config.mediaAllowedHosts | quote }} - TWILIO_MESSAGING_SERVICE_SID: {{ .Values.config.messagingServiceSid | quote }} - MAX_MEDIA_BYTES: {{ .Values.config.maxMediaBytes | quote }} - MAX_AUDIO_SECONDS: {{ .Values.config.maxAudioSeconds | quote }} - OPENCODE_IMAGE_PARTS_ENABLED: {{ .Values.config.imagePartsEnabled | quote }} - WHISPER_URL: {{ .Values.config.whisperUrl | quote }} - WHISPER_MODEL: {{ .Values.config.whisperModel | quote }} - OPENCODE_API_BASE_URL: {{ .Values.config.opencodeApiBaseUrl | quote }} - OPENCODE_SERVER_USERNAME: {{ .Values.config.opencodeUsername | quote }} From dfcf383f32ccdc224999bef436d257908133fc53 Mon Sep 17 00:00:00 2001 From: Steven Welch Date: Sat, 19 Sep 2026 21:37:13 -0600 Subject: [PATCH 5/7] chore(retire-sms-bridge): delete opencode-sms-bridge/templates/deployment.yaml --- opencode-sms-bridge/templates/deployment.yaml | 171 ------------------ 1 file changed, 171 deletions(-) delete mode 100644 opencode-sms-bridge/templates/deployment.yaml diff --git a/opencode-sms-bridge/templates/deployment.yaml b/opencode-sms-bridge/templates/deployment.yaml deleted file mode 100644 index 69d1dcd..0000000 --- a/opencode-sms-bridge/templates/deployment.yaml +++ /dev/null @@ -1,171 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ include "opencode-sms-bridge.fullname" . }} - annotations: - argocd.argoproj.io/sync-wave: "2" - ignore-check.kube-linter.io/unset-cpu-requirements: "single-node policy" - ignore-check.kube-linter.io/unset-memory-requirements: "single-node policy" - secret.reloader.stakater.com/reload: {{ join "," (list .Values.secrets.routing .Values.secrets.shared .Values.secrets.worker .Values.secrets.opencodeServerAuth) | quote }} - labels: - {{- include "opencode-sms-bridge.labels" . | nindent 4 }} -spec: - replicas: 1 - strategy: - type: Recreate - selector: - matchLabels: - app: {{ include "opencode-sms-bridge.fullname" . }} - template: - metadata: - annotations: - checksum/opencode-sms-bridge-config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} - labels: - {{- include "opencode-sms-bridge.labels" . | nindent 8 }} - spec: - automountServiceAccountToken: false - securityContext: - fsGroup: 1000 - runAsGroup: 1000 - runAsNonRoot: true - runAsUser: 1000 - seccompProfile: - type: RuntimeDefault - containers: - - name: ingress - image: {{ .Values.image.repository }}:{{ .Values.image.tag }} - env: - - name: BRIDGE_MODE - value: ingress - - name: ROUTING_CONFIG_PATH - value: /etc/opencode-sms-bridge/routing.json - - name: STATE_ENCRYPTION_KEY - valueFrom: - secretKeyRef: {name: {{ .Values.secrets.shared }}, key: state-encryption-key} - - name: SENDER_HASH_KEY - valueFrom: - secretKeyRef: {name: {{ .Values.secrets.shared }}, key: sender-hash-key} - - name: TWILIO_AUTH_TOKEN - valueFrom: - secretKeyRef: {name: {{ .Values.secrets.shared }}, key: twilio-auth-token} - - name: CANONICAL_WEBHOOK_URL - valueFrom: - configMapKeyRef: {name: {{ include "opencode-sms-bridge.fullname" . }}-config, key: CANONICAL_WEBHOOK_URL} - - name: STATE_PATH - valueFrom: - configMapKeyRef: {name: {{ include "opencode-sms-bridge.fullname" . }}-config, key: STATE_PATH} - ports: - - name: http - containerPort: 8080 - readinessProbe: - httpGet: {path: /healthz, port: http} - livenessProbe: - httpGet: {path: /healthz, port: http} - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: [ALL] - readOnlyRootFilesystem: true - volumeMounts: - - name: state - mountPath: /state - - name: routing - mountPath: /etc/opencode-sms-bridge - readOnly: true - - name: tmp - mountPath: /tmp - - name: worker - image: {{ .Values.image.repository }}:{{ .Values.image.tag }} - env: - - name: BRIDGE_MODE - value: worker - - name: ROUTING_CONFIG_PATH - value: /etc/opencode-sms-bridge/routing.json - - name: STATE_ENCRYPTION_KEY - valueFrom: - secretKeyRef: {name: {{ .Values.secrets.shared }}, key: state-encryption-key} - - name: SENDER_HASH_KEY - valueFrom: - secretKeyRef: {name: {{ .Values.secrets.shared }}, key: sender-hash-key} - - name: TWILIO_AUTH_TOKEN - valueFrom: - secretKeyRef: {name: {{ .Values.secrets.shared }}, key: twilio-auth-token} - - name: TWILIO_API_KEY_SID - valueFrom: - secretKeyRef: {name: {{ .Values.secrets.worker }}, key: twilio-api-key-sid} - - name: TWILIO_API_KEY_SECRET - valueFrom: - secretKeyRef: {name: {{ .Values.secrets.worker }}, key: twilio-api-key-secret} - - name: OPENCODE_SERVER_PASSWORD - valueFrom: - secretKeyRef: {name: {{ .Values.secrets.opencodeServerAuth }}, key: password} - - name: CANONICAL_WEBHOOK_URL - valueFrom: - configMapKeyRef: {name: {{ include "opencode-sms-bridge.fullname" . }}-config, key: CANONICAL_WEBHOOK_URL} - - name: STATE_PATH - valueFrom: - configMapKeyRef: {name: {{ include "opencode-sms-bridge.fullname" . }}-config, key: STATE_PATH} - - name: TWILIO_MEDIA_ALLOWED_HOSTS - valueFrom: - configMapKeyRef: {name: {{ include "opencode-sms-bridge.fullname" . }}-config, key: TWILIO_MEDIA_ALLOWED_HOSTS} - - name: TWILIO_MESSAGING_SERVICE_SID - valueFrom: - configMapKeyRef: {name: {{ include "opencode-sms-bridge.fullname" . }}-config, key: TWILIO_MESSAGING_SERVICE_SID} - - name: MAX_MEDIA_BYTES - valueFrom: - configMapKeyRef: {name: {{ include "opencode-sms-bridge.fullname" . }}-config, key: MAX_MEDIA_BYTES} - - name: MAX_AUDIO_SECONDS - valueFrom: - configMapKeyRef: {name: {{ include "opencode-sms-bridge.fullname" . }}-config, key: MAX_AUDIO_SECONDS} - - name: OPENCODE_IMAGE_PARTS_ENABLED - valueFrom: - configMapKeyRef: {name: {{ include "opencode-sms-bridge.fullname" . }}-config, key: OPENCODE_IMAGE_PARTS_ENABLED} - - name: WHISPER_URL - valueFrom: - configMapKeyRef: {name: {{ include "opencode-sms-bridge.fullname" . }}-config, key: WHISPER_URL} - - name: WHISPER_MODEL - valueFrom: - configMapKeyRef: {name: {{ include "opencode-sms-bridge.fullname" . }}-config, key: WHISPER_MODEL} - - name: OPENCODE_API_BASE_URL - valueFrom: - configMapKeyRef: {name: {{ include "opencode-sms-bridge.fullname" . }}-config, key: OPENCODE_API_BASE_URL} - - name: OPENCODE_SERVER_USERNAME - valueFrom: - configMapKeyRef: {name: {{ include "opencode-sms-bridge.fullname" . }}-config, key: OPENCODE_SERVER_USERNAME} - livenessProbe: - exec: - command: - - python3 - - -c - - import urllib.request; urllib.request.urlopen('http://127.0.0.1:8081/healthz', timeout=2) - readinessProbe: - exec: - command: - - python3 - - -c - - import urllib.request; urllib.request.urlopen('http://127.0.0.1:8081/healthz', timeout=2) - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: [ALL] - readOnlyRootFilesystem: true - volumeMounts: - - name: state - mountPath: /state - - name: routing - mountPath: /etc/opencode-sms-bridge - readOnly: true - - name: tmp - mountPath: /tmp - volumes: - - name: state - persistentVolumeClaim: - claimName: {{ .Values.persistence.existingClaim }} - - name: routing - secret: - secretName: {{ .Values.secrets.routing }} - items: - - key: routing.json - path: routing.json - - name: tmp - emptyDir: {} From 481a509b5e59658d8f38948f88a72c0d498eaa79 Mon Sep 17 00:00:00 2001 From: Steven Welch Date: Sat, 19 Sep 2026 21:37:41 -0600 Subject: [PATCH 6/7] chore(retire-sms-bridge): delete opencode-sms-bridge/README.md --- opencode-sms-bridge/README.md | 40 ----------------------------------- 1 file changed, 40 deletions(-) delete mode 100644 opencode-sms-bridge/README.md diff --git a/opencode-sms-bridge/README.md b/opencode-sms-bridge/README.md deleted file mode 100644 index 4a1f630..0000000 --- a/opencode-sms-bridge/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# OpenCode SMS bridge chart - -> **Deprecated.** Version 0.1.4 is the final release and only adds this deprecation marker; no template or values changed from 0.1.3. The chart receives no further maintenance, and published OCI versions up to 0.1.4 remain available at `oci://ghcr.io/makeitworkcloud/charts/opencode-sms-bridge` with no artifacts removed. Do not select this chart for new deployments. - -This chart deploys the portable, single-replica `opencode-sms-bridge` Pod: a public signed-webhook ingress container and a private queue worker container. It routes each destination number to one of four existing primary OpenCode agents: `lawnmowerman`, `grillmaster`, `homesteader`, or `homerepair`. It is not a Twilio-account or cluster-integration chart. - -## Ownership - -The chart owns a Deployment and non-secret ConfigMap. `makeitworkcloud/kustomize-cluster` owns the existing `opencode` namespace, RWO state PVC, stable ClusterIP Service, public workload `TunnelBinding`, and all SOPS-encrypted Secret values. Do not define those resources here. - -The Pod uses `Recreate` because the SQLite queue/session store is intentionally single-writer on an RWO PVC. It is annotated with the installed Reloader's named-Secret annotation so rotation of any referenced bridge or OpenCode Basic-auth Secret replaces both containers. - -## Prerequisites - -The GitOps consumer must provide these Secrets in the `opencode` namespace: - -- `opencode-sms-bridge-routing` with `routing.json`, containing the Twilio account identifier, initial approved sender set, and exactly four fixed destination-to-primary-agent mappings: one each for `lawnmowerman`, `grillmaster`, `homesteader`, and `homerepair`; -- `opencode-sms-bridge-shared` with the webhook-validation token, Fernet state-encryption key, and independent sender-HMAC key; -- `opencode-sms-bridge-worker` with a least-privilege Twilio API Key SID/secret for outbound replies; and -- the existing `opencode-server-auth` Secret for the worker's private OpenCode HTTP request. - -Only a signed request from an approved source number is queued or answered. The bridge invokes the existing primary agent IDs, so they retain their normal OpenCode permissions, MCPs, skills, and shared instructions. The source allowlist is an ingress identity gate, not standing authorization; the existing explicit-confirmation requirements govern individual mutations. - -Use an immutable published image SHA in `image.tag`; `latest` is only the source-chart default and must never be selected by the GitOps consumer. - -## Configuration - -`config.maxMediaBytes` is a quoted decimal string (for example, `"5242880"`). It is rendered into ConfigMap data and consumed by the worker's integer parser; do not use YAML numeric or floating-point notation for this value. - -`config.messagingServiceSid` is a non-secret Twilio Messaging Service identifier. Keep it empty until Terraform has created the service and the operator has associated its sender pool with an approved A2P campaign. The chart passes it only to the worker through the ConfigMap. A non-empty value makes a compatible bridge image submit outbound replies through the Messaging Service; an empty value preserves direct `from_` sending for rollback. Never place API keys or other credentials in this value. - -## Image and audio gates - -Image parts are disabled by default. Enable `config.imagePartsEnabled` only after the selected OpenCode model and deployed file-part API are functionally verified. Keep `config.whisperUrl` empty until a local Whisper-compatible service, capacity, and retention boundary are selected; audio MMS then receives a bounded non-processing reply rather than unvalidated forwarding. - -## Rendered resource - -- Deployment, sync wave `2`, with two hardened containers and a `Recreate` strategy. - -The corresponding cluster overlay must place the RWO state PVC in wave `2` with the Deployment so `WaitForFirstConsumer` storage can bind. Secrets and the Service may be earlier; the `TunnelBinding` belongs in wave `3`. These waves order only resources within the existing `opencode` child Application. From 70fcfd32263c4108dad69b3155f5857623058955 Mon Sep 17 00:00:00 2001 From: Steven Welch Date: Sat, 19 Sep 2026 21:37:56 -0600 Subject: [PATCH 7/7] chore(retire-sms-bridge): remove opencode-sms-bridge from chart index The chart directory was deleted, so the root README chart index no longer lists it. Generic chart autodiscovery and the opencode-server chart are unchanged. --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index a82561a..61d3067 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,6 @@ directory containing `Chart.yaml` is an independently versioned chart. | --- | --- | | `agent-pipe-uploader/` | Internal presigned-S3 artifact uploader Service and Deployment | | `opencode-server/` | OpenCode Deployment and non-secret configuration | -| `opencode-sms-bridge/` (deprecated at 0.1.4) | Signed Twilio SMS/MMS bridge Deployment for fixed OpenCode mobile agents; final release, no further maintenance | ## Guides