Files
template-app/modules/knowledge/README.md
T

51 lines
3.2 KiB
Markdown

# 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 answers `unavailable` with the reason, an index job fails its row with
`vector_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-platform `Knowledge`
client. The service's `document_ref` is the object's pathname inside the project's Blob prefix
and `options.content_sha256` is 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:
1. `knowledge.search` is 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.
2. 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.
3. `knowledge.settings.enableDocumentAi` is a `write` whose use case performs network I/O
(eligibility, quota, the Qdrant probe/link) — impossible inside a Convex mutation; it needs
its own action composition.
4. `knowledge.status` resolves 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.