knowledge
The retrieval module: named collections of the app's documents, an idempotent document-AI
enablement flow (knowledge.settings.enableDocumentAi), durable index/remove jobs, and cited
search over the indexed chunks.
Search backends
The worker binds one of two KnowledgeSearchService adapters per deployment
(KNOWLEDGE_BACKEND, see apps/worker/src/ports.ts):
vectors(default): chunk locally, embed through the AI gateway, store in the bound vector store (KNOWLEDGE_VECTOR_STORE): Qdrant when a service is linked (QDRANT_URL) — the enablement flow links a managed one — or pgvector over the app's own Postgres when chosen explicitly (KNOWLEDGE_VECTOR_STORE=pgvector, on a Postgres that has the extension; the platform's default managed Postgres image does not). With neither, the module binds an unavailable search service: readiness answersunavailablewith the reason, an index job fails its row withvector_store_unavailable, and the migrate job creates no vector table, so a fresh app deploys on any Postgres.platform: the platform's managed documents-index service through the kit-platformKnowledgeclient. The service'sdocument_refis the object's pathname inside the project's Blob prefix andoptions.content_sha256is required. The adapter hashes the job's bytes, resolves that pathname through the files module's scoped storage reference, and maps returned citations back through the same project scope. Foreign or stale references are omitted; public file views still do not expose storage keys.
Why the module is Postgres-only (no Convex profile yet)
module.convex.ts ships a fail-closed Convex binding for a future wiring, but the module is
not registered in the Convex profile (convex/lib/runtime.ts), and the manifest stays
profiles: ["postgres"]. The integration review (2026-10-23) kept it Postgres-only because the
module genuinely cannot run on the Convex runtime today:
knowledge.searchis an effect procedure — every backend leaves the process (the managed service over HTTP, or embeddings through the AI gateway plus a vector store). Convex queries/mutations cannot perform network I/O; effects need an explicit action composition like the files module's action→mutation workflows, and none exists for search.- The index/remove jobs must run where the platform SDKs can leave the process. The Convex
binding fails closed (
… must run through the Convex Node action boundary); unlike documents'documentsActions:process, no composed Node action exists for these jobs yet, so every indexing request on the Convex profile would dispatch straight into the fence. knowledge.settings.enableDocumentAiis awritewhose use case performs network I/O (eligibility, quota, the Qdrant probe/link) — impossible inside a Convex mutation; it needs its own action composition.knowledge.statusresolves the effect search port for the readiness snapshot, which the Convex container does not bind.
Wiring the profile means composing those Node actions first (mirror convex/documentsActions.ts);
registering the module before then would ship a broken search, a broken enablement flow and
always-failing jobs, not a fail-closed gate.