backup: snapshot post-démo GHT 2026-05-19
Some checks failed
tests / Lint (ruff + black) (push) Successful in 1m50s
tests / Tests unitaires (sans GPU) (push) Failing after 1m50s
tests / Tests sécurité (critique) (push) Has been skipped

Backup état complet après enregistrement vidéo démo de bout en bout.
À utiliser comme point de référence pour la consolidation post-démo.

Changements majeurs de la session 18-19 mai :
- AIVA-URGENCE : page autonome avec preset URL + auto-focus chain
- Workflow Demo_urgence_3_db : merge linux_db + steps AIVA + pause humaine NoMachine
- Bypass LLM (static_result / static_text) dans replay_engine
  pour démos déterministes sans appel Ollama
- Fix api_stream:3013 — replay_paused au premier polling /next
- dag_execute : lift duration_ms vers top-level pour wait runtime
- NPM bypass auth /aiva-urgence/ via location ^~ (proxy_host/10.conf hors git)
- scripts/cancel-replays.sh — workaround Stop VWB qui ne purge pas la queue

Anchors visuels (468) forcés dans le commit pour garantir restorabilité.
DB workflows actuelle + ~12 .bak DB de la journée incluses.

Sujets identifiés pour consolidation post-démo (TODO) :
1. Bug VWB recapture anchor ne régénère pas le PNG
2. Léa client accumule état mémoire (restart périodique requis)
3. Stop VWB ne purge pas la queue serveur (lien manquant vers /replay/cancel)
4. Bug coord client mss tronqué 2560x60 → mapping Y cassé
5. delay_before/delay_after ignorés au runtime (fix partiel duration_ms)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dom
2026-05-19 14:55:06 +02:00
parent f2212e77e3
commit 5ea4960e65
627 changed files with 211348 additions and 169 deletions

53
scripts/cancel-replays.sh Executable file
View File

