Installer et configurer le daemon local (N0) par script ou à la main, vérifier le masquage, rejouer les preuves de bout en bout, activer l'audit signé et reproduire le benchmark GO/NO-GO. Chaque bloc se copie d'un clic.
Le parcours script installe le binaire, génère la configuration locale (n0.env en 0600, ou n0.env.ps1 sous Windows), le script de démarrage start-n0, puis affiche la clé composite une seule fois. Trois étapes par OS.
Distribution par release GitHub : binaire par OS, NER léger embarqué (ONNX int8, 135 Mo), lib onnxruntime, checksums SHA-256 vérifiés. Aucune toolchain Rust, aucun torch.
powershell -ExecutionPolicy Bypass -File https://raw.githubusercontent.com/coucagog/cloison-proxy/main/install-n0.ps1
powershell -ExecutionPolicy Bypass -File .\deploy\configure-n0.ps1 # interactif
powershell -ExecutionPolicy Bypass -File .\deploy\configure-n0.ps1 -Start # configure PUIS démarre
powershell -ExecutionPolicy Bypass -File $env:USERPROFILE\.cloison\start-n0.ps1
bash <(curl -fsSL https://raw.githubusercontent.com/coucagog/cloison-proxy/main/install-n0.sh)
bash deploy/configure-n0.sh # interactif
bash deploy/configure-n0.sh --start # configure PUIS démarre
~/.cloison/start-n0.sh
bash <(curl -fsSL https://raw.githubusercontent.com/coucagog/cloison-proxy/main/install-n0.sh)
bash deploy/configure-n0.sh # interactif
bash deploy/configure-n0.sh --start # configure PUIS démarre
~/.cloison/start-n0.sh
Ils génèrent la configuration locale — ~/.cloison/n0.env (0600) sur Linux/macOS, %USERPROFILE%\.cloison\n0.env.ps1 sur Windows — le script start-n0, et affichent la clé composite une seule fois. Idempotents : rejouables, ils ne démarrent le daemon qu'avec --start / -Start.
| Option | Effet |
|---|---|
| --version v0.3.1 | installe une version précise (défaut : latest) |
| --prefix DIR | répertoire d'installation (défaut ~/.cloison) |
| --skip-ner / -SkipNer | sans le NER léger (gazetteers + alias seuls — la limite « texte libre » de §07 reste alors assumée) |
Composants installés : binaire cloison-proxy(.exe) · NER léger ner/model-int8.onnx + tokenizer.json + label_map.json · lib onnxruntime (chargée dynamiquement).
Le mode N0 s'active en posant CLOISON_VAULT_PATH : coffre chiffré AES-256-GCM persistant, auth 100 % locale, fail-loud au boot. Le daemon expose un endpoint compatible OpenAI sur http://localhost:8787.
export CLOISON_ROLE=edge
export CLOISON_LISTEN_ADDR=127.0.0.1:8787
export CLOISON_UPSTREAM_BASE_URL=https://openrouter.ai/api/v1
export CLOISON_VAULT_PATH=~/.cloison/vault.redb
export CLOISON_VAULT_PASSPHRASE='votre-passphrase'
export CLOISON_EXPECTED_ACCESS_TOKEN=mon_jeton
export CLOISON_TENANT_KEY_HEX=$(openssl rand -hex 32)
cloison-proxy
$env:CLOISON_ROLE='edge'
$env:CLOISON_LISTEN_ADDR='127.0.0.1:8787'
$env:CLOISON_UPSTREAM_BASE_URL='https://openrouter.ai/api/v1'
$env:CLOISON_VAULT_PATH="$env:USERPROFILE\.cloison\vault.redb"
$env:CLOISON_VAULT_PASSPHRASE='votre-passphrase'
$env:CLOISON_EXPECTED_ACCESS_TOKEN='mon_jeton'
$env:CLOISON_TENANT_KEY_HEX=(-join (1..32 | ForEach-Object { '{0:x2}' -f (Get-Random -Max 256) }))
cloison-proxy.exe
Ajouter les chemins pour couvrir les noms/lieux en texte libre (distilbert ONNX int8, ~11 ms/doc) ; absent → dégradation gracieuse sur N0 v1 (gazetteers + alias), avec avertissement :
export CLOISON_NER_MODEL_ONNX=~/.cloison/ner/model-int8.onnx
export CLOISON_NER_TOKENIZER=~/.cloison/ner/tokenizer.json
export CLOISON_ONNX_LIB=libonnxruntime.so # .dylib (macOS) / onnxruntime.dll (Windows)
Base URL : http://localhost:8787/v1
Clé : mn_mon_jeton.sk-or-v1-<votre-cle-fournisseur>
Ce manuel ne documente que des comportements déjà prouvés, chacun avec sa trace dans les journaux du dépôt. Tout le reste (intégrations en cours) n'y figure pas.
Smoke test réel : exit 0 (cœur) et exit 0 (NER embarqué). Masquage amont, restauration client, coffre sans clair, ville généralisée [VILLE_SN], embeddings bloqués (404).
journal/STACK-N0V13.md · NEXT-SESSION.md §8
Contre faux LLM : 12/12 (non-stream, stream, tool-calls, 401, jeton forgé…). Contre LLM réel (OpenRouter, gpt-4o-mini) : 8/8 — le fournisseur ne reçoit que des sentinelles.
journal/STACK-7.md
Reçus Ed25519 (compteurs, jamais de texte), rapports k-anonymes, journal append-only vérifiable, ingestion control → ledger testée de bout en bout.
journal/STACK-4.md · STACK-5.md
Grille pré-enregistrée v1.1, modèles réels sur CPU : PERSON 0.937 · LOC 0.835 · CNI/MAIL/TEL 1.000 · macro 0.954 · spécificité 0.77.
journal/STACK-8.md · bench/cloison-bench/results/
Deux contrôles : le smoke test distribué (prouvé exit 0 sur Windows réel) et le roundtrip manuel qui reproduit la preuve e2e des journaux.
powershell -ExecutionPolicy Bypass -File https://raw.githubusercontent.com/coucagog/cloison-proxy/main/smoke-n0.ps1
Ce que le smoke prouve : boot du daemon N0 (coffre persistant, fail-loud, sel 0600), NER embarqué chargé, masquage amont (sentinelles ⟦…⟧, aucune PII), restauration client complète, ville généralisée [VILLE_SN], coffre sans clair, embeddings → 404.
curl http://127.0.0.1:8787/v1/chat/completions \
-H "Authorization: Bearer mn_mon_jeton.sk-or-v1-XXXX" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"Appelez Xolani Ndlovu au 77 123 45 67, il habite a Ziguinchor."}]}'
Résultat prouvé : l'amont ne reçoit que Appelez ⟦…·PE⟧ ⟦…·PE⟧ au ⟦…·PH⟧, il habite à [VILLE_SN]. — le nom (hors gazetteer) est masqué par le NER embarqué, le téléphone +221 par les regex, la ville est généralisée ; la réponse du client contient les vraies valeurs restaurées, zéro jeton résiduel.
Le harnais deploy/e2e_reel.sh prouve le masquage anti-pass-through : il vérifie que le corps reçu par l'amont contient des sentinelles ⟦ et PAS la PII. Résultats historiques : mock 12/12, LLM réel 8/8.
cd cloison
sudo -E bash deploy/e2e_reel.sh
cd cloison
CLOISON_E2E_MODE=real OPENROUTER_API_KEY=<votre-cle> bash deploy/e2e_reel.sh
Scénarios couverts (prouvés) : chat non-stream, stream SSE (sentinelle découpée sur les chunks), tool-calls (arguments masqués/restaurés, stream compris), 401 sur clé invalide, jeton forgé → marqueur neutre, /v1/models, completions legacy.
Observe-only : le proxy détecte et compte sans rien masquer, émet des reçus signés Ed25519 (compteurs uniquement — jamais de texte) et sert un rapport de conformité k-anonyme (défaut k=5).
export CLOISON_AUDIT_MODE=1
export CLOISON_AUDIT_KEYS=/data/audit_key # clé Ed25519 de l'agent
export CLOISON_AUDIT_LEDGER_FILE=/data/audit_ledger.jsonl # reçus persistés (0600)
export CLOISON_AUDIT_K=5 # seuil k-anonymat
curl "http://127.0.0.1:8787/v1/audit/report?period=daily" \
-H "Authorization: Bearer mn_mon_jeton.sk-or-v1-XXXX"
Chaque réponse non-stream porte aussi l'en-tête X-Cloison-Audit-Receipt (reçu signé, base64url). Les périodes valides : hourly | daily | weekly | all. Les cellules sous le seuil k ne sont jamais publiées.
Le fossé ouest-africain est mesuré sur un jeu 100 % synthétique sénégalais (seed 42, 500 docs, 0 PII réelle), contre une baseline Presidio forte, avec une grille de scoring pré-enregistrée (v1.1, non modifiable). Verdict : GO.
cd bench/cloison-bench
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python -m spacy download fr_core_news_md
pytest test_benchmark.py # 32 tests du harnais
CLOISON_OFFLINE=1 python3 run_detect_target.py --offline # détecteur cible
| Métrique | Baseline Presidio forte | CLOISON (afroxlmr + consensus) | Grille v1.1 |
|---|---|---|---|
| PERSON | 0.518 | 0.937 | ≥ 0.638 ✅ |
| LOC | 0.596 | 0.835 | ≥ 0.746 ✅ |
| CNI / MAIL / TEL | 1.000 / 0.985 / 0.652 | 1.000 / 1.000 / 1.000 | non-régression ✅ |
| Macro F1 | 0.750 | 0.954 | ≥ 0.850 ✅ |
| Spécificité non-PII | 0.42 | 0.77 | ≥ 0.60 ✅ |
À lire avant d'acheter. Ce que le produit ne prétend pas résoudre est rendu visible, jamais dissimulé.
| Niveau | Où tourne le moteur | Ce que l'opérateur lit |
|---|---|---|
| N0 · local | poste de l'utilisateur | rien — promesse absolue (hors poste compromis) |
| N1 · site | serveur du client | seul le client, chez lui |
| N2 · enclave | matériel scellé attesté | personne, et c'est prouvé |
| N3 · hébergé | chez l'éditeur | l'éditeur lit le clair — entrée de gamme, jamais l'argument |