Getting started
Run intelligence locally with fake models, watch a conversation turn into a claim, and swap in a real embedding provider.
Prerequisites
Follow Local development, then:
./localenv up intelligence-api- API: localhost:8108
- Swagger UI: localhost:8108/api-docs
- Database:
postgres://postgres:postgres@localhost:5433/intelligence
Postgres has to have the vector extension available, which is why docker-compose.yml uses the
pgvector image (ADR 0022). ./localenv
takes care of that. Your own Postgres on port 5433 will fail the first migration.
It runs without any credentials
EMBEDDING_PROVIDER and EXTRACTION_PROVIDER default to fakes. The fake embedder returns the same
vector for the same text every time, and the fake extractor proposes no claims at all. So a fresh
checkout starts, migrates, and answers requests. Search returns results. They just do not mean
anything.
curl -s 'localhost:8108/v1/knowledge/search?q=pricing+tiers' \
-H 'X-Dev-Principal: [email protected]' | jqA program can call with a broker credential instead of an Access token. The JWT's email is the caller, the same address an Access session would use. See docs/decisions/0079-a-person-mints-their-own-api-credential.md.
Locally, DEV_AUTH=1 takes the caller's identity from the X-Dev-Principal header. The default is
[email protected]. Set DEV_ACTOR in the repo-root .env to use a different address; the local
stack also puts that person on INTELLIGENCE_REVIEWERS, so you can try the review flow. There is no
list of who may read: knowledge belongs to the whole company, so anyone the gateway lets in can
read it.
Watch a conversation turn into a claim
The whole path needs workspace and the workers:
./localenv up workspace-api intelligence-api intelligence-listener intelligence-enrichmentSay something worth reading
Add a turn in workspace (see
its getting started). The listener queues one
observe job and waits before running it. An active conversation costs one job, not one per message,
so expect a pause rather than an instant result.
Watch the queue
The Enrichment queue: The Postgres table intelligence's derivation work runs through: leased claims, deduplication on job and target, exponential backoff, and a dead letter. It is a table rather than a broker queue because a burst of turns in one conversation has to collapse into one extraction, which is a row update. is a Postgres table, so you can query it directly.
GET /internal/jobs/depth reports the same thing:
curl -s localhost:8108/internal/jobs/depth \
-H 'Authorization: Bearer local-scheduler-token-not-a-secret-0' | jqRead what came out
curl -s 'localhost:8108/v1/knowledge/insights' -H 'X-Dev-Principal: [email protected]' | jq
curl -s 'localhost:8108/v1/knowledge/candidates' -H 'X-Dev-Principal: [email protected]' | jqWith the fake extractor both lists are empty, which is the honest answer: nothing proposed a claim.
Point the EXTRACTION_* settings at a real model to see the pipeline produce something.
Point it at a real provider
Set these in services/intelligence/.env. They are the same variables the deployment uses, which is
the reason the model calls live in the service instead of in every client:
EMBEDDING_PROVIDER=openai
EMBEDDING_BASE_URL=…
EMBEDDING_API_KEY=…
EMBEDDING_MODEL=text-embedding-3-small
EMBEDDING_DIMENSIONS=1536openai here names the request format, not the company. Azure OpenAI, OpenAI, Together, vLLM,
LocalAI, and Ollama's compatibility endpoint all accept it.
EMBEDDING_DIMENSIONS is fixed by the first migration, because vector(N) is a column type.
Changing the model or the width means recalculating every embedding, not editing a variable.
Locally, drop the database. Deployed, that is the reindex job.
Every key is documented in services/intelligence/.env.example.
Run the batch jobs by hand
The scheduled work is plain HTTP, so you do not need a scheduler locally:
curl -s -X POST localhost:8108/internal/jobs/cluster-links \
-H 'Authorization: Bearer local-scheduler-token-not-a-secret-0'That call only queues the job and returns. ./localenv up intelligence-batch is what actually runs
it.
Review console
The review UI is intelligence-app on localhost:3503:
./localenv up intelligence-appThe hamburger drawer is three collapsible sections, the same shape as tool-app: Workspace, Intelligence, and Admin. Admin items, and Facts, are hidden unless the caller is a platform admin. The icon ribbon stays a flat list of every page.
Safari and Chrome can install it on the home screen. The icon and splash screens live under frontend/intelligence-app/public/image/pwa.
Tests
go test ./services/intelligence/...Intelligence Service
The company knowledge layer — claims backed by quotes from conversations, notes, and meetings, a map of people and things, and the patterns that only show up across projects.
Architecture
How intelligence decides what is known — the pipeline, how a claim earns trust, the job queue, the entity graph, and why the search index can always be rebuilt.