@@ -0,0 +1,53 @@
#!/usr/bin/env bash
# Annule TOUS les replays actifs/en-pause côté streaming server.
# À utiliser AVANT de relancer un replay quand le bouton Stop VWB
# ne purge pas la queue (bug en cours d'investigation).
#
# Usage : ./scripts/cancel-replays.sh
set -euo pipefail
ENV_FILE="/home/dom/ai/rpa_vision_v3/.env.local"
STREAM_URL="http://localhost:5005"
if [[ ! -f "$ENV_FILE" ]]; then
echo "❌ .env.local introuvable" >&2
exit 1
fi
TOKEN=$(grep RPA_API_TOKEN "$ENV_FILE" | cut -d= -f2 | tr -d "'\"")
if [[ -z "$TOKEN" ]]; then
echo "❌ RPA_API_TOKEN vide" >&2
exit 1
fi
# Liste les replays actifs et les annule un par un.
mapfile -t ACTIVE < <(
curl -s -H "Authorization: Bearer $TOKEN" \
"$STREAM_URL/api/v1/traces/stream/replay/list" \
| python3 -c "
import sys, json
try:
d = json.load(sys.stdin)
for x in d.get('replays', []):
if x.get('status') in ('running', 'paused_need_help', 'busy'):
print(x['replay_id'])
except Exception as e:
sys.stderr.write(f'parse error: {e}\n')
"
)
if [[ ${#ACTIVE[@]} -eq 0 ]]; then
echo "✓ Aucun replay actif"
exit 0
fi
echo "Annulation de ${#ACTIVE[@]} replay(s) actif(s) :"
for r in "${ACTIVE[@]}"; do
echo -n " $r ... "
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
"$STREAM_URL/api/v1/traces/stream/replay/$r/cancel" > /dev/null
echo "✓"
done
echo "✓ Tous les replays annulés, queues purgées."

View File

@@ -0,0 +1,70 @@
#!/usr/bin/env bash
# Déclenche manuellement le Ctrl+V puis Ctrl+Enter dans DBeaver de la VM via ydotool.
# Contournement nécessaire car NoMachine en "passive grab" mange la touche Ctrl
# envoyée par pynput depuis Léa Windows (les clics passent, pas les key combos).
#
# Pré-conditions (vérifiées + auto-réparées par ce script) :
# - ydotoold tourne dans la VM avec socket /tmp/.ydotool_socket (perm 0666)
# - Le gardien clipboard (prepare_clipboard_linuxdb.sh) maintient le INSERT
# dans les clipboards Wayland + X11 de la VM
#
# Pré-condition manuelle (le script ne peut pas la vérifier) :
# - DBeaver console <demo_95 2> a le focus dans la zone éditeur SQL
#
# Usage : lancer juste après les clics du workflow linux_db (entre ord 7 et ord 8).
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
VM_HOST="dom@192.168.122.132"
SSH_PASS="loli"
SUDO_PASS="loli"
YDOTOOL_SOCKET="/tmp/.ydotool_socket"
ssh_vm() {
SSHPASS="$SSH_PASS" sshpass -e ssh -o StrictHostKeyChecking=no "$VM_HOST" "$@"
}
# 1. Vérifier ydotoold (doit être lancé en amont par opérateur — voir handoff §5)
# Le script ne tente PAS de le relancer car invoqué depuis le serveur systemd
# qui n'a pas de TTY → sudo via stdin échoue silencieusement.
if ! ssh_vm "test -S $YDOTOOL_SOCKET"; then
echo "ERREUR: ydotoold (socket $YDOTOOL_SOCKET) absent dans la VM" >&2
echo "Lance manuellement depuis terminal VM (TTY) :" >&2
echo " sudo ydotoold --socket-path=$YDOTOOL_SOCKET --socket-perm=0666 &" >&2
exit 1
fi
# 2. Vérifier gardien clipboard, relancer si nécessaire
GUARD_OK=$(ssh_vm "
if [ -f /tmp/clipboard_guard.pid ]; then
P=\$(cat /tmp/clipboard_guard.pid)
kill -0 \$P 2>/dev/null && echo OK || echo DEAD
else
echo MISSING
fi
")
if [ "$GUARD_OK" != "OK" ]; then
echo "[setup] gardien clipboard absent/mort ($GUARD_OK), relance via prepare_clipboard_linuxdb.sh…"
"$SCRIPT_DIR/prepare_clipboard_linuxdb.sh" || {
echo "ERREUR: échec préparation clipboard" >&2
exit 1
}
fi
# 3. Envoyer Ctrl+V (scan codes : Ctrl=29, V=47)
echo "[ydotool] Ctrl+V"
ssh_vm "YDOTOOL_SOCKET=$YDOTOOL_SOCKET ydotool key 29:1 47:1 47:0 29:0"
# 4. Délai pour que DBeaver finisse de coller (~1.6k chars)
sleep 0.5
# 5. Envoyer Ctrl+Enter (scan codes : Ctrl=29, Enter=28)
echo "[ydotool] Ctrl+Enter"
ssh_vm "YDOTOOL_SOCKET=$YDOTOOL_SOCKET ydotool key 29:1 28:1 28:0 29:0"
echo ""
echo "OK INSERT collé et exécuté dans DBeaver."
echo ""
echo "Pour vérifier en base demo_95 :"
echo " sshpass -p $SSH_PASS ssh $VM_HOST \"python3 -c 'import sqlite3; c=sqlite3.connect(\\\"/home/dom/demo_95\\\"); print(list(c.execute(\\\"SELECT id,nom_patient,date_creation FROM requalification_urgence ORDER BY id DESC LIMIT 2\\\")))'\""

View File

@@ -0,0 +1,9 @@
INSERT INTO requalification_urgence (ipp, nom_patient, decision, sommes, resume, justification, workflow_id, date_creation) VALUES ('25003284', 'MOREL Catherine',
'REQUALIFICATION_HOSPITALISATION', 1750, 'Patiente de 78 ans admise aux urgences pour dyspnée fébrile sur terrain asthmatique. Examen clinique retrouvant une polypnée à 28 par
minute, saturation 88 pour cent en air ambiant, fièvre à 39 degrés. Radiographie thoracique montrant un foyer alvéolaire systématisé du lobe inférieur droit compatible avec une
pneumopathie communautaire. Mise sous oxygénothérapie 3 litres par minute, antibiothérapie par amoxicilline acide clavulanique et nébulisations bronchodilatatrices. Surveillance
prolongée en UHCD pendant 36 heures pour optimisation respiratoire et hémodynamique. Transfert en service de pneumologie pour poursuite de la prise en charge.', 'La décision
REQUALIFICATION HOSPITALISATION est justifiée par plusieurs éléments concordants conformes au critère 3 de la grille PMSI ATIH. Premier critère : surveillance médicalisée prolongée
supérieure à 6 heures avec oxygénothérapie et antibiothérapie intraveineuse. Deuxième critère : sévérité respiratoire initiale avec désaturation à 88 pour cent nécessitant un support
continu non disponible en consultation simple. Troisième critère : transfert en service de pneumologie confirmant la nécessité de soins continus dépassant le forfait urgences. Ces
éléments dépassent le périmètre du FORFAIT URGENCE et valident la valorisation en hospitalisation MCO.', 'wf_483910cdd851_1778750587', '2026-05-15');

View File

@@ -0,0 +1,91 @@
#!/usr/bin/env bash
# Précharge le clipboard de la VM Ubuntu avec le INSERT SQL du workflow linux_db.
# Contourne la lenteur du char-by-char NoMachine (bug paste:true).
#
# Source de vérité : scripts/payload_insert_morel.sql (extrait depuis workflows.db
# backup du 2026-05-16_102755, avant transformation du step ord 8 en Ctrl+V).
#
# Wayland ne permet pas de "verrouiller" la sélection clipboard : wl-copy meurt
# dès qu'un autre client (terminal, navigateur, DBeaver) prend le clipboard.
# Solution : un GARDIEN qui re-pousse le payload toutes les 0.5s en boucle.
# Le PID du gardien est sauvegardé dans /tmp/clipboard_guard.pid sur la VM
# pour permettre un kill propre sans pkill -f (qui se tuerait lui-même).
#
# À lancer AVANT chaque run du workflow linux_db.
# Le step ord 8 du workflow est désormais un Ctrl+V (et non plus le type_text).
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PAYLOAD_FILE="$SCRIPT_DIR/payload_insert_morel.sql"
VM_HOST="dom@192.168.122.132"
SSH_PASS="loli"
VM_PAYLOAD="/tmp/clipboard_payload.sql"
VM_PIDFILE="/tmp/clipboard_guard.pid"
# 1. Vérifier le payload local
if [ ! -s "$PAYLOAD_FILE" ]; then
echo "ERREUR: payload introuvable ou vide : $PAYLOAD_FILE" >&2
exit 1
fi
BYTES=$(wc -c < "$PAYLOAD_FILE")
echo "[1/3] Payload local : ${BYTES} bytes ($PAYLOAD_FILE)"
# 2. Pousser dans la VM via SSH (cat redirect)
SSHPASS="$SSH_PASS" sshpass -e ssh -o StrictHostKeyChecking=no "$VM_HOST" \
"cat > $VM_PAYLOAD" < "$PAYLOAD_FILE"
REMOTE_BYTES=$(SSHPASS="$SSH_PASS" sshpass -e ssh -o StrictHostKeyChecking=no "$VM_HOST" \
"wc -c < $VM_PAYLOAD")
echo "[2/3] Fichier déployé : ${REMOTE_BYTES} bytes sur VM ($VM_PAYLOAD)"
if [ "$REMOTE_BYTES" != "$BYTES" ]; then
echo "ERREUR: taille fichier VM (${REMOTE_BYTES}) != local (${BYTES})" >&2
exit 1
fi
# 3. Lancer le gardien clipboard : boucle qui re-pousse le payload toutes les 0.5s.
# Kill de l'ancien via /tmp/clipboard_guard.pid (PID file, PAS pkill -f
# qui se tuerait lui-même car le pattern apparaît dans notre cmdline SSH).
SSHPASS="$SSH_PASS" sshpass -e ssh -o StrictHostKeyChecking=no "$VM_HOST" \
"export WAYLAND_DISPLAY=wayland-0 XDG_RUNTIME_DIR=/run/user/1000
# Kill ancien gardien si PID file existe et pointe vers un processus vivant
if [ -f $VM_PIDFILE ]; then
OLD_PID=\$(cat $VM_PIDFILE)
if [ -n \"\$OLD_PID\" ] && kill -0 \"\$OLD_PID\" 2>/dev/null; then
kill \"\$OLD_PID\" 2>/dev/null
sleep 0.3
fi
fi
# Lancer la boucle gardien : écrit sur LES DEUX clipboards.
# - wl-copy : clipboard Wayland (apps natives Wayland)
# - xsel : clipboard X11/XWayland (DBeaver/Java/GTK qui passe par XWayland)
# Sans le double-write, DBeaver lit un clipboard X11 vide même si Wayland plein.
# XAUTHORITY = cookie temporaire de mutter/XWayland (régénéré à chaque session)
XAUTH=\$(ls /run/user/1000/.mutter-Xwaylandauth.* 2>/dev/null | head -1)
if [ -z \"\$XAUTH\" ]; then
echo 'WARN: mutter-Xwaylandauth introuvable, X11 paste ne marchera pas' >&2
XAUTH=/home/dom/.Xauthority
fi
nohup setsid bash -c \"export DISPLAY=:0 XAUTHORITY=\$XAUTH; while true; do wl-copy < $VM_PAYLOAD; xsel --clipboard --input < $VM_PAYLOAD 2>/dev/null; sleep 0.5; done\" >/dev/null 2>&1 </dev/null &
GUARD_PID=\$!
echo \"\$GUARD_PID\" > $VM_PIDFILE
sleep 0.7
# Vérifier que le gardien tourne et que le clipboard est rempli
if ! kill -0 \"\$GUARD_PID\" 2>/dev/null; then
echo 'ERREUR: gardien mort juste après lancement' >&2
exit 1
fi
CHECK=\$(wl-paste | wc -c)
echo \"[3/3] gardien actif PID=\$GUARD_PID, clipboard=\$CHECK bytes\"
# Tolérance ±1 byte (wl-paste ajoute parfois un newline final)
DELTA=\$(( \$CHECK - $BYTES ))
if [ \$DELTA -lt -1 ] || [ \$DELTA -gt 1 ]; then
echo \"ERREUR: clipboard (\$CHECK) != payload ($BYTES) delta=\$DELTA\" >&2
exit 1
fi"
echo ""
echo "OK clipboard VM verrouillé en boucle. Tu peux lancer le replay linux_db."
echo "(le step ord 8 fera Ctrl+V, l'INSERT sera collé instantanément dans DBeaver)"
echo ""
echo "APRÈS LA DÉMO, tuer le gardien :"
echo " SSHPASS=$SSH_PASS sshpass -e ssh ${VM_HOST} \"kill \\\$(cat $VM_PIDFILE)\""