Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,16 @@ DATABASE_URL=postgres://postgres:postgres@127.0.0.1:5432/ignition_outbound
OPENAI_API_KEY=
OPENAI_RESEARCH_MODEL=
OPENAI_SYNTHESIS_MODEL=
OPENAI_EMBEDDING_MODEL=text-embedding-3-small
TEI_EMBEDDING_GRPC_ADDRESS=127.0.0.1:8081
TEI_EMBEDDING_RUNTIME_MODEL_ID=janni-t/qwen3-embedding-0.6b-int8-tei-onnx
TEI_EMBEDDING_RUNTIME_MODEL_SHA=8fe0c238c7c48016d28e750413ca492024be3ddf
TEI_EMBEDDING_DIMENSION=1024
TEI_EMBEDDING_CONCURRENCY=1
TEI_RERANKER_GRPC_ADDRESS=127.0.0.1:8082
TEI_RERANKER_RUNTIME_MODEL_ID=csylabs/bge-reranker-v2-m3-int8-onnx
TEI_RERANKER_RUNTIME_MODEL_SHA=eaf5072d7b1a3f1fa584cc7482c7efb8f784dca0
TEI_GRPC_TIMEOUT_MS=15000
TEI_QUERY_INSTRUCTION=Given a search query, retrieve relevant passages that answer the query in French or English.
AI_PROVIDER=codex-cli
KIMI_CODE_API_KEY=
KIMI_CODE_BASE_URL=https://api.kimi.com/coding/v1
Expand Down Expand Up @@ -35,11 +44,6 @@ BOOKING_URL=
CRAWLER_SERVICE_URL=http://127.0.0.1:8000
CRAWLER_API_KEY=
SEARCH_FALLBACK_ENABLED=true
DOCUMENT_EXTRACTOR=lightweight
# Optional advanced extraction profile: start the documents-advanced compose profile.
# DOCUMENT_EXTRACTOR=docling
# DOCLING_SERVICE_URL=http://127.0.0.1:5001
# DOCLING_API_KEY=
S3_ENDPOINT=http://127.0.0.1:9000
S3_REGION=us-east-1
S3_BUCKET=ignition-outbound
Expand Down
5 changes: 4 additions & 1 deletion Dockerfile.backend
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ RUN bun install --frozen-lockfile
RUN mkdir -p dist/backend dist/migrate dist/media-canary \
&& bun build apps/api/src/index.ts apps/worker/src/index.ts --target bun --outdir dist/backend \
&& bun build packages/infrastructure/src/database/migrate.ts --target bun --outdir dist/migrate \
&& bun build packages/infrastructure/src/documents/document-extractor-process.ts --target bun --outfile dist/document-extractor/document-extractor-process.js \
&& bun build scripts/verify-content-media-runtime.ts --target bun --outdir dist/media-canary

FROM node:22-bookworm-slim AS codex-cli
Expand All @@ -23,7 +24,7 @@ WORKDIR /app
ENV NODE_ENV=production

RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates ffmpeg fonts-dejavu-core nodejs poppler-utils \
&& apt-get install -y --no-install-recommends ca-certificates ffmpeg fonts-dejavu-core nodejs \
&& rm -rf /var/lib/apt/lists/*

COPY --from=codex-cli /usr/local/lib/node_modules/@openai /usr/local/lib/node_modules/@openai
Expand All @@ -32,7 +33,9 @@ RUN ln -s /usr/local/lib/node_modules/@openai/codex/bin/codex.js /usr/local/bin/
COPY --from=build /app/dist/backend ./dist/backend
COPY --from=build /app/dist/migrate ./dist/migrate
COPY --from=build /app/dist/media-canary ./dist/media-canary
COPY --from=build /app/dist/document-extractor ./dist/document-extractor
COPY --from=build /app/packages/infrastructure/migrations ./migrations
COPY --from=build /app/packages/infrastructure/src/embeddings/tei.proto ./packages/infrastructure/src/embeddings/tei.proto

RUN mkdir -p /var/lib/noosphere-codex \
&& chown -R bun:bun /var/lib/noosphere-codex
Expand Down
50 changes: 43 additions & 7 deletions README.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ Technical details remain observable without taking over the product. Exceptions
| Setter corpus | automatic gate passed | 100/100 Codex Luna dry-runs, resolvable receipts, no sends |
| Human editorial review | open | the review artifact exists but is not auto-labelled |
| 2-vCPU / 8-GiB VPS | below the concurrent SLO | zero errors, memory-view p95 above target |
| Recommended VPS | 4 vCPU / 16 GiB minimum | final measurement still required on that profile |
| Light deployment | Netcup RS 2000 G12, 8 dedicated cores / 16 GiB | acceptable minimum for a canary or one lightly loaded workspace |
| Recommended production | Netcup RS 4000 G12, 12 dedicated cores / 32 GiB | target for concurrent research, crawling, TEI and campaigns |
| Real provider canary | not executed | requires explicit, bounded authorization |

See the [Prospect 360 validation report](docs/performance/2026-08-23-prospect-360-memory-validation-report.md) for exact evidence. A shadow or dry-run result is never presented as proof of a real send.
Expand Down Expand Up @@ -74,7 +75,7 @@ Noosphere is a TypeScript/Bun modular monolith with an autonomous Python crawler
| `apps/web` | Next.js 16 and React 19 |
| `apps/crawler` | FastAPI, Crawl4AI, Playwright and SearXNG |

Standard primitives are PostgreSQL/ParadeDB, S3-compatible MinIO, PostgreSQL jobs/outbox, Bun, Next.js and Docker Compose. Docling is not required by the standard deployment; the lightweight extractor handles text, Markdown, HTML and text PDFs.
Standard primitives are PostgreSQL/ParadeDB, S3-compatible MinIO, PostgreSQL jobs/outbox, Bun, Next.js and Docker Compose. The local router extracts text PDFs, DOCX, PPTX, XLSX, HTML, Markdown and text; scans are reported without OCR.

```mermaid
flowchart TB
Expand Down Expand Up @@ -145,10 +146,9 @@ Never commit `.env`, API keys, LinkedIn cookies, OAuth tokens or webhook secrets
| Storage | `S3_ENDPOINT`, bucket and credentials | yes |
| Crawler | `CRAWLER_SERVICE_URL`, `CRAWLER_API_KEY` | yes |
| AI | `AI_PROVIDER` and the selected Kimi, Codex or OpenAI runtime | yes |
| Embeddings | `OPENAI_API_KEY`, `OPENAI_EMBEDDING_MODEL` | for knowledge search |
| Search | `TEI_EMBEDDING_*`, `TEI_RERANKER_*` | for knowledge search |
| Channels | Unipile credentials and healthy account IDs | only for enabled channels |
| Documents | `DOCUMENT_EXTRACTOR=lightweight` | standard value |
| Docling | advanced-profile URL and key | no |
| Documents | S3 storage, TEI Qwen and ParadeDB | for knowledge |

For Codex, initialize the private Docker authentication volume as documented in the [provider runbook](docs/runbooks/provider-configuration.md). Models and fallbacks can then be selected per workspace and capability in the UI.

Expand Down Expand Up @@ -187,7 +187,43 @@ A green suite is not a live proof. Read the [Prospect 360 validation report](doc

The standard deployment uses `compose.infrastructure.yml` and `compose.production.yml` for the API, web app, crawler, PostgreSQL, MinIO and specialized workers. Follow the [VPS production runbook](docs/runbooks/vps-production.md) for TLS, migrations, backups, restores and canaries.

Current recommendation: **x86_64, 4 vCPU, 16 GiB RAM and at least 100 GiB SSD/NVMe**. The isolated 2-vCPU / 8-GiB benchmark completed without errors but missed the p95 targets under 100 concurrent Prospect 360 assemblies, so that smaller profile is not recommended for the complete platform.
### Choose the server

Deploy Noosphere on an **x86_64/AMD64 machine with NVMe storage**. No GPU is required: Qwen3 Embedding and the BGE reranker run locally through CPU-based TEI. Dedicated cores are preferable to shared vCPUs because PostgreSQL, Chromium and TEI can become CPU-bound at the same time.

| Usage | Netcup machine | Resources | Recommendation |
|---|---|---|---|
| Remote development or short canary | VPS 2000 G12 | 8 shared vCPUs, 16 GiB, 512 GB NVMe | acceptable for deployment validation, not as the durable target |
| Light usage | **RS 2000 G12** | **8 dedicated cores, 16 GiB, 512 GB NVMe** | acceptable minimum for one lightly loaded workspace |
| Recommended production | **RS 4000 G12** | **12 dedicated cores, 32 GiB, 1 TB NVMe** | recommended target for the complete platform |

The **RS 2000 G12** fits when all the following conditions remain true:

- one active workspace;
- few concurrent users;
- no more than four concurrent crawls;
- heavy document indexing and campaign workloads do not run concurrently;
- moderate growth of documents, conversations and evidence.

This profile is not a multi-workspace capacity guarantee. Benchmarks showed PostgreSQL using about eight cores during an aggressive scenario before accounting for Qwen, reranker and crawler CPU. On 16 GiB, monitor memory, swap, job lag and p95 latency. Upgrade to the RS 4000 when sustained memory exceeds 12 GiB, swap remains active, CPU exceeds 70% for 15 minutes or multiple workspaces must run concurrently.

The **RS 4000 G12** is the production recommendation. Its headroom keeps both TEI models resident while crawls, workers, PostgreSQL, MinIO and backups operate together instead of sizing the platform for idle conditions.

### When embeddings are actually used

The TEI services stay running and keep their models resident to avoid cold starts lasting several dozen seconds. Resident memory does not mean continuous CPU usage: Qwen computes embeddings only in the following cases:

- when an eligible document, offer, proof or knowledge item is imported or changed;
- during hybrid knowledge search, to embed the query;
- during a full reindex or a future model migration.

The reconciler checks content hashes before calling TEI, so unchanged content is not embedded again on every worker pass. The BGE reranker runs only after hybrid retrieval, on a small candidate set. Message synchronization, prospect sourcing, post writing, sends and the Setter's normal execution do not currently invoke Qwen Embedding.

For one lightly used workspace, embedding load is therefore **occasional**; the permanent cost is mainly the RAM reserved for warm models. The truly intensive case is importing a large corpus or running a full reindex. This is why the RS 2000 is appropriate for one workspace, while the RS 4000 mainly provides headroom for multi-workspace concurrency and simultaneous heavy operations.

Public prices checked on 24 August 2026 and subject to VAT and contract changes: RS 2000 G12 from **€21.43/month including VAT** and RS 4000 G12 from **€39.92/month including VAT**. See [Netcup Root Server G12](https://www.netcup.com/en/server/root-server) for current specifications. The local measurement protocol and its limitations are recorded in the [capacity report](docs/performance/2026-08-21-noosphere-standard-stack-capacity.md).

Recommended system configuration: Debian 12 x86_64, 8 GiB emergency swap with `vm.swappiness=10`, off-server PostgreSQL and MinIO backups, and public exposure restricted to HTTP(S) and restricted SSH. PostgreSQL, MinIO and TEI remain on the private Docker network.

```bash
cp deploy/.env.production.example .env
Expand All @@ -197,7 +233,7 @@ docker compose --env-file .env \
-f compose.infrastructure.yml -f compose.production.yml up -d
```

The standard deployment does not start Docling. `documents-advanced` remains an optional profile.
The deployment starts no external document extractor. Each extraction runs in a transient Bun process and remains durably driven by PostgreSQL jobs.

Do not run a real LinkedIn, email or WhatsApp canary without explicit authorization bounded to the relevant account, workspace and content.

Expand Down
50 changes: 43 additions & 7 deletions README.fr.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ Les détails techniques restent observables sans envahir l’expérience. Les ex
| Corpus Setter | gate automatique atteint | 100/100 dry-runs Codex Luna, receipts résolubles, aucun envoi |
| Revue éditoriale humaine | ouverte | le fichier de revue existe, mais n’est pas auto-étiqueté |
| VPS 2 vCPU / 8 Gio | insuffisant pour le SLO concurrent | fonctionnement sans erreur, p95 mémoire hors cible |
| VPS recommandé | 4 vCPU / 16 Gio minimum | mesure finale encore à rejouer sur ce profil |
| Déploiement léger | Netcup RS 2000 G12, 8 cœurs dédiés / 16 Gio | minimum acceptable pour un canary ou un seul workspace peu chargé |
| Production recommandée | Netcup RS 4000 G12, 12 cœurs dédiés / 32 Gio | cible pour faire tourner simultanément recherche, crawling, TEI et campagnes |
| Canary provider réel | non exécuté | exige une autorisation explicite et bornée |

Le détail et les fichiers de preuve sont dans le [rapport de validation Prospect 360](docs/performance/2026-08-23-prospect-360-memory-validation-report.md). Une preuve shadow ou dry-run ne constitue jamais une preuve d’envoi réel.
Expand Down Expand Up @@ -74,7 +75,7 @@ Noosphere est un monolithe modulaire TypeScript/Bun avec un crawler Python auton
| `apps/web` | Next.js 16 et React 19 |
| `apps/crawler` | FastAPI, Crawl4AI, Playwright et SearXNG |

Primitives standard : PostgreSQL/ParadeDB, MinIO compatible S3, queue/outbox PostgreSQL, Bun, Next.js et Docker Compose. Docling n’est pas requis dans le déploiement standard ; l’extracteur léger gère texte, Markdown, HTML et PDF texte.
Primitives standard : PostgreSQL/ParadeDB, MinIO compatible S3, queue/outbox PostgreSQL, Bun, Next.js et Docker Compose. Le routeur local extrait PDF texte, DOCX, PPTX, XLSX, HTML, Markdown et texte ; les scans sont signalés sans OCR.

```mermaid
flowchart TB
Expand Down Expand Up @@ -145,10 +146,9 @@ Ne commitez jamais `.env`, clés API, cookies LinkedIn, jetons OAuth ou secrets
| Stockage | `S3_ENDPOINT`, bucket et identifiants | oui |
| Crawler | `CRAWLER_SERVICE_URL`, `CRAWLER_API_KEY` | oui |
| IA | `AI_PROVIDER` puis Kimi, Codex ou OpenAI selon la route | oui |
| Embeddings | `OPENAI_API_KEY`, `OPENAI_EMBEDDING_MODEL` | pour la connaissance |
| Recherche | `TEI_EMBEDDING_*`, `TEI_RERANKER_*` | pour la connaissance |
| Canaux | Unipile et IDs de comptes sains | seulement pour les canaux activés |
| Documents | `DOCUMENT_EXTRACTOR=lightweight` | valeur standard |
| Docling | URL et clé du profil `documents-advanced` | non |
| Documents | stockage S3, TEI Qwen et ParadeDB | pour la connaissance |

Pour Codex, exécutez l’authentification dans le volume privé décrit par le [runbook providers](docs/runbooks/provider-configuration.md). Les modèles et fallbacks se choisissent ensuite par workspace et par capacité dans l’interface.

Expand Down Expand Up @@ -187,7 +187,43 @@ Une suite verte ne remplace pas une preuve live. Consultez le [rapport de valida

Le déploiement standard utilise `compose.infrastructure.yml` et `compose.production.yml`. Il comprend API, web, crawler, PostgreSQL, MinIO et workers spécialisés. Suivez le [runbook VPS](docs/runbooks/vps-production.md) pour TLS, migrations, sauvegardes, restauration et canary.

Profil recommandé à ce stade : **x86_64, 4 vCPU, 16 Gio de RAM, SSD/NVMe 100 Gio ou plus**. Le benchmark isolé 2 vCPU / 8 Gio a terminé sans erreur, mais a dépassé les seuils p95 sous 100 assemblages Prospect 360 concurrents ; ce profil n’est donc pas recommandé pour l’ensemble de la plateforme.
### Choisir la machine

Noosphere doit être déployé sur une machine **x86_64/AMD64 avec stockage NVMe**. Aucun GPU n’est requis : Qwen3 Embedding et le reranker BGE sont servis localement par TEI en mode CPU. Les cœurs dédiés sont préférables aux vCPU partagés, car PostgreSQL, Chromium et TEI peuvent solliciter le CPU au même moment.

| Usage | Machine Netcup | Ressources | Recommandation |
|---|---|---|---|
| Développement distant ou canary court | VPS 2000 G12 | 8 vCPU partagés, 16 Gio, 512 Go NVMe | acceptable pour valider le déploiement, pas comme cible durable |
| Usage léger | **RS 2000 G12** | **8 cœurs dédiés, 16 Gio, 512 Go NVMe** | minimum acceptable pour un seul workspace peu chargé |
| Production recommandée | **RS 4000 G12** | **12 cœurs dédiés, 32 Gio, 1 To NVMe** | cible recommandée pour la plateforme complète |

Le **RS 2000 G12** convient lorsque toutes les conditions suivantes sont vraies :

- un seul workspace actif ;
- peu d’utilisateurs simultanés ;
- au plus quatre crawls concurrents ;
- indexations documentaires et campagnes lourdes non lancées en parallèle ;
- croissance modérée des documents, conversations et preuves.

Ce profil ne doit pas être confondu avec une garantie de capacité multi-workspace. Les tests ont montré que PostgreSQL pouvait déjà mobiliser environ huit cœurs pendant un scénario agressif, avant d’ajouter le coût CPU de Qwen, du reranker et du crawler. Sur 16 Gio, surveillez la mémoire, le swap, le lag des jobs et la latence p95. Passez au RS 4000 si la mémoire reste au-dessus de 12 Gio, si le swap est utilisé durablement, si le CPU dépasse 70 % pendant 15 minutes ou si plusieurs workspaces doivent travailler simultanément.

Le **RS 4000 G12** est notre choix de production : sa marge permet de conserver simultanément les deux modèles TEI en mémoire, d’exécuter les crawls, les workers, PostgreSQL, MinIO et les sauvegardes sans dimensionner la plateforme sur son fonctionnement au repos.

### Quand les embeddings sont réellement utilisés

Les services TEI restent démarrés et gardent leurs modèles en mémoire pour éviter un démarrage à froid de plusieurs dizaines de secondes. Cette mémoire résidente ne signifie pas que le CPU travaille en permanence : Qwen calcule un embedding seulement dans les cas suivants :

- à l'import ou à la modification d'un document, d'une offre, d'une preuve ou d'une connaissance éligible ;
- lors d'une recherche hybride dans la connaissance, pour vectoriser la requête ;
- pendant une réindexation complète ou une future migration de modèle.

Le réconciliateur vérifie les hashes avant l'appel TEI : un contenu inchangé n'est pas ré-embeddé à chaque passage du worker. Le reranker BGE n'intervient qu'après la recherche hybride, sur un petit ensemble de candidats. La synchronisation des messages, le sourcing de prospects, la rédaction des posts, les envois et le fonctionnement courant du Setter n'appellent pas actuellement Qwen Embedding.

En pratique, pour un workspace léger, la charge d'embedding est donc **ponctuelle** ; le coût permanent est surtout la RAM réservée aux modèles chauds. Le pic réellement intensif correspond à l'import d'un corpus important ou à une réindexation complète. C'est pourquoi le RS 2000 est cohérent pour un seul workspace, tandis que le RS 4000 apporte surtout de la marge pour la concurrence multi-workspace et les opérations lourdes simultanées.

Prix publics relevés le 24 août 2026, susceptibles d’évoluer selon TVA et durée d’engagement : RS 2000 G12 à partir de **21,43 € TTC/mois** et RS 4000 G12 à partir de **39,92 € TTC/mois**. Consultez les [Root Servers G12 Netcup](https://www.netcup.com/en/server/root-server) pour les caractéristiques actuelles. Le protocole et les limites de la mesure locale sont documentés dans le [rapport de capacité](docs/performance/2026-08-21-noosphere-standard-stack-capacity.md).

Configuration système conseillée : Debian 12 x86_64, 8 Gio de swap de secours avec `vm.swappiness=10`, sauvegardes PostgreSQL et MinIO hors du serveur, et exposition publique limitée à HTTP(S) et SSH restreint. PostgreSQL, MinIO et les services TEI restent sur le réseau Docker privé.

```bash
cp deploy/.env.production.example .env
Expand All @@ -197,7 +233,7 @@ docker compose --env-file .env \
-f compose.infrastructure.yml -f compose.production.yml up -d
```

Le déploiement standard ne démarre pas Docling. Le profil `documents-advanced` est optionnel.
Le déploiement ne démarre aucun extracteur externe. Chaque extraction utilise un processus Bun transitoire et durablement piloté par les jobs PostgreSQL.

Ne lancez pas de canary LinkedIn, email ou WhatsApp réel sans autorisation explicite et bornée au compte, au workspace et au contenu concernés.

Expand Down
Loading
Loading