@pleri/olam-cli 0.1.186 → 0.1.188
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.
- package/dist/ask/knowledge-pack-builder.d.ts.map +1 -1
- package/dist/ask/knowledge-pack-builder.js +5 -0
- package/dist/ask/knowledge-pack-builder.js.map +1 -1
- package/dist/ask/knowledge-pack.generated.d.ts.map +1 -1
- package/dist/ask/knowledge-pack.generated.js +406 -22
- package/dist/ask/knowledge-pack.generated.js.map +1 -1
- package/dist/commands/auth-status.js +2 -2
- package/dist/commands/auth-status.js.map +1 -1
- package/dist/commands/auth.js +1 -1
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +4 -0
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/install.js +2 -2
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/services.d.ts.map +1 -1
- package/dist/commands/services.js +12 -0
- package/dist/commands/services.js.map +1 -1
- package/dist/commands/setup.js +1 -1
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +4 -0
- package/dist/commands/status.js.map +1 -1
- package/dist/image-digests.json +8 -8
- package/dist/index.js +788 -368
- package/dist/lib/health-probes.d.ts +14 -0
- package/dist/lib/health-probes.d.ts.map +1 -1
- package/dist/lib/health-probes.js +41 -3
- package/dist/lib/health-probes.js.map +1 -1
- package/dist/mcp-server.js +95 -27
- package/hermes-bundle/version.json +1 -1
- package/host-cp/k8s/manifests/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/auth-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/chunks-electric/10-serviceaccount.yaml +8 -0
- package/host-cp/k8s/manifests/chunks-electric/20-rbac.yaml +27 -0
- package/host-cp/k8s/manifests/chunks-electric/30-configmap.yaml +23 -0
- package/host-cp/k8s/manifests/chunks-electric/45-pvc.yaml +19 -0
- package/host-cp/k8s/manifests/chunks-electric/50-deployment.yaml +84 -0
- package/host-cp/k8s/manifests/chunks-electric/60-service.yaml +17 -0
- package/host-cp/k8s/manifests/chunks-postgres/10-serviceaccount.yaml +8 -0
- package/host-cp/k8s/manifests/chunks-postgres/20-rbac.yaml +29 -0
- package/host-cp/k8s/manifests/chunks-postgres/30-configmap.yaml +185 -0
- package/host-cp/k8s/manifests/chunks-postgres/45-pvc.yaml +24 -0
- package/host-cp/k8s/manifests/chunks-postgres/50-deployment.yaml +101 -0
- package/host-cp/k8s/manifests/chunks-postgres/60-service.yaml +24 -0
- package/host-cp/k8s/manifests/kg-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/mcp-auth-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/memory-service/50-deployment.yaml +1 -1
- package/host-cp/k8s/manifests/plan-chat-service/10-serviceaccount.yaml +8 -0
- package/host-cp/k8s/manifests/plan-chat-service/20-rbac.yaml +29 -0
- package/host-cp/k8s/manifests/plan-chat-service/30-configmap.yaml +36 -0
- package/host-cp/k8s/manifests/plan-chat-service/45-pvc.yaml +24 -0
- package/host-cp/k8s/manifests/plan-chat-service/50-deployment.yaml +135 -0
- package/host-cp/k8s/manifests/plan-chat-service/60-service.yaml +17 -0
- package/host-cp/src/plan-chat-service.mjs +216 -0
- package/host-cp/src/pr-cache.mjs +11 -2
- package/host-cp/src/server.mjs +36 -20
- package/package.json +1 -1
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# ConfigMap for olam-chunks-postgres.
|
|
2
|
+
#
|
|
3
|
+
# Two ConfigMaps in one file:
|
|
4
|
+
#
|
|
5
|
+
# 1. olam-chunks-postgres-env — non-secret env vars (POSTGRES_USER, POSTGRES_DB).
|
|
6
|
+
# POSTGRES_PASSWORD lives in the Secret rendered by
|
|
7
|
+
# packages/cli/src/lib/k8s-secret-render.ts.
|
|
8
|
+
#
|
|
9
|
+
# 2. olam-chunks-postgres-initdb-sql — the chunks schema. Mounted at
|
|
10
|
+
# /docker-entrypoint-initdb.d/01-chunks.sql so
|
|
11
|
+
# the postgres image's entrypoint auto-applies it
|
|
12
|
+
# on FIRST init (empty data dir). Subsequent
|
|
13
|
+
# restarts skip the directory by design.
|
|
14
|
+
#
|
|
15
|
+
# Source-of-truth: packages/chunks/src/schema.ts
|
|
16
|
+
# (SCHEMA_SQL export). The CI gate
|
|
17
|
+
# `audit:chunks-schema-parity` (follow-up) will
|
|
18
|
+
# fail when this ConfigMap drifts from
|
|
19
|
+
# SCHEMA_VERSION-tagged schema.ts.
|
|
20
|
+
apiVersion: v1
|
|
21
|
+
kind: ConfigMap
|
|
22
|
+
metadata:
|
|
23
|
+
name: olam-chunks-postgres-env
|
|
24
|
+
namespace: olam
|
|
25
|
+
labels:
|
|
26
|
+
app: olam-chunks-postgres
|
|
27
|
+
olam.io/component: substrate
|
|
28
|
+
data:
|
|
29
|
+
POSTGRES_USER: "postgres"
|
|
30
|
+
POSTGRES_DB: "chunks"
|
|
31
|
+
# PGDATA must point at a subdirectory of the PVC mount, not its root —
|
|
32
|
+
# the PVC root may carry the local-path provisioner's lost+found dir,
|
|
33
|
+
# which postgres's initdb rejects ("data directory not empty").
|
|
34
|
+
PGDATA: "/var/lib/postgresql/data/pgdata"
|
|
35
|
+
---
|
|
36
|
+
apiVersion: v1
|
|
37
|
+
kind: ConfigMap
|
|
38
|
+
metadata:
|
|
39
|
+
name: olam-chunks-postgres-initdb-sql
|
|
40
|
+
namespace: olam
|
|
41
|
+
labels:
|
|
42
|
+
app: olam-chunks-postgres
|
|
43
|
+
olam.io/component: substrate
|
|
44
|
+
data:
|
|
45
|
+
# MIRRORS packages/chunks/src/schema.ts SCHEMA_VERSION=2.
|
|
46
|
+
# Idempotent: CREATE TABLE IF NOT EXISTS / ADD COLUMN IF NOT EXISTS /
|
|
47
|
+
# DO blocks with EXCEPTION-WHEN-{undefined_object,duplicate_object}.
|
|
48
|
+
01-chunks.sql: |
|
|
49
|
+
CREATE TABLE IF NOT EXISTS chunks (
|
|
50
|
+
world_id TEXT NOT NULL,
|
|
51
|
+
session_id TEXT NOT NULL,
|
|
52
|
+
message_id TEXT NOT NULL,
|
|
53
|
+
seq INTEGER NOT NULL,
|
|
54
|
+
actor_id TEXT NOT NULL,
|
|
55
|
+
actor_type TEXT NOT NULL CHECK (actor_type IN ('agent', 'operator', 'codex', 'system')),
|
|
56
|
+
role TEXT NOT NULL CHECK (role IN ('user', 'assistant', 'tool', 'system')),
|
|
57
|
+
chunk TEXT NOT NULL,
|
|
58
|
+
chunk_type TEXT NOT NULL DEFAULT 'text' CHECK (chunk_type IN ('text', 'tool_use', 'goal_mode_assumption', 'dispatch_overflow')),
|
|
59
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT clock_timestamp(),
|
|
60
|
+
PRIMARY KEY (message_id, seq)
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
ALTER TABLE chunks ADD COLUMN IF NOT EXISTS chunk_type TEXT NOT NULL DEFAULT 'text';
|
|
64
|
+
|
|
65
|
+
DO $$ BEGIN
|
|
66
|
+
ALTER TABLE chunks DROP CONSTRAINT IF EXISTS chunks_chunk_type_check;
|
|
67
|
+
EXCEPTION WHEN undefined_object THEN NULL;
|
|
68
|
+
END $$;
|
|
69
|
+
|
|
70
|
+
DO $$ BEGIN
|
|
71
|
+
ALTER TABLE chunks ADD CONSTRAINT chunks_chunk_type_check
|
|
72
|
+
CHECK (chunk_type IN ('text', 'tool_use', 'goal_mode_assumption', 'dispatch_overflow'));
|
|
73
|
+
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
74
|
+
END $$;
|
|
75
|
+
|
|
76
|
+
CREATE INDEX IF NOT EXISTS chunks_world_session_seq
|
|
77
|
+
ON chunks (world_id, session_id, seq);
|
|
78
|
+
|
|
79
|
+
CREATE INDEX IF NOT EXISTS chunks_world_session_created
|
|
80
|
+
ON chunks (world_id, session_id, created_at);
|
|
81
|
+
|
|
82
|
+
CREATE INDEX IF NOT EXISTS idx_chunks_planning
|
|
83
|
+
ON chunks (session_id, seq)
|
|
84
|
+
WHERE world_id = '_planning';
|
|
85
|
+
|
|
86
|
+
CREATE TABLE IF NOT EXISTS planning_sessions (
|
|
87
|
+
session_id TEXT PRIMARY KEY,
|
|
88
|
+
actor_id TEXT NOT NULL,
|
|
89
|
+
summary TEXT,
|
|
90
|
+
crystallize_status TEXT NOT NULL DEFAULT 'open'
|
|
91
|
+
CHECK (crystallize_status IN ('open', 'in_progress', 'crystallized', 'failed', 'abandoned')),
|
|
92
|
+
crystallized_world_id TEXT,
|
|
93
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
94
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
CREATE INDEX IF NOT EXISTS idx_planning_sessions_created_at
|
|
98
|
+
ON planning_sessions (created_at DESC);
|
|
99
|
+
|
|
100
|
+
ALTER TABLE planning_sessions ADD COLUMN IF NOT EXISTS session_source TEXT;
|
|
101
|
+
|
|
102
|
+
CREATE OR REPLACE FUNCTION chunks_append_only_trigger()
|
|
103
|
+
RETURNS trigger AS $body$
|
|
104
|
+
BEGIN
|
|
105
|
+
RAISE EXCEPTION 'chunks is append-only; % forbidden', TG_OP;
|
|
106
|
+
END;
|
|
107
|
+
$body$ LANGUAGE plpgsql;
|
|
108
|
+
|
|
109
|
+
DROP TRIGGER IF EXISTS chunks_no_update ON chunks;
|
|
110
|
+
CREATE TRIGGER chunks_no_update
|
|
111
|
+
BEFORE UPDATE ON chunks
|
|
112
|
+
FOR EACH ROW EXECUTE FUNCTION chunks_append_only_trigger();
|
|
113
|
+
|
|
114
|
+
DROP TRIGGER IF EXISTS chunks_no_delete ON chunks;
|
|
115
|
+
CREATE TRIGGER chunks_no_delete
|
|
116
|
+
BEFORE DELETE ON chunks
|
|
117
|
+
FOR EACH ROW EXECUTE FUNCTION chunks_append_only_trigger();
|
|
118
|
+
|
|
119
|
+
CREATE TABLE IF NOT EXISTS message_usage (
|
|
120
|
+
world_id TEXT NOT NULL,
|
|
121
|
+
session_id TEXT NOT NULL,
|
|
122
|
+
message_id TEXT NOT NULL,
|
|
123
|
+
actor_id TEXT NOT NULL,
|
|
124
|
+
model TEXT NOT NULL,
|
|
125
|
+
input_tokens INTEGER NOT NULL DEFAULT 0,
|
|
126
|
+
output_tokens INTEGER NOT NULL DEFAULT 0,
|
|
127
|
+
cache_read_tokens INTEGER NOT NULL DEFAULT 0,
|
|
128
|
+
cache_create_tokens INTEGER NOT NULL DEFAULT 0,
|
|
129
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT clock_timestamp(),
|
|
130
|
+
PRIMARY KEY (message_id, actor_id)
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
CREATE INDEX IF NOT EXISTS message_usage_session_created
|
|
134
|
+
ON message_usage (session_id, created_at);
|
|
135
|
+
|
|
136
|
+
CREATE OR REPLACE FUNCTION message_usage_append_only_trigger()
|
|
137
|
+
RETURNS trigger AS $body$
|
|
138
|
+
BEGIN
|
|
139
|
+
RAISE EXCEPTION 'message_usage is append-only; % forbidden', TG_OP;
|
|
140
|
+
END;
|
|
141
|
+
$body$ LANGUAGE plpgsql;
|
|
142
|
+
|
|
143
|
+
DROP TRIGGER IF EXISTS message_usage_no_update ON message_usage;
|
|
144
|
+
CREATE TRIGGER message_usage_no_update
|
|
145
|
+
BEFORE UPDATE ON message_usage
|
|
146
|
+
FOR EACH ROW EXECUTE FUNCTION message_usage_append_only_trigger();
|
|
147
|
+
|
|
148
|
+
DROP TRIGGER IF EXISTS message_usage_no_delete ON message_usage;
|
|
149
|
+
CREATE TRIGGER message_usage_no_delete
|
|
150
|
+
BEFORE DELETE ON message_usage
|
|
151
|
+
FOR EACH ROW EXECUTE FUNCTION message_usage_append_only_trigger();
|
|
152
|
+
|
|
153
|
+
CREATE TABLE IF NOT EXISTS planning_artifacts (
|
|
154
|
+
id TEXT PRIMARY KEY,
|
|
155
|
+
world_id TEXT NOT NULL,
|
|
156
|
+
session_id TEXT NOT NULL,
|
|
157
|
+
type TEXT NOT NULL CHECK (type IN ('commit_plan', 'component_scaffold', 'design_jam')),
|
|
158
|
+
title TEXT NOT NULL,
|
|
159
|
+
body JSONB NOT NULL,
|
|
160
|
+
status TEXT NOT NULL DEFAULT 'open'
|
|
161
|
+
CHECK (status IN ('open', 'crystallized', 'failed', 'archived')),
|
|
162
|
+
linear_issue_url TEXT,
|
|
163
|
+
crystallized_world_id TEXT,
|
|
164
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
165
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
CREATE INDEX IF NOT EXISTS idx_planning_artifacts_session
|
|
169
|
+
ON planning_artifacts (session_id, created_at);
|
|
170
|
+
|
|
171
|
+
CREATE INDEX IF NOT EXISTS idx_planning_artifacts_world
|
|
172
|
+
ON planning_artifacts (world_id, status);
|
|
173
|
+
|
|
174
|
+
CREATE OR REPLACE FUNCTION planning_artifacts_touch_updated_at()
|
|
175
|
+
RETURNS trigger AS $body$
|
|
176
|
+
BEGIN
|
|
177
|
+
NEW.updated_at = NOW();
|
|
178
|
+
RETURN NEW;
|
|
179
|
+
END;
|
|
180
|
+
$body$ LANGUAGE plpgsql;
|
|
181
|
+
|
|
182
|
+
DROP TRIGGER IF EXISTS planning_artifacts_touch ON planning_artifacts;
|
|
183
|
+
CREATE TRIGGER planning_artifacts_touch
|
|
184
|
+
BEFORE UPDATE ON planning_artifacts
|
|
185
|
+
FOR EACH ROW EXECUTE FUNCTION planning_artifacts_touch_updated_at();
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# PVC for the chunks-postgres data directory.
|
|
2
|
+
#
|
|
3
|
+
# Sized 10Gi for local-dev. Chunks rows are small (~1KB each) so even a
|
|
4
|
+
# busy single-operator world rarely cracks 1Gi; the headroom is for the
|
|
5
|
+
# message_usage + planning_artifacts sidecar tables.
|
|
6
|
+
#
|
|
7
|
+
# accessModes: ReadWriteOnce — postgres is a StatefulSet with replicas=1.
|
|
8
|
+
# k3d's local-path provisioner only supports RWO; the in-cluster postgres
|
|
9
|
+
# pattern is single-writer by design (no operator-managed HA).
|
|
10
|
+
apiVersion: v1
|
|
11
|
+
kind: PersistentVolumeClaim
|
|
12
|
+
metadata:
|
|
13
|
+
name: olam-chunks-postgres-data
|
|
14
|
+
namespace: olam
|
|
15
|
+
labels:
|
|
16
|
+
app: olam-chunks-postgres
|
|
17
|
+
olam.io/component: substrate
|
|
18
|
+
spec:
|
|
19
|
+
accessModes:
|
|
20
|
+
- ReadWriteOnce
|
|
21
|
+
storageClassName: local-path
|
|
22
|
+
resources:
|
|
23
|
+
requests:
|
|
24
|
+
storage: 10Gi
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# StatefulSet for olam-chunks-postgres.
|
|
2
|
+
#
|
|
3
|
+
# Why StatefulSet vs Deployment: even with replicas=1 the StatefulSet gives
|
|
4
|
+
# stable network identity (olam-chunks-postgres-0 inside the headless service)
|
|
5
|
+
# and ordered termination semantics — both useful when Electric's replication
|
|
6
|
+
# slot survives pod restarts.
|
|
7
|
+
#
|
|
8
|
+
# command override: postgres requires wal_level=logical for Electric SQL's
|
|
9
|
+
# logical-replication subscription. The image's default postgresql.conf
|
|
10
|
+
# ships wal_level=replica; the -c overrides on the entrypoint args take
|
|
11
|
+
# precedence. max_replication_slots / max_wal_senders need raising too —
|
|
12
|
+
# Electric holds one slot per database.
|
|
13
|
+
#
|
|
14
|
+
# securityContext: postgres image runs as uid 999 by default. fsGroup=999
|
|
15
|
+
# on the pod ensures the PVC mount is chowned to 999 so postgres can write
|
|
16
|
+
# its data dir.
|
|
17
|
+
apiVersion: apps/v1
|
|
18
|
+
kind: StatefulSet
|
|
19
|
+
metadata:
|
|
20
|
+
name: olam-chunks-postgres
|
|
21
|
+
namespace: olam
|
|
22
|
+
labels:
|
|
23
|
+
app: olam-chunks-postgres
|
|
24
|
+
olam.io/component: substrate
|
|
25
|
+
spec:
|
|
26
|
+
replicas: 1
|
|
27
|
+
serviceName: olam-chunks-postgres
|
|
28
|
+
selector:
|
|
29
|
+
matchLabels:
|
|
30
|
+
app: olam-chunks-postgres
|
|
31
|
+
template:
|
|
32
|
+
metadata:
|
|
33
|
+
labels:
|
|
34
|
+
app: olam-chunks-postgres
|
|
35
|
+
spec:
|
|
36
|
+
enableServiceLinks: false
|
|
37
|
+
serviceAccountName: olam-chunks-postgres
|
|
38
|
+
securityContext:
|
|
39
|
+
fsGroup: 999
|
|
40
|
+
containers:
|
|
41
|
+
- name: postgres
|
|
42
|
+
# postgres:16-alpine — sha256-pinned per T4 threat model.
|
|
43
|
+
image: postgres:16-alpine@sha256:16bc17c64a573ef34162af9298258d1aec548232985b33ed7b1eac33ba35c229
|
|
44
|
+
imagePullPolicy: IfNotPresent
|
|
45
|
+
args:
|
|
46
|
+
- postgres
|
|
47
|
+
- -c
|
|
48
|
+
- wal_level=logical
|
|
49
|
+
- -c
|
|
50
|
+
- max_replication_slots=10
|
|
51
|
+
- -c
|
|
52
|
+
- max_wal_senders=10
|
|
53
|
+
ports:
|
|
54
|
+
- name: postgres
|
|
55
|
+
containerPort: 5432
|
|
56
|
+
protocol: TCP
|
|
57
|
+
envFrom:
|
|
58
|
+
- configMapRef:
|
|
59
|
+
name: olam-chunks-postgres-env
|
|
60
|
+
- secretRef:
|
|
61
|
+
name: olam-chunks-postgres-secret
|
|
62
|
+
volumeMounts:
|
|
63
|
+
- name: data
|
|
64
|
+
mountPath: /var/lib/postgresql/data
|
|
65
|
+
- name: initdb
|
|
66
|
+
mountPath: /docker-entrypoint-initdb.d
|
|
67
|
+
readOnly: true
|
|
68
|
+
readinessProbe:
|
|
69
|
+
exec:
|
|
70
|
+
command:
|
|
71
|
+
- sh
|
|
72
|
+
- -c
|
|
73
|
+
- pg_isready -U postgres -d chunks -h 127.0.0.1
|
|
74
|
+
initialDelaySeconds: 5
|
|
75
|
+
periodSeconds: 5
|
|
76
|
+
timeoutSeconds: 3
|
|
77
|
+
failureThreshold: 12
|
|
78
|
+
livenessProbe:
|
|
79
|
+
exec:
|
|
80
|
+
command:
|
|
81
|
+
- sh
|
|
82
|
+
- -c
|
|
83
|
+
- pg_isready -U postgres -h 127.0.0.1
|
|
84
|
+
initialDelaySeconds: 30
|
|
85
|
+
periodSeconds: 20
|
|
86
|
+
timeoutSeconds: 5
|
|
87
|
+
failureThreshold: 3
|
|
88
|
+
resources:
|
|
89
|
+
requests:
|
|
90
|
+
cpu: "100m"
|
|
91
|
+
memory: "256Mi"
|
|
92
|
+
limits:
|
|
93
|
+
cpu: "1000m"
|
|
94
|
+
memory: "1Gi"
|
|
95
|
+
volumes:
|
|
96
|
+
- name: data
|
|
97
|
+
persistentVolumeClaim:
|
|
98
|
+
claimName: olam-chunks-postgres-data
|
|
99
|
+
- name: initdb
|
|
100
|
+
configMap:
|
|
101
|
+
name: olam-chunks-postgres-initdb-sql
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Headless Service for olam-chunks-postgres StatefulSet.
|
|
2
|
+
#
|
|
3
|
+
# clusterIP: None gives the StatefulSet's pod stable DNS:
|
|
4
|
+
# olam-chunks-postgres-0.olam-chunks-postgres.olam.svc.cluster.local
|
|
5
|
+
# Callers (plan-chat-service, chunks-electric) connect via the shorter
|
|
6
|
+
# olam-chunks-postgres.olam.svc.cluster.local form which Kubernetes resolves
|
|
7
|
+
# round-robin to the single backing pod.
|
|
8
|
+
apiVersion: v1
|
|
9
|
+
kind: Service
|
|
10
|
+
metadata:
|
|
11
|
+
name: olam-chunks-postgres
|
|
12
|
+
namespace: olam
|
|
13
|
+
labels:
|
|
14
|
+
app: olam-chunks-postgres
|
|
15
|
+
olam.io/component: substrate
|
|
16
|
+
spec:
|
|
17
|
+
clusterIP: None
|
|
18
|
+
selector:
|
|
19
|
+
app: olam-chunks-postgres
|
|
20
|
+
ports:
|
|
21
|
+
- name: postgres
|
|
22
|
+
port: 5432
|
|
23
|
+
targetPort: 5432
|
|
24
|
+
protocol: TCP
|
|
@@ -61,7 +61,7 @@ spec:
|
|
|
61
61
|
mountPath: /data
|
|
62
62
|
containers:
|
|
63
63
|
- name: olam-kg-service
|
|
64
|
-
image: ghcr.io/pleri/olam-kg-service@sha256:
|
|
64
|
+
image: ghcr.io/pleri/olam-kg-service@sha256:c9a0226339907711443657e2ca1eb40d2e2df120562dbb5d7d0ddf628614fb74
|
|
65
65
|
imagePullPolicy: IfNotPresent
|
|
66
66
|
securityContext:
|
|
67
67
|
runAsNonRoot: true
|
|
@@ -68,7 +68,7 @@ spec:
|
|
|
68
68
|
mountPath: /data
|
|
69
69
|
containers:
|
|
70
70
|
- name: olam-mcp-auth-service
|
|
71
|
-
image: ghcr.io/pleri/olam-mcp-auth@sha256:
|
|
71
|
+
image: ghcr.io/pleri/olam-mcp-auth@sha256:eba57d0c5c89763bc266faba80e98912875f541c9ad8e96ee5f28790f9fb96d8
|
|
72
72
|
imagePullPolicy: IfNotPresent
|
|
73
73
|
securityContext:
|
|
74
74
|
runAsNonRoot: true
|
|
@@ -70,7 +70,7 @@ spec:
|
|
|
70
70
|
# bootstrap-placeholder comment + run `npm run refresh:manifest-digests`
|
|
71
71
|
# once ghcr.io/pleri/olam-memory-service has a real published digest.
|
|
72
72
|
# bootstrap-placeholder: pre-publish; refresh after first release
|
|
73
|
-
image: ghcr.io/pleri/olam-memory-service@sha256:
|
|
73
|
+
image: ghcr.io/pleri/olam-memory-service@sha256:33390ba1b2b4785ebf9af9732c42c40ae572ec1176e01f1fed8225d0d449ca57
|
|
74
74
|
imagePullPolicy: IfNotPresent
|
|
75
75
|
securityContext:
|
|
76
76
|
runAsNonRoot: true
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# plan-chat-service does not need to read or write any Kubernetes API objects.
|
|
2
|
+
# A no-op Role + RoleBinding documents the minimal-privilege stance and
|
|
3
|
+
# keeps the file present so audit:cli-bundle-k8s does not skip this peripheral.
|
|
4
|
+
apiVersion: rbac.authorization.k8s.io/v1
|
|
5
|
+
kind: Role
|
|
6
|
+
metadata:
|
|
7
|
+
name: olam-plan-chat-service
|
|
8
|
+
namespace: olam
|
|
9
|
+
labels:
|
|
10
|
+
app: olam-plan-chat-service
|
|
11
|
+
olam.io/component: peripheral
|
|
12
|
+
rules: []
|
|
13
|
+
---
|
|
14
|
+
apiVersion: rbac.authorization.k8s.io/v1
|
|
15
|
+
kind: RoleBinding
|
|
16
|
+
metadata:
|
|
17
|
+
name: olam-plan-chat-service
|
|
18
|
+
namespace: olam
|
|
19
|
+
labels:
|
|
20
|
+
app: olam-plan-chat-service
|
|
21
|
+
olam.io/component: peripheral
|
|
22
|
+
roleRef:
|
|
23
|
+
apiGroup: rbac.authorization.k8s.io
|
|
24
|
+
kind: Role
|
|
25
|
+
name: olam-plan-chat-service
|
|
26
|
+
subjects:
|
|
27
|
+
- kind: ServiceAccount
|
|
28
|
+
name: olam-plan-chat-service
|
|
29
|
+
namespace: olam
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# ConfigMap for olam-plan-chat-service.
|
|
2
|
+
#
|
|
3
|
+
# plan-chat-service.mjs (packages/host-cp/src/plan-chat-service.mjs) reads
|
|
4
|
+
# these env vars at startup. See the file header for the canonical names.
|
|
5
|
+
#
|
|
6
|
+
# DATABASE_URL: points at the in-cluster chunks-postgres StatefulSet's Service.
|
|
7
|
+
# The password is sourced from the chunks-postgres-secret
|
|
8
|
+
# (mounted via envFrom in 50-deployment.yaml) — the literal
|
|
9
|
+
# here uses the env-var substitution syntax
|
|
10
|
+
# `$(VAR)` which kubelet expands when DATABASE_URL is itself
|
|
11
|
+
# read via envFrom or env: subordinate.
|
|
12
|
+
#
|
|
13
|
+
# BUT: kubelet only expands env-refs declared on the container,
|
|
14
|
+
# not values inside a ConfigMap key. So we keep DATABASE_URL
|
|
15
|
+
# OUT of this ConfigMap and assemble it in the Deployment's
|
|
16
|
+
# env: section instead (which CAN reference the Secret-backed
|
|
17
|
+
# POSTGRES_PASSWORD via $(POSTGRES_PASSWORD)). See 50-deployment.yaml.
|
|
18
|
+
#
|
|
19
|
+
# ELECTRIC_URL: chunks-electric ClusterIP. No auth (ELECTRIC_INSECURE=true on
|
|
20
|
+
# that service in local-dev mode).
|
|
21
|
+
#
|
|
22
|
+
# SECRET_PATH: filesystem path where the olam-plan-chat-secret Secret is
|
|
23
|
+
# mounted (see volumeMounts in 50-deployment.yaml). The mount
|
|
24
|
+
# key is "secret" → file `/etc/olam-plan-chat/secret`.
|
|
25
|
+
apiVersion: v1
|
|
26
|
+
kind: ConfigMap
|
|
27
|
+
metadata:
|
|
28
|
+
name: olam-plan-chat-service-env
|
|
29
|
+
namespace: olam
|
|
30
|
+
labels:
|
|
31
|
+
app: olam-plan-chat-service
|
|
32
|
+
olam.io/component: peripheral
|
|
33
|
+
data:
|
|
34
|
+
OLAM_PLAN_CHAT_PORT: "3200"
|
|
35
|
+
OLAM_PLAN_CHAT_ELECTRIC_URL: "http://olam-chunks-electric.olam.svc.cluster.local:3000"
|
|
36
|
+
OLAM_PLAN_CHAT_SECRET_PATH: "/etc/olam-plan-chat/secret"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# PersistentVolumeClaim for olam-plan-chat-service /data volume.
|
|
2
|
+
#
|
|
3
|
+
# plan-chat-service is mostly stateless (DB lives in chunks-postgres, secret
|
|
4
|
+
# lives in olam-plan-chat-secret), but ships a /data PVC for parity with
|
|
5
|
+
# the other peripherals. Used for any transient state the service decides
|
|
6
|
+
# to spool (e.g. planning-session resumption buffers).
|
|
7
|
+
#
|
|
8
|
+
# local-path StorageClass ships with k3d by default. On non-k3d clusters,
|
|
9
|
+
# substitute storageClassName with your cluster's provisioner.
|
|
10
|
+
apiVersion: v1
|
|
11
|
+
kind: PersistentVolumeClaim
|
|
12
|
+
metadata:
|
|
13
|
+
name: olam-plan-chat-service-data
|
|
14
|
+
namespace: olam
|
|
15
|
+
labels:
|
|
16
|
+
app: olam-plan-chat-service
|
|
17
|
+
olam.io/component: peripheral
|
|
18
|
+
spec:
|
|
19
|
+
accessModes:
|
|
20
|
+
- ReadWriteOnce
|
|
21
|
+
storageClassName: local-path
|
|
22
|
+
resources:
|
|
23
|
+
requests:
|
|
24
|
+
storage: 1Gi
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Deployment for olam-plan-chat-service.
|
|
2
|
+
#
|
|
3
|
+
# Image strategy: REUSES the olam-host-cp image. Per the package layout,
|
|
4
|
+
# plan-chat-service.mjs is a sibling under packages/host-cp/src/, and the
|
|
5
|
+
# host-cp image's WORKDIR=/app already contains it at /app/src/plan-chat-service.mjs.
|
|
6
|
+
# The single shared image avoids version-drift between the two binaries that
|
|
7
|
+
# share plan-chat-secret.mjs (bearer-auth logic), planning-sessions.mjs,
|
|
8
|
+
# crystallize-planning.mjs, and resolver.mjs.
|
|
9
|
+
#
|
|
10
|
+
# The command override replaces the host-cp default
|
|
11
|
+
# ENTRYPOINT (`node src/server.mjs`) with the plan-chat-service entrypoint.
|
|
12
|
+
#
|
|
13
|
+
# Image: pinned to the SAME digest as host-cp's 50-deployment.yaml. Refresh
|
|
14
|
+
# both in lockstep via scripts/refresh-manifest-digests.mjs on every release.
|
|
15
|
+
apiVersion: apps/v1
|
|
16
|
+
kind: Deployment
|
|
17
|
+
metadata:
|
|
18
|
+
name: olam-plan-chat-service
|
|
19
|
+
namespace: olam
|
|
20
|
+
labels:
|
|
21
|
+
app: olam-plan-chat-service
|
|
22
|
+
olam.io/component: peripheral
|
|
23
|
+
spec:
|
|
24
|
+
replicas: 1
|
|
25
|
+
strategy:
|
|
26
|
+
type: RollingUpdate
|
|
27
|
+
rollingUpdate:
|
|
28
|
+
maxSurge: 1
|
|
29
|
+
maxUnavailable: 0
|
|
30
|
+
selector:
|
|
31
|
+
matchLabels:
|
|
32
|
+
app: olam-plan-chat-service
|
|
33
|
+
template:
|
|
34
|
+
metadata:
|
|
35
|
+
labels:
|
|
36
|
+
app: olam-plan-chat-service
|
|
37
|
+
spec:
|
|
38
|
+
enableServiceLinks: false
|
|
39
|
+
imagePullSecrets:
|
|
40
|
+
- name: ghcr-pull
|
|
41
|
+
serviceAccountName: olam-plan-chat-service
|
|
42
|
+
securityContext:
|
|
43
|
+
runAsNonRoot: true
|
|
44
|
+
runAsUser: 1000
|
|
45
|
+
runAsGroup: 1000
|
|
46
|
+
fsGroup: 1000
|
|
47
|
+
initContainers:
|
|
48
|
+
# chown-data: identical to memory-service pattern. Postgres-RWO PVC
|
|
49
|
+
# mounts as root-owned on local-path; this brings it to 1000:1000.
|
|
50
|
+
- name: chown-data
|
|
51
|
+
image: busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662
|
|
52
|
+
imagePullPolicy: IfNotPresent
|
|
53
|
+
securityContext:
|
|
54
|
+
runAsUser: 0
|
|
55
|
+
runAsNonRoot: false
|
|
56
|
+
allowPrivilegeEscalation: false
|
|
57
|
+
command: ["chown", "-R", "1000:1000", "/data"]
|
|
58
|
+
volumeMounts:
|
|
59
|
+
- name: plan-chat-data
|
|
60
|
+
mountPath: /data
|
|
61
|
+
containers:
|
|
62
|
+
- name: olam-plan-chat-service
|
|
63
|
+
# Reuses the host-cp image (same source tree, same node_modules).
|
|
64
|
+
# Digest pinned in lockstep with packages/host-cp/k8s/manifests/50-deployment.yaml.
|
|
65
|
+
image: ghcr.io/pleri/olam-host-cp@sha256:20d84b6d490c633bc5a158b0f7f849152aba3cf1d2d45657360f627d8d41ec3f
|
|
66
|
+
imagePullPolicy: IfNotPresent
|
|
67
|
+
# Override the host-cp ENTRYPOINT. plan-chat-service.mjs exports
|
|
68
|
+
# startService(); we boot it via -e import-and-call.
|
|
69
|
+
command: ["node"]
|
|
70
|
+
args:
|
|
71
|
+
- "-e"
|
|
72
|
+
- "import('/app/src/plan-chat-service.mjs').then(m => m.startService()).catch(e => { console.error('[plan-chat-service]', e); process.exit(1); });"
|
|
73
|
+
workingDir: /app
|
|
74
|
+
securityContext:
|
|
75
|
+
runAsNonRoot: true
|
|
76
|
+
runAsUser: 1000
|
|
77
|
+
allowPrivilegeEscalation: false
|
|
78
|
+
capabilities:
|
|
79
|
+
drop: ["ALL"]
|
|
80
|
+
ports:
|
|
81
|
+
- name: http
|
|
82
|
+
containerPort: 3200
|
|
83
|
+
protocol: TCP
|
|
84
|
+
envFrom:
|
|
85
|
+
- configMapRef:
|
|
86
|
+
name: olam-plan-chat-service-env
|
|
87
|
+
env:
|
|
88
|
+
# DATABASE_URL composition. Same pattern as chunks-electric.
|
|
89
|
+
- name: POSTGRES_PASSWORD
|
|
90
|
+
valueFrom:
|
|
91
|
+
secretKeyRef:
|
|
92
|
+
name: olam-chunks-postgres-secret
|
|
93
|
+
key: POSTGRES_PASSWORD
|
|
94
|
+
- name: OLAM_PLAN_CHAT_DATABASE_URL
|
|
95
|
+
value: "postgres://postgres:$(POSTGRES_PASSWORD)@olam-chunks-postgres.olam.svc.cluster.local:5432/chunks"
|
|
96
|
+
volumeMounts:
|
|
97
|
+
- name: plan-chat-data
|
|
98
|
+
mountPath: /data
|
|
99
|
+
- name: plan-chat-secret
|
|
100
|
+
mountPath: /etc/olam-plan-chat
|
|
101
|
+
readOnly: true
|
|
102
|
+
readinessProbe:
|
|
103
|
+
httpGet:
|
|
104
|
+
path: /livez
|
|
105
|
+
port: 3200
|
|
106
|
+
initialDelaySeconds: 10
|
|
107
|
+
periodSeconds: 5
|
|
108
|
+
timeoutSeconds: 3
|
|
109
|
+
failureThreshold: 12
|
|
110
|
+
livenessProbe:
|
|
111
|
+
httpGet:
|
|
112
|
+
path: /livez
|
|
113
|
+
port: 3200
|
|
114
|
+
initialDelaySeconds: 60
|
|
115
|
+
periodSeconds: 20
|
|
116
|
+
timeoutSeconds: 5
|
|
117
|
+
failureThreshold: 3
|
|
118
|
+
resources:
|
|
119
|
+
requests:
|
|
120
|
+
cpu: "50m"
|
|
121
|
+
memory: "256Mi"
|
|
122
|
+
limits:
|
|
123
|
+
cpu: "500m"
|
|
124
|
+
memory: "1Gi"
|
|
125
|
+
volumes:
|
|
126
|
+
- name: plan-chat-data
|
|
127
|
+
persistentVolumeClaim:
|
|
128
|
+
claimName: olam-plan-chat-service-data
|
|
129
|
+
- name: plan-chat-secret
|
|
130
|
+
secret:
|
|
131
|
+
secretName: olam-plan-chat-secret
|
|
132
|
+
defaultMode: 0400
|
|
133
|
+
items:
|
|
134
|
+
- key: PLAN_CHAT_SECRET
|
|
135
|
+
path: secret
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
apiVersion: v1
|
|
2
|
+
kind: Service
|
|
3
|
+
metadata:
|
|
4
|
+
name: olam-plan-chat-service
|
|
5
|
+
namespace: olam
|
|
6
|
+
labels:
|
|
7
|
+
app: olam-plan-chat-service
|
|
8
|
+
olam.io/component: peripheral
|
|
9
|
+
spec:
|
|
10
|
+
type: ClusterIP
|
|
11
|
+
selector:
|
|
12
|
+
app: olam-plan-chat-service
|
|
13
|
+
ports:
|
|
14
|
+
- name: http
|
|
15
|
+
port: 3200
|
|
16
|
+
targetPort: 3200
|
|
17
|
+
protocol: TCP
|