Files
krow_backend/infrastructure
Suriyakumarvijayanayagam 109fc2f1c6
Some checks failed
CI / test (push) Has been cancelled
CI / fixture (push) Has been cancelled
Add the in-cluster embedder, so production retrieval stops being keyword-only
Production had no EMBED_PROVIDER, so every knowledge_chunk carried a null
embedding and a question only matched documents that shared its words. A person
asking about a family emergency got nothing from a document titled "shift cover
and cancellation".

Ollama rather than Voyage: internal/knowledge/embed.go calls it "the default
worth reaching for" — real semantics, no credential, no per-token cost, and no
tenant text leaving the cluster. Voyage needs an API key nobody has issued.

Bounded deliberately. The API pods share this node, so an unbounded model
server is a way to evict them; the memory limit means the kubelet kills the
embedder and nothing else. The 1Gi request is also what keeps it off the second
node, which has 1.2Gi allocatable and could not hold it.

Applied in three stages so nothing was pointed at an embedder that had not
been proven: deploy and pull the model, run reembed with the settings passed as
exec environment — 34 chunks in 11s, which proves connectivity without touching
live config — and only then patch krow-config and restart. Rolling back is
removing four keys and restarting.

Verified after: 55/55 on verify-deploy, and a question with no literal keyword
overlap with the corpus returned the relevant policy documents.

This file is the record of what was applied. It was applied by hand, which is
the same gap the README already admits for migrations — there is no deploy
pipeline, so a manifest in the repository is a description of the cluster
rather than the thing that produces it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJvibeSc1JYXjatankqM1g
2026-08-29 15:33:59 +05:30
..
2026-08-28 12:21:44 +05:30
2026-08-25 16:37:05 +05:30

infrastructure

Deployment and local-environment definitions.

Empty in Phase 1, on purpose. The Phase 1 scope is the Go module, the database connection and the initial migration, run against a PostgreSQL 18.6 instance that already exists on the developer's machine. Nothing here is needed to get make migrate-up && make run working.

What lands here in later phases, once each is actually approved:

File Phase Contents
docker-compose.dev.yml 2 PostgreSQL + pgvector, so the dev database stops being a machine-local install
docker-compose.dev.yml (extended) later Redis, MinIO — each only when the phase that needs it starts
Dockerfile.api later Multi-stage build for go-api
Dockerfile.owliver later The Python service
otel-collector.yaml later OpenTelemetry collector config

NATS is deliberately absent from that table: it is not part of the target architecture, and nothing here should reintroduce it.

Adding any of these before its phase would be speculative, so the directory holds only this note for now.