From 881534234d699c7350aaa8b46add807336114282 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 10 Sep 2026 18:47:49 +0200 Subject: [PATCH] docs: correct the DeepL claim and refresh the renamed paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CLINICAL_ASSISTANT.md described DeepL as an admin-configurable translation provider with its own keys and a fallback between providers. There is no DeepL client in the code: TRANSLATE_PROVIDERS is ['libretranslate'], and an unrecognised setting silently falls back rather than being rejected — the first wording I wrote claimed a rejection that does not happen either. TODO.md now names clinical-storage-milvus and personal-assistant-storage-milvus, and records the MinIO audio-backup work as finished. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Dv6sqaY6Vq3ChZHMem3cnU --- TODO.md | 29 +++++++++++------------------ docs/CLINICAL_ASSISTANT.md | 2 +- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/TODO.md b/TODO.md index 633631eb..652860ab 100644 --- a/TODO.md +++ b/TODO.md @@ -15,25 +15,17 @@ and green (674 tests, three consecutive clean runs). heavier to run) and **Cap** (newer, smaller). hCaptcha is neither Google nor open source, so it trades one third party for another. - [ ] **Kubernetes / CI-CD hardening.** Details under *Deployment readiness*. -- [ ] **Finish pointing audio backups at MinIO — one blocked step.** The - `audio-backups` bucket now exists on the same MinIO the app already uses - (`assets:9000`). The app's key is scoped by a MinIO *user* policy, so a - bucket policy alone grants it nothing — verified, it returns AccessDenied. - The remaining step attaches a second policy covering only that bucket, - leaving the generated-images grant untouched. It needs the MinIO root - credentials, and my permission layer blocked me from running it. Run: - `RU=$(cat ../ped-ai-storage/secrets/minio-root-user) RP=$(cat ../ped-ai-storage/secrets/minio-root-password)` - then `docker compose exec -T -e MINIO_ROOT_USER="$RU" -e MINIO_ROOT_PASSWORD="$RP" pediatric-scribe node scripts/enable-audio-backup-bucket.js`, - set `AUDIO_BACKUPS_S3_*` (the script prints them), and restart. Until then - recordings go to the encrypted Postgres column, which works; rows already - there keep working afterwards. +- [x] **Audio backups are in MinIO.** Same server, its own `audio-backups` + bucket. The app key carries a second policy covering only that bucket, so + the mounted credentials serve both. Verified: storage=object, round trip + byte-identical, objects removed with their rows. - [ ] **Basic index has no reader.** `MilvusVectorStore.search()` exists, but no tool calls it. Decide where the query path lives: pymilvus inside the deliberately-lean `nextcloud-basic-mcp` image, or a query API from the indexer container. Nothing can read that index until this is settled. Source: `/home/danvics/docker/nextcloud-basic-mcp` - [ ] **Apply the restored clinical vector-store compose.** Written, committed - and validated at `/home/danvics/docker/nextcloud-mcp-server`, deliberately + and validated at `/home/danvics/docker/clinical-storage-milvus`, deliberately NOT applied — `up -d` recreates the live clinical Milvus. ### Known gaps @@ -121,7 +113,7 @@ Worth doing before Kubernetes, roughly in order: - **Settings claim corrected**: there is no "use my normal physical exam" trigger, and the prompt forbids copying template content. -- Storage stack is under version control (`/home/danvics/docker/ped-ai-storage`), +- Storage stack is under version control (`/home/danvics/docker/personal-assistant-storage-milvus`), secrets verified excluded, with a README recording the misleading project names and the MinIO/separate-etcd requirements. - Both Milvus stores keep objects in MinIO; verified end to end on the basic side @@ -132,12 +124,13 @@ Worth doing before Kubernetes, roughly in order: ## Worth knowing - **Four repos were rescued from container images today**: `nextcloud-basic-mcp`, - `clinical-assist`, the deleted `nextcloud-mcp-server` compose file, and the + `clinical-assist`, the deleted clinical-storage compose file, and the operator's `check.py` drift. Prefer building from a repo over a live container. - **Two Milvus instances, historically misleading names.** - Clinical index = `nextcloud-mcp-server-milvus-1` (MinIO-backed, collection - `mcp_bge_m3_1024`). Nextcloud basic index = `ped-ai-storage-basic-milvus-1` - (db `basic`, collection `basic_bge_m3_1024_v2`). + Clinical index = `nextcloud-mcp-server-milvus-1` in + `clinical-storage-milvus` (MinIO-backed, collection `mcp_bge_m3_1024`). + Personal assistant index = `personal-assistant-storage-milvus-basic-milvus-1` + (db `basic`, collection `personal_assistant_bge_m3_1024`). - **Embedded etcd is unusable with authorization on.** Every non-root Milvus user failed `etcdserver: invalid auth token`. Both stores now run a separate etcd container, matching the profile that always worked. diff --git a/docs/CLINICAL_ASSISTANT.md b/docs/CLINICAL_ASSISTANT.md index 2ca5d727..e9923083 100644 --- a/docs/CLINICAL_ASSISTANT.md +++ b/docs/CLINICAL_ASSISTANT.md @@ -89,7 +89,7 @@ After each completed assistant turn (and on any change to the conversation), the ## Translation -Every message offers Translate with a target-language picker and a provider choice. The default provider is the local LibreTranslate container (`LIBRETRANSLATE_URL`, default `http://libretranslate:5000`); DeepL is an admin-configured alternative (`DEEPL_API_KEY` + `DEEPL_API_BASE`, default `https://api.deepl.com/v2`, `api-free.deepl.com` also allowed). The admin default lives in `clinical_assistant.translate_provider` (libretranslate|deepl). Responses are cached per provider+message+lang; transient provider failures fall back to the other configured provider once; validation failures never fall back. No patient data leaves the local network unless the admin explicitly configures DeepL. +Every message offers Translate with a target-language picker. Translation is the local LibreTranslate container (`LIBRETRANSLATE_URL`, default `http://libretranslate:5000`), which is the only provider there is. `clinical_assistant.translate_provider` is read but any unrecognised value silently falls back to LibreTranslate, and no DeepL client exists in the code at all. Responses are cached per provider+message+lang. Patient text therefore never leaves the local network. ## Settings