merge: issue/0045-notify-encrypted-rooms — DM rooms con E2EE

El script notify-developer.sh ahora crea salas DM con encriptacion
E2EE habilitada via initial_state m.room.encryption. Corrige que
bots recientes (father-bot, test-bot, test-personality) aparezcan
sin cifrado en Element.
This commit is contained in:
2026-04-10 22:44:35 +00:00
4 changed files with 129 additions and 2 deletions
+11 -2
View File
@@ -105,14 +105,23 @@ send_dm() {
local backoff=2
while [[ $retry -lt $max_retries ]]; do
# Crear DM room (o reutilizar existente)
# Crear DM room con E2EE habilitado (o reutilizar existente)
ROOM_RESP=$(curl -sf -X POST "${MATRIX_HOMESERVER}/_matrix/client/v3/createRoom" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"is_direct\": true,
\"invite\": [\"${user_id}\"],
\"preset\": \"trusted_private_chat\"
\"preset\": \"trusted_private_chat\",
\"initial_state\": [
{
\"type\": \"m.room.encryption\",
\"state_key\": \"\",
\"content\": {
\"algorithm\": \"m.megolm.v1.aes-sha2\"
}
}
]
}" 2>&1) || {
retry=$((retry + 1))
if [[ $retry -lt $max_retries ]]; then
+1
View File
@@ -55,3 +55,4 @@ afectados y notas de implementacion.
| 42 | Auto-avatar con proveedores gratuitos | [0042-auto-avatar-providers.md](completed/0042-auto-avatar-providers.md) | completado |
| 43 | Guardrails de seguridad para Father Bot | [0043-father-bot-security-guardrails.md](completed/0043-father-bot-security-guardrails.md) | completado |
| 44 | Formalizar pipeline de creacion de agentes | [0044-formalize-agent-creation-pipeline.md](completed/0044-formalize-agent-creation-pipeline.md) | completado |
| 45 | DM rooms sin E2EE en notify-developer.sh | [0045-notify-encrypted-rooms.md](completed/0045-notify-encrypted-rooms.md) | completado |
@@ -0,0 +1,79 @@
# 0045 — DM rooms creados por notify-developer.sh sin E2EE
## Objetivo
El script `notify-developer.sh` (paso 12 del pipeline de creacion de agentes) crea salas DM
sin encriptacion E2EE. Esto causa que Element muestre "End-to-end encryption isn't enabled"
en las conversaciones con bots creados recientemente (father-bot, test-bot, test-personality),
mientras que los bots mas antiguos (assistant-bot, asistente-2) tienen E2EE porque sus DMs
fueron iniciados desde Element Web (que encripta por defecto).
## Contexto
El `createRoom` actual usa `preset: trusted_private_chat` que configura permisos pero **no activa
E2EE**. Para activar encriptacion se necesita un `initial_state` con evento `m.room.encryption`.
Archivo afectado: `dev-scripts/agent/notify-developer.sh` (linea ~109).
## Arquitectura
- `dev-scripts/agent/notify-developer.sh` — script bash (impuro, shell)
- No hay cambios en `pkg/` (puro)
## Tareas
### Fase 1: Fix
- [ ] 1.1 Agregar `initial_state` con `m.room.encryption` (algorithm `m.megolm.v1.aes-sha2`) al
JSON del `createRoom` en `notify-developer.sh`
### Fase 2: Tests
- [ ] 2.1 Test de shell que valide que el JSON del createRoom incluye encryption
### Fase 3: Docs
- [ ] 3.1 Cerrar issue, mover a completed
## Ejemplo de uso
Antes (sin E2EE):
```json
{
"is_direct": true,
"invite": ["@dev:server"],
"preset": "trusted_private_chat"
}
```
Despues (con E2EE):
```json
{
"is_direct": true,
"invite": ["@dev:server"],
"preset": "trusted_private_chat",
"initial_state": [
{
"type": "m.room.encryption",
"state_key": "",
"content": {
"algorithm": "m.megolm.v1.aes-sha2"
}
}
]
}
```
## Decisiones de diseno
- Se usa `m.megolm.v1.aes-sha2` que es el algoritmo estandar de Matrix para group encryption.
- El `preset: trusted_private_chat` se mantiene para los permisos (invite-only, admins).
- No se requieren cambios en el codigo Go — solo el script bash.
## Prerequisitos
Ninguno.
## Riesgos
- Bajo: cambio minimo y bien definido en un solo archivo.
+38
View File
@@ -0,0 +1,38 @@
import { test, expect } from "@playwright/test";
import * as fs from "fs";
import * as path from "path";
const REPO_ROOT = path.resolve(__dirname, "../..");
const NOTIFY_SCRIPT = path.join(
REPO_ROOT,
"dev-scripts/agent/notify-developer.sh"
);
test.describe("notify-developer.sh — E2EE en DM rooms", () => {
test("script existe y es ejecutable", () => {
expect(fs.existsSync(NOTIFY_SCRIPT)).toBe(true);
const stats = fs.statSync(NOTIFY_SCRIPT);
// Check executable bit (owner)
expect(stats.mode & 0o100).toBeTruthy();
});
test("createRoom incluye initial_state con m.room.encryption", () => {
const content = fs.readFileSync(NOTIFY_SCRIPT, "utf-8");
// Must have initial_state in the createRoom call
expect(content).toContain("initial_state");
expect(content).toContain("m.room.encryption");
expect(content).toContain("m.megolm.v1.aes-sha2");
});
test("createRoom mantiene preset trusted_private_chat", () => {
const content = fs.readFileSync(NOTIFY_SCRIPT, "utf-8");
expect(content).toContain("trusted_private_chat");
});
test("createRoom incluye is_direct e invite", () => {
const content = fs.readFileSync(NOTIFY_SCRIPT, "utf-8");
expect(content).toContain("is_direct");
expect(content).toContain("invite");
});
});