@pleri/olam-cli 0.1.147 → 0.1.148

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/commands/auth.d.ts.map +1 -1
  2. package/dist/commands/auth.js +26 -1
  3. package/dist/commands/auth.js.map +1 -1
  4. package/dist/commands/doctor.d.ts +31 -3
  5. package/dist/commands/doctor.d.ts.map +1 -1
  6. package/dist/commands/doctor.js +274 -6
  7. package/dist/commands/doctor.js.map +1 -1
  8. package/dist/commands/services.d.ts +41 -3
  9. package/dist/commands/services.d.ts.map +1 -1
  10. package/dist/commands/services.js +221 -13
  11. package/dist/commands/services.js.map +1 -1
  12. package/dist/commands/substrate-audit-log.d.ts +2 -0
  13. package/dist/commands/substrate-audit-log.d.ts.map +1 -1
  14. package/dist/commands/substrate-audit-log.js +13 -0
  15. package/dist/commands/substrate-audit-log.js.map +1 -1
  16. package/dist/image-digests.json +7 -7
  17. package/dist/index.js +3381 -2560
  18. package/dist/lib/auth-refresh-kubernetes.d.ts +62 -0
  19. package/dist/lib/auth-refresh-kubernetes.d.ts.map +1 -0
  20. package/dist/lib/auth-refresh-kubernetes.js +127 -0
  21. package/dist/lib/auth-refresh-kubernetes.js.map +1 -0
  22. package/dist/lib/kubectl-wrap.d.ts +6 -0
  23. package/dist/lib/kubectl-wrap.d.ts.map +1 -1
  24. package/dist/lib/kubectl-wrap.js +6 -1
  25. package/dist/lib/kubectl-wrap.js.map +1 -1
  26. package/dist/lib/manifest-refresh.d.ts +8 -1
  27. package/dist/lib/manifest-refresh.d.ts.map +1 -1
  28. package/dist/lib/manifest-refresh.js +17 -7
  29. package/dist/lib/manifest-refresh.js.map +1 -1
  30. package/dist/lib/peripheral-registry.d.ts +36 -0
  31. package/dist/lib/peripheral-registry.d.ts.map +1 -0
  32. package/dist/lib/peripheral-registry.js +55 -0
  33. package/dist/lib/peripheral-registry.js.map +1 -0
  34. package/dist/lib/port-forward.d.ts +67 -0
  35. package/dist/lib/port-forward.d.ts.map +1 -1
  36. package/dist/lib/port-forward.js +153 -0
  37. package/dist/lib/port-forward.js.map +1 -1
  38. package/dist/lib/upgrade-kubernetes.d.ts +35 -11
  39. package/dist/lib/upgrade-kubernetes.d.ts.map +1 -1
  40. package/dist/lib/upgrade-kubernetes.js +265 -21
  41. package/dist/lib/upgrade-kubernetes.js.map +1 -1
  42. package/host-cp/k8s/manifests/auth-service/10-serviceaccount.yaml +8 -0
  43. package/host-cp/k8s/manifests/auth-service/20-rbac.yaml +34 -0
  44. package/host-cp/k8s/manifests/auth-service/30-configmap.yaml +24 -0
  45. package/host-cp/k8s/manifests/auth-service/45-pvc.yaml +25 -0
  46. package/host-cp/k8s/manifests/auth-service/50-deployment.yaml +114 -0
  47. package/host-cp/k8s/manifests/auth-service/60-service.yaml +21 -0
  48. package/host-cp/k8s/manifests/kg-service/10-serviceaccount.yaml +8 -0
  49. package/host-cp/k8s/manifests/kg-service/20-rbac.yaml +34 -0
  50. package/host-cp/k8s/manifests/kg-service/30-configmap.yaml +18 -0
  51. package/host-cp/k8s/manifests/kg-service/45-pvc.yaml +25 -0
  52. package/host-cp/k8s/manifests/kg-service/50-deployment.yaml +108 -0
  53. package/host-cp/k8s/manifests/kg-service/60-service.yaml +21 -0
  54. package/host-cp/k8s/manifests/mcp-auth-service/10-serviceaccount.yaml +8 -0
  55. package/host-cp/k8s/manifests/mcp-auth-service/20-rbac.yaml +34 -0
  56. package/host-cp/k8s/manifests/mcp-auth-service/30-configmap.yaml +18 -0
  57. package/host-cp/k8s/manifests/mcp-auth-service/45-pvc.yaml +25 -0
  58. package/host-cp/k8s/manifests/mcp-auth-service/50-deployment.yaml +114 -0
  59. package/host-cp/k8s/manifests/mcp-auth-service/60-service.yaml +21 -0
  60. package/host-cp/k8s/manifests/memory-service/10-serviceaccount.yaml +8 -0
  61. package/host-cp/k8s/manifests/memory-service/20-rbac.yaml +34 -0
  62. package/host-cp/k8s/manifests/memory-service/30-configmap.yaml +20 -0
  63. package/host-cp/k8s/manifests/memory-service/45-pvc.yaml +25 -0
  64. package/host-cp/k8s/manifests/memory-service/50-deployment.yaml +116 -0
  65. package/host-cp/k8s/manifests/memory-service/60-service.yaml +21 -0
  66. package/host-cp/k8s/templates/auth-service-secret-template.yaml +28 -0
  67. package/host-cp/k8s/templates/kg-service-secret-template.yaml +28 -0
  68. package/host-cp/k8s/templates/mcp-auth-service-secret-template.yaml +28 -0
  69. package/host-cp/k8s/templates/memory-service-secret-template.yaml +29 -0
  70. package/host-cp/src/plan-chat-service.mjs +22 -3
  71. package/host-cp/src/server.mjs +4 -4
  72. package/package.json +1 -1
