Files
homelab-frontend/tasks/8.8-memory-adapter-core.md
T

65 lines
3.4 KiB
Markdown

# 8.8 — `X-Service: memory` adapter, core resources (GREEN)
Phase: 8 — ServiceAdapter CRD rollout
Stage: RED
Depends on: 8.1, 8.2, 8.3
Design contract: [API_ROUTING_HYBRID_DESIGN.md](../API_ROUTING_HYBRID_DESIGN.md) §6.
Covers only the poimen-memory endpoints confirmed **already built and tested**
(`~/workplace/Poimen/memory/DESIGN.md`'s M3.5 phase): `GET /memory/query`,
`GET /memory/projects`, `GET /memory/projects/{id}/status`, `GET /memory/skills`,
`GET /memory/skills/{name}`, `POST /memory/ingest`. `/memory/context`,
`/memory/projects/{id}/notes` and the git-aware `/memory/nodes/*` endpoints are
**not** in scope here — see [8.9](8.9-memory-adapter-extended.md).
**Hard prerequisite, not optional — do in this order:**
1. `NetworkPolicy` in namespace `poimen` restricting ingress on `poimen-memory` to
the `api` namespace's gateway pod only. Must land before step 2.
2. Remove the `apikey:` middleware from `poimen-memory` itself — separate change
in the `~/workplace/Poimen/memory` repo, out of scope for this repo but a hard
prerequisite for this adapter being safe to expose. Do not apply the CR below
before this lands.
3. Provision `memory:read`/`memory:write` as real Authentik scopes (via 8.7's
`iam` adapter or `core mwinit`-issued tokens).
- [ ] `k8s/serviceadapter-memory.yaml` CR per §6's example, `auth.capability: memory:read`
default, `ingest` method overrides to `memory:write`
- [ ] `responseSchema` on `query` uses 8.3's array-of-object extension:
`type: array, items: { fields: { level: string, sha256: string, text: string, score: number } }`
- [ ] `responseSchema` on `projects` uses the array-of-scalar extension:
`type: array, items: string`
- [ ] `responseSchema` on `skills`/`skills/{name}` marks `generated_from` as
`{type: string, nullable: true}` — the real upstream response sends `null`
for un-derived skills, confirmed in `DESIGN.md`'s example
- [ ] `requestSchema` on `ingest`: `required: ["project", "source", "records"]`,
`ingest_id` optional (`strict: false` — server may compute it if absent)
- [ ] A `memory:read`-scoped token can `GET` `query`/`skill`/`project` and gets 403
on `ingest`; a `memory:write`-scoped token can `POST ingest`
## Verify
```bash
curl -s -H 'Authorization: Bearer <jwt-with-memory:read>' \
https://api.riotpiao.com/ -H 'X-Service: memory' -H 'X-Resource: query' \
-G --data-urlencode 'query=why did requests over 10KB fail' \
--data-urlencode 'project=poimen' --data-urlencode 'level=L1,L2'
# expected: 200, JSON array of {level,sha256,text,score,parents}
curl -s -H 'Authorization: Bearer <jwt-with-memory:read>' \
https://api.riotpiao.com/ -H 'X-Service: memory' -H 'X-Resource: project'
# expected: 200, ["poimen", ...]
curl -s -o /dev/null -w '%{http_code}\n' -X POST \
-H 'Authorization: Bearer <jwt-with-memory:read>' \
https://api.riotpiao.com/ -H 'X-Service: memory' -H 'X-Resource: ingest' -d '{}'
# expected: 403 — memory:read token, ingest needs memory:write
curl -s -X POST -H 'Authorization: Bearer <jwt-with-memory:write>' \
https://api.riotpiao.com/ -H 'X-Service: memory' -H 'X-Resource: ingest' \
-d '{"project":"poimen","source":"agent:uuid","records":[]}'
# expected: 202, {"job_id":"ingest-...","status_url":"..."}
kubectl -n poimen get networkpolicy -o yaml | grep -A5 poimen-memory
# expected: ingress restricted to the api namespace's gateway pod selector only
```