Files
poimen-memory/tasks/M6.1-agent-manager-db-manifest.md
T

123 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# M6.1 — CNPG `agent-manager-db` manifest
| Field | Value |
|---|---|
| Phase | M6 — agent-manager migration |
| Size | M — 13 days |
| Status | ⬜ Not started |
| Flags | homelab |
| Spec | inlined below |
| Blocks | — |
## Goal
A dedicated Postgres for agent-manager's session store, provisioned the way
everything else in the cluster is: through git, with no manual `psql`. Same
pattern this project already used for `memory-db` (M2.2), applied to a
different, unrelated app.
## Facts (inlined — no spec read needed)
**agent-manager is a separate repo**, not part of this Rust workspace:
`github.com/Riotpiaole/agent-manager` (fork of `github.com/YoanWai/
agent-manager`), local checkout `~/workplace/agent-manager`, branch
`add-headless-spawn`. Its session store is `internal/store/store.go` — see
M6.2/M6.3 for the schema and query port.
**Existing CNPG pattern, verified on the live cluster: 3 Clusters today, one
per app, each ClusterIP-only (not LAN-reachable):**
| namespace/name | app |
|---|---|
| `cicd/forgejo-db` | Forgejo |
| `iam/authentik-db` | Authentik |
| `temporal/temporal-db` | Temporal |
**No shared/multi-tenant DB cluster** — every app gets its own dedicated
CNPG `Cluster`. `agent-manager-db` follows the same rule; it does not join
`memory-db` (M2.2's cluster) even though both are new Postgres instances
touched by the same person around the same time. Different app, different
cluster.
Follow `k8s/infra/databases/temporal-db.yaml` exactly, same as M2.2 did:
`imageName` pinned, `enableSuperuserAccess: false`, `storageClass:
longhorn-cnpg`, `enablePodMonitor: true`, control-plane tolerations,
`podAntiAffinityType: preferred`.
**Instance count — open question, default to convention.** Motivation for
this whole migration is durability-of-location, not HA (single-machine
usage, not a multi-host shared-session requirement). The 3 existing
clusters are all 3-instance. Default to 3 instances for consistency with
every other app in the cluster rather than special-casing this one to 1;
revisit only if resource pressure on the homelab nodes makes it a real
tradeoff.
Storage: session rows are tiny (`sessions`, `groups`, `settings`,
`review_*` — no blobs beyond a `snapshot TEXT` pane capture per session).
1Gi is generous; no need for `memory-db`'s 10Gi (that one holds
768-dim vectors).
## Steps
1. `k8s/infra/databases/agent-manager-db.yaml``Cluster` + `Database`,
namespace `agent-manager`, no extensions (plain relational, no
pgvector).
2. Namespace `agent-manager`, created by the ArgoCD app that owns it.
3. Add to the owning kustomization's explicit resource list — an unlisted
file is silently dropped with no error and no drift shown (the M2.2
task file names this exact trap).
4. Commit, push to **both** Forgejo origin and the GitHub mirror — verify
which `repoURL` the eventual ArgoCD `Application` for this app actually
watches before assuming either push is the one that matters (`kong`
app, for example, tracks the GitHub mirror specifically, not Forgejo).
5. Let ArgoCD sync. **No `kubectl apply`.**
6. Verify the app user can create tables (schema arrives in M6.2, but a
throwaway `CREATE TABLE t(id text); DROP TABLE t;` proves connectivity
here).
## Acceptance
- `Cluster` reaches `Cluster in healthy state`.
- ArgoCD shows the app `Synced/Healthy`.
- No manual `psql` was run to get there.
- Service is ClusterIP-only — not reachable from the LAN directly (M6.4's
nginx route is the only path in).
## Verify
**Harness:** `kubectl` and `psql` read-only checks after sync.
**Integration test**`verify/m6.1.sh`, output diffed against
`expected/m6.1.txt`:
1. `a1_cluster_healthy` — `kubectl get cluster -n agent-manager
agent-manager-db` reports all instances ready.
2. `a2_clusterip_only` — `kubectl get svc -n agent-manager -o
jsonpath='{.items[*].spec.type}'` contains no `LoadBalancer` or
`NodePort`.
3. `a3_argocd_synced` — the owning app is `Synced/Healthy`.
4. `a4_app_user_can_ddl` — as `app`, `CREATE TABLE t(id text); DROP TABLE
t;` succeeds.
5. `a5_no_lan_route_yet` — connection attempt from outside the cluster
network fails at this point in the plan (M6.4 hasn't landed).
**Command:** `bash verify/m6.1.sh | diff - expected/m6.1.txt`
**False pass:**
- Confirming sync without checking service type. A `Cluster` can be
healthy and `Synced` while someone fat-fingered a `LoadBalancer` type
into the manifest, silently violating the "dedicated ingress, not raw
LAN IP" network-path decision this whole migration made. Assertion 2 is
the guard.
## Traps
- Forgetting the kustomization resource list (same trap M2.2 already
named) — file sits in git, ArgoCD reports Synced, objects never exist.
- Adding `prune: true` without accounting for CNPG-operator-created
children (Services, Secrets, PVCs). M2.2's Traps section already hit
this on `llm-serving`; same fix applies here (`prune: false`).
---
Background: `k8s/infra/databases/temporal-db.yaml` · [M2.2](M2.2-memory-db-manifest.md) (same pattern, different app)