@@ -0,0 +1,8 @@
1
+ apiVersion: v1
2
+ kind: ServiceAccount
3
+ metadata:
4
+ name: olam-kg-service
5
+ namespace: olam
6
+ labels:
7
+ app: olam-kg-service
8
+ olam.io/component: peripheral
@@ -0,0 +1,34 @@
1
+ # Phase 1a Decision 19: Role scoped to resourceNames: ["olam-kg-service"] on
2
+ # apps/v1 deployments. Without this scope, the in-cluster ServiceAccount
3
+ # could patch ANY Deployment in the namespace. This is the load-bearing
4
+ # security guardrail — preserve verbatim.
5
+ apiVersion: rbac.authorization.k8s.io/v1
6
+ kind: Role
7
+ metadata:
8
+ name: olam-kg-service
9
+ namespace: olam
10
+ labels:
11
+ app: olam-kg-service
12
+ olam.io/component: peripheral
13
+ rules:
14
+ - apiGroups: ["apps"]
15
+ resources: ["deployments"]
16
+ resourceNames: ["olam-kg-service"]
17
+ verbs: ["get", "patch", "watch"]
18
+ ---
19
+ apiVersion: rbac.authorization.k8s.io/v1
20
+ kind: RoleBinding
21
+ metadata:
22
+ name: olam-kg-service
23
+ namespace: olam
24
+ labels:
25
+ app: olam-kg-service
26
+ olam.io/component: peripheral
27
+ subjects:
28
+ - kind: ServiceAccount
29
+ name: olam-kg-service
30
+ namespace: olam
31
+ roleRef:
32
+ kind: Role
33
+ name: olam-kg-service
34
+ apiGroup: rbac.authorization.k8s.io
@@ -0,0 +1,18 @@
1
+ # ConfigMap for olam-kg-service environment. Sensitive values live in
2
+ # the Secret (see templates/kg-service-secret-template.yaml).
3
+ # Operators apply the Secret separately before applying the manifests.
4
+ apiVersion: v1
5
+ kind: ConfigMap
6
+ metadata:
7
+ name: olam-kg-service-env
8
+ namespace: olam
9
+ labels:
10
+ app: olam-kg-service
11
+ olam.io/component: peripheral
12
+ data:
13
+ # Port kg-service listens on. Must match 60-service.yaml targetPort.
14
+ OLAM_KG_PORT: "9997"
15
+ # Data directory — backed by the PVC mounted at /data.
16
+ OLAM_KG_DATA_PATH: "/data/kg"
17
+ # URL of auth-service (cluster-internal DNS). Override in non-k3d environments.
18
+ OLAM_AUTH_SERVICE_URL: "http://olam-auth-service.olam.svc.cluster.local:9999"
@@ -0,0 +1,25 @@
1
+ # PersistentVolumeClaim for olam-kg-service /data volume.
2
+ #
3
+ # Why PVC instead of hostPath: see packages/host-cp/k8s/manifests/host-cp/45-pvc.yaml
4
+ # for the full rationale (fsGroup, k3d node filesystem, etc.).
5
+ #
6
+ # local-path StorageClass ships with k3d by default (rancher/local-path-provisioner).
7
+ # On non-k3d clusters, substitute storageClassName with your cluster's provisioner.
8
+ # D24: storageClassName operator-editable — edit the field below for non-k3d substrates.
9
+ apiVersion: v1
10
+ kind: PersistentVolumeClaim
11
+ metadata:
12
+ name: olam-kg-data
13
+ namespace: olam
14
+ labels:
15
+ app: olam-kg-service
16
+ olam.io/component: peripheral
17
+ spec:
18
+ accessModes:
19
+ - ReadWriteOnce
20
+ # D24: operator-editable. k3d default is local-path. Change for non-k3d substrates.
21
+ storageClassName: local-path
22
+ resources:
23
+ requests:
24
+ # D25: kg-service PVC size 10Gi (larger: graph index grows with codebase).
25
+ storage: 10Gi
@@ -0,0 +1,108 @@
1
+ # Deployment for olam-kg-service.
2
+ #
3
+ # Image: pinned to sha256 digest (not :latest or named tag) per T4 threat model.
4
+ # Digest resolves to ghcr.io/pleri/olam-kg-service:0.1.0 (multi-arch index).
5
+ # To update: resolve the new tag's digest via:
6
+ # TOKEN=$(curl -s "https://ghcr.io/token?scope=repository:pleri/olam-kg-service:pull&service=ghcr.io" | jq -r .token)
7
+ # curl -sI -H "Authorization: Bearer $TOKEN" \
8
+ # -H "Accept: application/vnd.oci.image.index.v1+json,application/vnd.docker.distribution.manifest.list.v2+json" \
9
+ # https://ghcr.io/v2/pleri/olam-kg-service/manifests/<tag> | grep docker-content-digest
10
+ #
11
+ # securityContext: conservative defaults per T6/T7 threat model (runAsNonRoot,
12
+ # readOnlyRootFilesystem). /tmp backed by emptyDir for transient write needs.
13
+ apiVersion: apps/v1
14
+ kind: Deployment
15
+ metadata:
16
+ name: olam-kg-service
17
+ namespace: olam
18
+ labels:
19
+ app: olam-kg-service
20
+ olam.io/component: peripheral
21
+ spec:
22
+ replicas: 1
23
+ strategy:
24
+ type: RollingUpdate
25
+ rollingUpdate:
26
+ maxSurge: 1
27
+ maxUnavailable: 0
28
+ selector:
29
+ matchLabels:
30
+ app: olam-kg-service
31
+ template:
32
+ metadata:
33
+ labels:
34
+ app: olam-kg-service
35
+ spec:
36
+ serviceAccountName: olam-kg-service
37
+ securityContext:
38
+ runAsNonRoot: true
39
+ runAsUser: 1000
40
+ runAsGroup: 1000
41
+ fsGroup: 1000
42
+ initContainers:
43
+ - name: chown-data
44
+ # busybox:1.36 — sha256-pinned per T4 threat model.
45
+ image: busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662
46
+ imagePullPolicy: IfNotPresent
47
+ securityContext:
48
+ runAsUser: 0
49
+ runAsNonRoot: false
50
+ allowPrivilegeEscalation: false
51
+ command: ["chown", "-R", "1000:1000", "/data"]
52
+ volumeMounts:
53
+ - name: kg-data
54
+ mountPath: /data
55
+ containers:
56
+ - name: olam-kg-service
57
+ image: ghcr.io/pleri/olam-kg-service@sha256:c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4
58
+ imagePullPolicy: IfNotPresent
59
+ securityContext:
60
+ runAsNonRoot: true
61
+ runAsUser: 1000
62
+ readOnlyRootFilesystem: true
63
+ allowPrivilegeEscalation: false
64
+ capabilities:
65
+ drop: ["ALL"]
66
+ ports:
67
+ - name: http
68
+ containerPort: 9997
69
+ protocol: TCP
70
+ envFrom:
71
+ - configMapRef:
72
+ name: olam-kg-service-env
73
+ - secretRef:
74
+ name: olam-kg-service-secret
75
+ volumeMounts:
76
+ - name: kg-data
77
+ mountPath: /data
78
+ - name: tmp
79
+ mountPath: /tmp
80
+ readinessProbe:
81
+ httpGet:
82
+ path: /health
83
+ port: 9997
84
+ initialDelaySeconds: 5
85
+ periodSeconds: 5
86
+ timeoutSeconds: 3
87
+ failureThreshold: 6
88
+ livenessProbe:
89
+ httpGet:
90
+ path: /health
91
+ port: 9997
92
+ initialDelaySeconds: 30
93
+ periodSeconds: 20
94
+ timeoutSeconds: 5
95
+ failureThreshold: 3
96
+ resources:
97
+ requests:
98
+ cpu: "100m"
99
+ memory: "256Mi"
100
+ limits:
101
+ cpu: "1000m"
102
+ memory: "1Gi"
103
+ volumes:
104
+ - name: kg-data
105
+ persistentVolumeClaim:
106
+ claimName: olam-kg-data
107
+ - name: tmp
108
+ emptyDir: {}
@@ -0,0 +1,21 @@
1
+ # ClusterIP Service for olam-kg-service.
2
+ # Port 9997 — consumed by agents and host-cp via cluster-internal DNS.
3
+ # Operator surfaces externally via:
4
+ # kubectl port-forward -n olam svc/olam-kg-service 9997:9997
5
+ apiVersion: v1
6
+ kind: Service
7
+ metadata:
8
+ name: olam-kg-service
9
+ namespace: olam
10
+ labels:
11
+ app: olam-kg-service
12
+ olam.io/component: peripheral
13
+ spec:
14
+ type: ClusterIP
15
+ selector:
16
+ app: olam-kg-service
17
+ ports:
18
+ - name: http
19
+ port: 9997
20
+ targetPort: 9997
21
+ protocol: TCP
@@ -0,0 +1,8 @@
1
+ apiVersion: v1
2
+ kind: ServiceAccount
3
+ metadata:
4
+ name: olam-mcp-auth-service
5
+ namespace: olam
6
+ labels:
7
+ app: olam-mcp-auth-service
8
+ olam.io/component: peripheral
@@ -0,0 +1,34 @@
1
+ # Phase 1a Decision 19: Role scoped to resourceNames: ["olam-mcp-auth-service"] on
2
+ # apps/v1 deployments. Without this scope, the in-cluster ServiceAccount
3
+ # could patch ANY Deployment in the namespace. This is the load-bearing
4
+ # security guardrail — preserve verbatim.
5
+ apiVersion: rbac.authorization.k8s.io/v1
6
+ kind: Role
7
+ metadata:
8
+ name: olam-mcp-auth-service
9
+ namespace: olam
10
+ labels:
11
+ app: olam-mcp-auth-service
12
+ olam.io/component: peripheral
13
+ rules:
14
+ - apiGroups: ["apps"]
15
+ resources: ["deployments"]
16
+ resourceNames: ["olam-mcp-auth-service"]
17
+ verbs: ["get", "patch", "watch"]
18
+ ---
19
+ apiVersion: rbac.authorization.k8s.io/v1
20
+ kind: RoleBinding
21
+ metadata:
22
+ name: olam-mcp-auth-service
23
+ namespace: olam
24
+ labels:
25
+ app: olam-mcp-auth-service
26
+ olam.io/component: peripheral
27
+ subjects:
28
+ - kind: ServiceAccount
29
+ name: olam-mcp-auth-service
30
+ namespace: olam
31
+ roleRef:
32
+ kind: Role
33
+ name: olam-mcp-auth-service
34
+ apiGroup: rbac.authorization.k8s.io
@@ -0,0 +1,18 @@
1
+ # ConfigMap for olam-mcp-auth-service environment. Sensitive values live in
2
+ # the Secret (see templates/mcp-auth-service-secret-template.yaml).
3
+ # Operators apply the Secret separately before applying the manifests.
4
+ apiVersion: v1
5
+ kind: ConfigMap
6
+ metadata:
7
+ name: olam-mcp-auth-service-env
8
+ namespace: olam
9
+ labels:
10
+ app: olam-mcp-auth-service
11
+ olam.io/component: peripheral
12
+ data:
13
+ # Port mcp-auth-service listens on. Must match 60-service.yaml targetPort.
14
+ OLAM_MCP_AUTH_PORT: "9998"
15
+ # Data directory — backed by the PVC mounted at /data.
16
+ OLAM_MCP_AUTH_DATA_PATH: "/data/mcp-auth"
17
+ # URL of auth-service (cluster-internal DNS). Override in non-k3d environments.
18
+ OLAM_AUTH_SERVICE_URL: "http://olam-auth-service.olam.svc.cluster.local:9999"
@@ -0,0 +1,25 @@
1
+ # PersistentVolumeClaim for olam-mcp-auth-service /data volume.
2
+ #
3
+ # Why PVC instead of hostPath: see packages/host-cp/k8s/manifests/host-cp/45-pvc.yaml
4
+ # for the full rationale (fsGroup, k3d node filesystem, etc.).
5
+ #
6
+ # local-path StorageClass ships with k3d by default (rancher/local-path-provisioner).
7
+ # On non-k3d clusters, substitute storageClassName with your cluster's provisioner.
8
+ # D24: storageClassName operator-editable — edit the field below for non-k3d substrates.
9
+ apiVersion: v1
10
+ kind: PersistentVolumeClaim
11
+ metadata:
12
+ name: olam-mcp-auth-data
13
+ namespace: olam
14
+ labels:
15
+ app: olam-mcp-auth-service
16
+ olam.io/component: peripheral
17
+ spec:
18
+ accessModes:
19
+ - ReadWriteOnce
20
+ # D24: operator-editable. k3d default is local-path. Change for non-k3d substrates.
21
+ storageClassName: local-path
22
+ resources:
23
+ requests:
24
+ # D25: mcp-auth-service PVC size 5Gi.
25
+ storage: 5Gi
@@ -0,0 +1,114 @@
1
+ # Deployment for olam-mcp-auth-service.
2
+ #
3
+ # Image: pinned to sha256 digest (not :latest or named tag) per T4 threat model.
4
+ # Digest resolves to ghcr.io/pleri/olam-mcp-auth-service:0.1.0 (multi-arch index).
5
+ # To update: resolve the new tag's digest via:
6
+ # TOKEN=$(curl -s "https://ghcr.io/token?scope=repository:pleri/olam-mcp-auth-service:pull&service=ghcr.io" | jq -r .token)
7
+ # curl -sI -H "Authorization: Bearer $TOKEN" \
8
+ # -H "Accept: application/vnd.oci.image.index.v1+json,application/vnd.docker.distribution.manifest.list.v2+json" \
9
+ # https://ghcr.io/v2/pleri/olam-mcp-auth-service/manifests/<tag> | grep docker-content-digest
10
+ #
11
+ # securityContext: conservative defaults per T6/T7 threat model (runAsNonRoot,
12
+ # readOnlyRootFilesystem). /tmp backed by emptyDir for transient write needs.
13
+ #
14
+ # D17 (LOAD-BEARING): mcp-auth-service MUST NOT mount /var/run/docker.sock.
15
+ # Phase 2 architecture: k8s pods cannot reach docker.sock. No hostPath socket
16
+ # mount here — mcp-auth-service authenticates MCP clients via JWT, not Docker.
17
+ apiVersion: apps/v1
18
+ kind: Deployment
19
+ metadata:
20
+ name: olam-mcp-auth-service
21
+ namespace: olam
22
+ labels:
23
+ app: olam-mcp-auth-service
24
+ olam.io/component: peripheral
25
+ spec:
26
+ replicas: 1
27
+ strategy:
28
+ type: RollingUpdate
29
+ rollingUpdate:
30
+ maxSurge: 1
31
+ maxUnavailable: 0
32
+ selector:
33
+ matchLabels:
34
+ app: olam-mcp-auth-service
35
+ template:
36
+ metadata:
37
+ labels:
38
+ app: olam-mcp-auth-service
39
+ spec:
40
+ serviceAccountName: olam-mcp-auth-service
41
+ securityContext:
42
+ runAsNonRoot: true
43
+ runAsUser: 1000
44
+ runAsGroup: 1000
45
+ fsGroup: 1000
46
+ initContainers:
47
+ - name: chown-data
48
+ # busybox:1.36 — sha256-pinned per T4 threat model.
49
+ image: busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662
50
+ imagePullPolicy: IfNotPresent
51
+ securityContext:
52
+ runAsUser: 0
53
+ runAsNonRoot: false
54
+ allowPrivilegeEscalation: false
55
+ command: ["chown", "-R", "1000:1000", "/data"]
56
+ volumeMounts:
57
+ - name: mcp-auth-data
58
+ mountPath: /data
59
+ containers:
60
+ - name: olam-mcp-auth-service
61
+ image: ghcr.io/pleri/olam-mcp-auth-service@sha256:b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3
62
+ imagePullPolicy: IfNotPresent
63
+ securityContext:
64
+ runAsNonRoot: true
65
+ runAsUser: 1000
66
+ readOnlyRootFilesystem: true
67
+ allowPrivilegeEscalation: false
68
+ capabilities:
69
+ drop: ["ALL"]
70
+ ports:
71
+ - name: http
72
+ containerPort: 9998
73
+ protocol: TCP
74
+ envFrom:
75
+ - configMapRef:
76
+ name: olam-mcp-auth-service-env
77
+ - secretRef:
78
+ name: olam-mcp-auth-service-secret
79
+ volumeMounts:
80
+ - name: mcp-auth-data
81
+ mountPath: /data
82
+ - name: tmp
83
+ mountPath: /tmp
84
+ readinessProbe:
85
+ httpGet:
86
+ path: /health
87
+ port: 9998
88
+ initialDelaySeconds: 5
89
+ periodSeconds: 5
90
+ timeoutSeconds: 3
91
+ failureThreshold: 6
92
+ livenessProbe:
93
+ httpGet:
94
+ path: /health
95
+ port: 9998
96
+ initialDelaySeconds: 30
97
+ periodSeconds: 20
98
+ timeoutSeconds: 5
99
+ failureThreshold: 3
100
+ resources:
101
+ requests:
102
+ cpu: "50m"
103
+ memory: "128Mi"
104
+ limits:
105
+ cpu: "500m"
106
+ memory: "512Mi"
107
+ volumes:
108
+ - name: mcp-auth-data
109
+ persistentVolumeClaim:
110
+ claimName: olam-mcp-auth-data
111
+ - name: tmp
112
+ emptyDir: {}
113
+ # D17 (LOAD-BEARING): NO docker.sock volume or hostPath mount here.
114
+ # mcp-auth-service does not need Docker access in Phase 2 k8s architecture.
@@ -0,0 +1,21 @@
1
+ # ClusterIP Service for olam-mcp-auth-service.
2
+ # Port 9998 — consumed by other peripherals and host-cp via cluster-internal DNS.
3
+ # Operator surfaces externally via:
4
+ # kubectl port-forward -n olam svc/olam-mcp-auth-service 9998:9998
5
+ apiVersion: v1
6
+ kind: Service
7
+ metadata:
8
+ name: olam-mcp-auth-service
9
+ namespace: olam
10
+ labels:
11
+ app: olam-mcp-auth-service
12
+ olam.io/component: peripheral
13
+ spec:
14
+ type: ClusterIP
15
+ selector:
16
+ app: olam-mcp-auth-service
17
+ ports:
18
+ - name: http
19
+ port: 9998
20
+ targetPort: 9998
21
+ protocol: TCP
@@ -0,0 +1,8 @@
1
+ apiVersion: v1
2
+ kind: ServiceAccount
3
+ metadata:
4
+ name: olam-memory-service
5
+ namespace: olam
6
+ labels:
7
+ app: olam-memory-service
8
+ olam.io/component: peripheral
@@ -0,0 +1,34 @@
1
+ # Phase 1a Decision 19: Role scoped to resourceNames: ["olam-memory-service"] on
2
+ # apps/v1 deployments. Without this scope, the in-cluster ServiceAccount
3
+ # could patch ANY Deployment in the namespace. This is the load-bearing
4
+ # security guardrail — preserve verbatim.
5
+ apiVersion: rbac.authorization.k8s.io/v1
6
+ kind: Role
7
+ metadata:
8
+ name: olam-memory-service
9
+ namespace: olam
10
+ labels:
11
+ app: olam-memory-service
12
+ olam.io/component: peripheral
13
+ rules:
14
+ - apiGroups: ["apps"]
15
+ resources: ["deployments"]
16
+ resourceNames: ["olam-memory-service"]
17
+ verbs: ["get", "patch", "watch"]
18
+ ---
19
+ apiVersion: rbac.authorization.k8s.io/v1
20
+ kind: RoleBinding
21
+ metadata:
22
+ name: olam-memory-service
23
+ namespace: olam
24
+ labels:
25
+ app: olam-memory-service
26
+ olam.io/component: peripheral
27
+ subjects:
28
+ - kind: ServiceAccount
29
+ name: olam-memory-service
30
+ namespace: olam
31
+ roleRef:
32
+ kind: Role
33
+ name: olam-memory-service
34
+ apiGroup: rbac.authorization.k8s.io
@@ -0,0 +1,20 @@
1
+ # ConfigMap for olam-memory-service environment. Sensitive values live in
2
+ # the Secret (see templates/memory-service-secret-template.yaml).
3
+ # Operators apply the Secret separately before applying the manifests.
4
+ apiVersion: v1
5
+ kind: ConfigMap
6
+ metadata:
7
+ name: olam-memory-service-env
8
+ namespace: olam
9
+ labels:
10
+ app: olam-memory-service
11
+ olam.io/component: peripheral
12
+ data:
13
+ # Port memory-service listens on. Must match 60-service.yaml targetPort.
14
+ OLAM_MEMORY_PORT: "3111"
15
+ # Data directory — backed by the PVC mounted at /data.
16
+ OLAM_MEMORY_DATA_PATH: "/data/memory"
17
+ # URL of auth-service (cluster-internal DNS). Override in non-k3d environments.
18
+ OLAM_AUTH_SERVICE_URL: "http://olam-auth-service.olam.svc.cluster.local:9999"
19
+ # Health path exposed at /agentmemory/livez (D15 — do not change).
20
+ OLAM_MEMORY_HEALTH_PATH: "/agentmemory/livez"
@@ -0,0 +1,25 @@
1
+ # PersistentVolumeClaim for olam-memory-service /data volume.
2
+ #
3
+ # Why PVC instead of hostPath: see packages/host-cp/k8s/manifests/host-cp/45-pvc.yaml
4
+ # for the full rationale (fsGroup, k3d node filesystem, etc.).
5
+ #
6
+ # local-path StorageClass ships with k3d by default (rancher/local-path-provisioner).
7
+ # On non-k3d clusters, substitute storageClassName with your cluster's provisioner.
8
+ # D24: storageClassName operator-editable — edit the field below for non-k3d substrates.
9
+ apiVersion: v1
10
+ kind: PersistentVolumeClaim
11
+ metadata:
12
+ name: olam-memory-data
13
+ namespace: olam
14
+ labels:
15
+ app: olam-memory-service
16
+ olam.io/component: peripheral
17
+ spec:
18
+ accessModes:
19
+ - ReadWriteOnce
20
+ # D24: operator-editable. k3d default is local-path. Change for non-k3d substrates.
21
+ storageClassName: local-path
22
+ resources:
23
+ requests:
24
+ # D25: memory-service PVC size 5Gi.
25
+ storage: 5Gi
@@ -0,0 +1,116 @@
1
+ # Deployment for olam-memory-service.
2
+ #
3
+ # Image: pinned to sha256 digest (not :latest or named tag) per T4 threat model.
4
+ # Digest resolves to ghcr.io/pleri/olam-memory-service:0.1.0 (multi-arch index).
5
+ # To update: resolve the new tag's digest via:
6
+ # TOKEN=$(curl -s "https://ghcr.io/token?scope=repository:pleri/olam-memory-service:pull&service=ghcr.io" | jq -r .token)
7
+ # curl -sI -H "Authorization: Bearer $TOKEN" \
8
+ # -H "Accept: application/vnd.oci.image.index.v1+json,application/vnd.docker.distribution.manifest.list.v2+json" \
9
+ # https://ghcr.io/v2/pleri/olam-memory-service/manifests/<tag> | grep docker-content-digest
10
+ #
11
+ # securityContext: conservative defaults per T6/T7 threat model (runAsNonRoot,
12
+ # readOnlyRootFilesystem). /tmp backed by emptyDir for transient write needs.
13
+ #
14
+ # D15 (LOAD-BEARING): readinessProbe and livenessProbe path MUST be
15
+ # /agentmemory/livez (not /health). Source: DEFAULT_HEALTH_PATH in
16
+ # packages/core/src/services-status/memory-probe.ts:18.
17
+ apiVersion: apps/v1
18
+ kind: Deployment
19
+ metadata:
20
+ name: olam-memory-service
21
+ namespace: olam
22
+ labels:
23
+ app: olam-memory-service
24
+ olam.io/component: peripheral
25
+ spec:
26
+ replicas: 1
27
+ strategy:
28
+ type: RollingUpdate
29
+ rollingUpdate:
30
+ maxSurge: 1
31
+ maxUnavailable: 0
32
+ selector:
33
+ matchLabels:
34
+ app: olam-memory-service
35
+ template:
36
+ metadata:
37
+ labels:
38
+ app: olam-memory-service
39
+ spec:
40
+ serviceAccountName: olam-memory-service
41
+ securityContext:
42
+ runAsNonRoot: true
43
+ runAsUser: 1000
44
+ runAsGroup: 1000
45
+ fsGroup: 1000
46
+ initContainers:
47
+ - name: chown-data
48
+ # busybox:1.36 — sha256-pinned per T4 threat model.
49
+ image: busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662
50
+ imagePullPolicy: IfNotPresent
51
+ securityContext:
52
+ runAsUser: 0
53
+ runAsNonRoot: false
54
+ allowPrivilegeEscalation: false
55
+ command: ["chown", "-R", "1000:1000", "/data"]
56
+ volumeMounts:
57
+ - name: memory-data
58
+ mountPath: /data
59
+ containers:
60
+ - name: olam-memory-service
61
+ image: ghcr.io/pleri/olam-memory-service@sha256:d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5
62
+ imagePullPolicy: IfNotPresent
63
+ securityContext:
64
+ runAsNonRoot: true
65
+ runAsUser: 1000
66
+ readOnlyRootFilesystem: true
67
+ allowPrivilegeEscalation: false
68
+ capabilities:
69
+ drop: ["ALL"]
70
+ ports:
71
+ - name: http
72
+ containerPort: 3111
73
+ protocol: TCP
74
+ envFrom:
75
+ - configMapRef:
76
+ name: olam-memory-service-env
77
+ - secretRef:
78
+ name: olam-memory-service-secret
79
+ volumeMounts:
80
+ - name: memory-data
81
+ mountPath: /data
82
+ - name: tmp
83
+ mountPath: /tmp
84
+ readinessProbe:
85
+ httpGet:
86
+ # D15 (LOAD-BEARING): memory-service health path is /agentmemory/livez.
87
+ # Source: DEFAULT_HEALTH_PATH in packages/core/src/services-status/memory-probe.ts:18.
88
+ # Do NOT change to /health — that endpoint does not exist on this service.
89
+ path: /agentmemory/livez
90
+ port: 3111
91
+ initialDelaySeconds: 5
92
+ periodSeconds: 5
93
+ timeoutSeconds: 3
94
+ failureThreshold: 6
95
+ livenessProbe:
96
+ httpGet:
97
+ # D15 (LOAD-BEARING): same path as readinessProbe.
98
+ path: /agentmemory/livez
99
+ port: 3111
100
+ initialDelaySeconds: 30
101
+ periodSeconds: 20
102
+ timeoutSeconds: 5
103
+ failureThreshold: 3
104
+ resources:
105
+ requests:
106
+ cpu: "50m"
107
+ memory: "256Mi"
108
+ limits:
109
+ cpu: "500m"
110
+ memory: "1Gi"
111
+ volumes:
112
+ - name: memory-data
113
+ persistentVolumeClaim:
114
+ claimName: olam-memory-data
115
+ - name: tmp
116
+ emptyDir: {}
@@ -0,0 +1,21 @@
1
+ # ClusterIP Service for olam-memory-service.
2
+ # Port 3111 — consumed by host-cp and agents via cluster-internal DNS.
3
+ # Operator surfaces externally via:
4
+ # kubectl port-forward -n olam svc/olam-memory-service 3111:3111
5
+ apiVersion: v1
6
+ kind: Service
7
+ metadata:
8
+ name: olam-memory-service
9
+ namespace: olam
10
+ labels:
11
+ app: olam-memory-service
12
+ olam.io/component: peripheral
13
+ spec:
14
+ type: ClusterIP
15
+ selector:
16
+ app: olam-memory-service
17
+ ports:
18
+ - name: http
19
+ port: 3111
20
+ targetPort: 3111
21
+ protocol: TCP