Estado: NOTA DE INVESTIGACIÓN (previa al plan). No es un sprint, sin código. Según docs/PROCESS.md §1.1, el análisis exploratorio vive en docs/research/ hasta que se compromete a un sprint. Fecha: 2026-07-23 Origen: un contrato de recepción de un taller de reparación de computadoras, descrito por el operador. Enuncia el patrón con más claridad que cualquier borrador de especificación, así que se registra aquí textual en sustancia.
---
0. El artefacto de origen
Cada cliente firmaba, con tinta, antes de que empezara cualquier trabajo. Los términos:
- Nosotros no rompimos tu computadora. Está rota — por eso estás aquí.
- Haremos nuestro mejor esfuerzo por arreglarla.
- Si no podemos, te ayudaremos a recuperar tus datos y a comprar un reemplazo.
- Nunca somos responsables de tus datos. Lo sentimos. Punto.
- No sabemos qué datos tienes, y no los vamos a saber — usamos programas
automatizados para cuidar la privacidad de nuestros clientes y nuestra propia salud mental.
Junto a la firma: fotografías de todo lo que trajeron, y de su identificación — para que, en caso de descubrimiento incidental de algo criminal, haya una identidad verificada que reportar.
Aquí hay tres mecanismos distintos haciendo trabajo, y solo uno de ellos es «un contrato».
---
1. El patrón — un concepto, tres caras
| Cara | Pregunta que responde | Forma en el taller |
|---|---|---|
| Declaración del estado inicial | ¿En qué estado lo recibí? | «ya está rota» más fotos de recepción |
| Consentimiento informado | ¿Entendieron y aceptaron los términos? | Contrato firmado, deliberadamente crudo |
| Registro de custodia | ¿Quién lo entregó, y se puede alterar este registro después? | Foto de la identificación; papel firmado |
1.1 La declaración del estado inicial es la misma epistemología que un control positivo
Sin un estado previo registrado no puedes distinguir «ya estaba fallando» de «tú la rompiste» — y la carga recae sobre quien no pueda demostrarlo. Esto es idéntico a la disciplina de pruebas de seguridad de HARVEST-PLAYBOOK.md §4 / PROCESS.md §14: un resultado de «bloqueado» no significa nada a menos que primero hayas demostrado que el ataque funcionaba contra el objetivo sin protección.
El mismo movimiento, tres veces, hecho a mano:
| Contexto | Estado inicial capturado | Mecanismo |
|---|---|---|
| Reparación de computadoras | Condición del aparato al recibirlo | Tinta y cámara |
| Remediación de WordPress (el trabajo de HostMonster) | Versiones de PHP, WP y plugins, configuración del anfitrión | Sondas de telemetría de wp-fix-internal (20 módulos de sonda — reportados por el agente de reconocimiento del ecosistema del 2026-07-23; no abiertos de forma independiente) |
| Convergencia de la bitácora de auditoría (Sprint 3.0) | UPDATE 1 sobre bases sin protección antes del arreglo | psql improvisado, 2026-07-23 |
Ninguno de estos es una pieza de biblioteca. Ese es el hueco (§3).
---
2. Qué ya existe (verificado en esta sesión)
| Componente | Ruta | Estado |
|---|---|---|
domain-agreements | crates/domain/agreements/src/lib.rs | Real, 1009 líneas. Agreement, AgreementType, AgreementVersion (contenido versionado más fechas de vigencia más VersionStatus), Consent, ConsentMethod |
| Evaluaciones | crates/operations/assessments | Real, 2333 líneas |
| Currículo | crates/domain/curriculum | Real, 2233 líneas |
application-assessments | crates/application/assessments | Delgado — 32 líneas |
| Entrega de medios con control de acceso | .claude/CLAUDE.md regla 10 | asset://<id> → ruta /media/... con token y control de acceso; /static es solo para recursos de compilación |
| Registro inalterable más borrado criptográfico | crates/foundation/audit-log/migrations/002_audit_hardening.sql:93-128 | subject_audit_keys, disparador de inmutabilidad que lanza excepción |
| Inmutabilidad del acuerdo firmado | buceo-feliz/src/diveops/operations/migrations/0065_signed_agreement_immutable_trigger.py | Solo en Django. prevent_signed_agreement_status_change() — RAISE EXCEPTION cuando OLD.status='signed' y el estado cambia; ERRCODE = 'check_violation' |
Qué NO existe
- Ninguna pieza de biblioteca de síntesis de voz, habla o audio. `find crates
-type d \( -name "tts" -o -name "speech" -o -name "voice" -o -name "audio" \)` → vacío.
- Ninguna evidencia de lectura en ninguna parte. No hay
scroll_depth,dwell
ni reading_time en ninguna pieza (las coincidencias de búsqueda caen en browser-automation/humanizer.rs y content/cms — sin relación).
- `Consent` registra el clic, nunca la exposición. Sus campos son
user_id,
agreement_version_id, consented_at, consent_method, ip_address, user_agent, withdrawn_at. ConsentMethod es {Checkbox, Click, Signature, Implicit, Api} — ninguna variante significa lectura declarada.
- No hay ninguna pieza de biblioteca de declaración del estado inicial.
- El disparador de inmutabilidad de Django no tiene contraparte en Rust. Este es
el segundo caso encontrado el 2026-07-23 en el que buceo-feliz impone inmutabilidad a nivel de base de datos que al lado de Rust le falta — el primero fue audit_logs (ver sprint-3.0-audit-log-fleet-convergence.md). El patrón amerita un barrido dedicado del ancestro en Django buscando imposiciones que la reescritura en Rust dejó caer.
---
3. El hueco que ninguno resolvió
La declaración del estado inicial no tiene dueño, pese a tres implementaciones a mano independientes. Una pieza de biblioteca sería dueña de: capturar un estado previo declarado, el reconocimiento de las dos partes, la inmutabilidad, y la comparación posterior (¿cambió el estado, y a favor de quién?).
Hueco secundario: el modelo de consentimiento demuestra consentimiento, no comprensión.
---
4. Prueba de consentimiento informado — de la más fuerte a la más débil
El planteamiento del operador importa: la meta es «vamos a hacer lo posible por dejarte más seguro», no un escudo de responsabilidad. Ese orden se sigue de la meta, no de la conveniencia probatoria.
1. Comprobación de comprensión — operations/assessments (2333 líneas, existe). Dos preguntas («¿cuál es la velocidad máxima segura de ascenso?», «¿qué haces si no puedes compensar?») valen más que cualquier telemetría de permanencia, jurídica y prácticamente. Es el único mecanismo que pone a prueba el objetivo real. 2. Lectura en voz alta (síntesis de voz) completada — el audio no se puede hojear, así que completarlo es evidencia más fuerte que la profundidad de desplazamiento; marca el ritmo del contenido sin una barrera punitiva; y es una adaptación de accesibilidad genuina en vez de un obstáculo. No existe ninguna pieza de biblioteca. 3. Participación en el currículo — domain/curriculum (2233 líneas, existe). El material de «cómo, por qué y qué podría pasar». 4. Declaración de lectura — profundidad de desplazamiento, permanencia por sección. Regístrala; nunca la conviertas en la única barrera.
Advertencia explícita sobre imponer una velocidad de lectura
Una barrera dura de «no puedes avanzar más rápido que N palabras por minuto» es la más débil de las cuatro y trae tres costos: se burla trivialmente (abre la pestaña, vete a caminar); es un peligro de accesibilidad (los lectores de pantalla, la dislexia, quienes no son hablantes nativos y quienes releen difieren todos legítimamente); y se lee como fabricada si alguna vez se examina — evidencia construida para una sala de juicio y no para la persona que está firmando. Es preferible el ritmo de la lectura en voz alta más una comprobación de comprensión, que son más fuertes en todos los ejes, incluido el que de verdad importa.
---
5. Registros de custodia y el conflicto de retención
La evidencia de recepción (fotos del equipo más la identificación) es ella misma información de alta sensibilidad — a menudo un conjunto de datos personales más rico que aquello que se recolectó para proteger. El control de un riesgo crea un activo nuevo que exige:
- entrega por la ruta de medios con token y control de acceso, nunca
/static(regla
10 del CLAUDE.md);
- una entrada en
audit_logspor cada vista — quién abrió la imagen de la
identificación, y cuándo;
- almacenamiento inalterable, porque evidencia que se puede editar en silencio no es
evidencia.
El conflicto: la evidencia de custodia tiene que conservarse y ser inalterable, mientras que las imágenes de identificación no deberían acumularse indefinidamente y pueden estar sujetas a solicitudes de borrado. Esas dos cosas apuntan en direcciones opuestas.
Ya resuelto en la `002`. El mensaje del disparador inalterable enuncia la resolución:
*El borrado de datos personales se hace por borrado criptográfico (`subject_audit_keys`), no mutando el renglón.*
Destruye la llave envuelta por sujeto: la identidad se vuelve irrecuperable mientras que el registro — que ocurrió una recepción, su cadena de huellas, su orden — queda intacto y demostrablemente sin alterar. La evidencia sobrevive; la identidad de la persona no tiene que hacerlo. Este es el patrón previsto para los registros de custodia.
5.1 La copia de trabajo — el activo de custodia de mayor valor
En el taller, la custodia no eran solo fotos e identificaciones. Una copia de los datos del cliente vivía en los discos de trabajo del taller, en la mesa, porque uno crea la imagen antes de trabajar — la alternativa es descubrir a media reparación que el disco de origen está fallando.
Esa copia de trabajo es el gemelo físico de la declaración del estado inicial: una foto previa al trabajo tomada para poder tanto demostrar el estado previo como restaurarlo. También es, por amplio margen, el activo más sensible del taller — un solo disco de mesa concentra los datos completos de muchos clientes, y su riesgo es agregado y no por ticket.
Así que una pieza de biblioteca de declaración del estado inicial tiene que modelar no solo un registro de condición sino también una copia de datos retenida opcional, con su propio ciclo de vida, distinto del del ticket:
- Existencia — ¿hay una copia, dónde está, en qué medio?
- Cifrado en reposo — el agregado vuelve esto materialmente distinto del riesgo de
un solo cliente.
- Retención — acotada por política, no por «hasta que se llene el disco».
- Desecho — destrucción verificada, registrada. Es el paso que más se aplaza
indefinidamente, porque nada lo fuerza y el disco sigue funcionando.
- Enlace — copia ↔ encuentro ↔ consentimiento, para que el desecho se pueda
disparar desde el cierre del ticket.
Pregunta abierta: ¿el contrato firmado del cliente cubre la retención de una copia, y por cuánto tiempo? Los términos de reparación deslindan responsabilidad sobre los datos; esa es una pregunta distinta de cuánto tiempo se guarda una copia y cuándo se destruye.
#### El disparador del desecho — entrega confirmada, no un temporizador
La práctica del taller lo responde, y lo responde mejor de lo que lo haría un temporizador de retención:
1. Datos recuperados y devueltos. 2. Se ayuda al cliente a organizarlos, se reinstalan los programas, se configura la máquina como estaba o mejor — de forma remota y por teléfono. 3. El cliente confirma su satisfacción. 4. Solo entonces se destruye la copia de trabajo — con dd, una sobrescritura completa, no un rm.
Un temporizador fijo no funciona aquí — confirmado en la práctica, no teorizado. Destruye la red de seguridad cuando el cliente todavía puede necesitarla: su restauración falla una semana después y la copia que lo habría salvado ya se fue. Los tiempos de regreso de los clientes son irreduciblemente impredecibles — días para uno, semanas para otro — así que cualquier periodo fijo de retención es o demasiado corto (destruye datos que alguien todavía necesita) o tan largo que deja de significar algo.
La barrera correcta es la entrega exitosa confirmada.
Y el respaldo tampoco debe ser un reloj — eso reintroduciría el mismo defecto un nivel más abajo. El respaldo real es un estado de contacto agotado: seguimiento intentado, vuelto a intentar, cliente ilocalizable. Eso lo dispara los intentos hechos y registrados, no los días transcurridos, y se mantiene defendible: el registro muestra qué se intentó antes del desecho, en vez de «se venció el temporizador». Así que la regla es «desechar al confirmar la entrega, o al registrar contacto agotado» — nunca por calendario.
Nótese que el desecho además está condicionado a un paso de servicio, no solo de datos: el cliente no está «confirmado» hasta que la máquina funciona como espera. Esa es una señal de terminación distinta de «los archivos se copiaron bien», y es la que importa.
#### El disparador que de verdad se dispara: la presión de capacidad
Reportado desde la práctica, y complica la versión ordenada de arriba. En la realidad el desecho a menudo ocurría porque el taller necesitaba el espacio. Los tickets se acumulaban sin cerrar, los discos de trabajo se llenaban, y con el tiempo alguien conectaba el disco y lo llenaba de ceros — dd if=/dev/zero of=/dev/sdX — porque la mesa necesitaba capacidad ese día.
Este es el tercer disparador honesto, y es el peor de los tres: lo mueve la necesidad operativa del taller y no el estado del cliente, así que puede destruir una copia de trabajo ligada a un ticket que sigue abierto. También es inevitable: los medios finitos lo garantizan tarde o temprano.
La conclusión de diseño no es «prevenir esto». La presión de capacidad no se puede legislar. Es que si el desecho no tiene disparador funcional ni cola visible, la presión de capacidad se vuelve el disparador por omisión — y entonces el desecho es incontrolado, y cae sobre lo que le haya tocado estar en el disco que alguien agarró.
Así que el trabajo del sistema es garantizar que cuando se dispare la presión de espacio, se dispare sobre copias elegibles:
- Seguir la elegibilidad de desecho de forma continua (entrega confirmada / contacto
agotado), para que siempre haya una reserva de datos que se puedan desechar con seguridad.
- Mostrarla como una lista de trabajo — «N copias elegibles, X GB recuperables» —
para que recuperar espacio sea la ruta fácil en vez de la improvisada.
- Hacer que desechar una copia no elegible exija una anulación explícita y
registrada, no un dd en silencio.
- Tratar una cuenta creciente de tickets sin cerrar como el indicador adelantado: los
tickets sin cerrar son lo que convierte la limpieza rutinaria en un borrado de emergencia.
Es la misma lección que el punto sobre latencia de la §6.5: un control incómodo se rodea. Si la ruta del desecho no es la forma más fácil de liberar espacio, no va a ser la forma en que se libere espacio.
Advertencia sobre el medio, para una implementación moderna: llenar de ceros con dd es sólido en discos magnéticos. En SSD o NVMe no es confiable — el nivelado de desgaste y el sobreaprovisionamiento pueden retener datos en bloques que la sobrescritura nunca toca. Los equivalentes modernos correctos son ATA Secure Erase / NVMe Format, o el borrado criptográfico: cifrar la copia de trabajo en reposo y destruir la llave. El borrado criptográfico es el mismo mecanismo que foundation-audit-log ya usa para datos personales (subject_audit_keys, 002:93-100) — así que la práctica de desecho físico del taller y el diseño de borrado que el marco ya tiene son la misma idea sobre medios distintos, y una pieza de biblioteca de copia de trabajo debería reutilizarla en vez de inventar una rutina de borrado.
5. Anotar el desecho en el ticket. 6. Cerrar el ticket.
El registro es lo que convierte el desecho de una afirmación en evidencia, y pertenece al mismo rastro inmutable que la recepción — los dos extremos de una sola cadena de custodia.
#### El ciclo de vida, expresado en piezas de biblioteca que ya existen
| Paso | Pieza de biblioteca |
|---|---|
| Ticket | domain-encounters — Encounter (Ticket/Cita/Visita) |
| Términos firmados | domain-agreements — Agreement + AgreementVersion + Consent |
| Fotos de recepción, identificación | content-assets, ruta /media con control de acceso (regla 10 del CLAUDE.md) |
| Nunca mirar los datos | application-dlp, rutas solo enmascaradas |
| Cada nota añadida, nunca editada | Registro inalterable de foundation-audit-log (002/003/004) |
| Borrado de la copia de trabajo | Borrado criptográfico vía subject_audit_keys |
| Nota del desecho → cerrar | operations-workflow — WorkflowStore::transition_if (comparar e intercambiar, cosechado en julio de 2026) |
La barrera del cierre es la interesante. «Anota el desecho, luego cierra» es una transición de estado con barrera: un ticket no debe llegar a closed a menos que exista un registro de desecho. Eso es exactamente el comparar-e-intercambiar atómico cosechado hacia operations-workflow este mes — UPDATE … WHERE id = $1 AND state = $expected, con la nota del desecho como precondición. Sin el comparar-e-intercambiar, dos actores pueden pasar los dos la comprobación en memoria y una transición se pierde; con él, un ticket no se puede cerrar por debajo de un desecho pendiente.
Así que el flujo de papel y mesa del taller se descompone en piezas de biblioteca que existen hoy, con exactamente un hueco: la declaración del estado inicial. Todo lo demás es ensamblaje.
5.1b El requisito de identificación era un control DISUASIVO, y eso no se mide por detecciones
Observado en la práctica: los clientes con algo que esconder no sacaban identificación, y se iban a otro lado.
La captura de identificación en recepción suele describirse como detectiva — «para que haya una identidad verificada que reportar». En operación su efecto dominante fue disuasivo: cambió quién entraba por la puerta. El material que habría disparado un reporte en su mayoría nunca llegó.
Esto derrota la métrica obvia. Preguntar «¿cuántas veces la foto de la identificación permitió un reporte?» podría plausiblemente devolver cero, de lo cual uno concluiría equivocadamente que la fricción no valía la pena. El valor vivía en los casos que nunca se presentaron. Un disuasivo no se puede medir por sus detecciones — el escenario contrafactual es invisible, y su éxito se ve idéntico a la irrelevancia.
Es la misma trampa epistémica que una prueba de seguridad vacua (PROCESS §14), invertida: allá, una prueba que pasa parece un mecanismo que funciona; aquí, una bitácora de hallazgos vacía parece un control innecesario. En los dos casos la ausencia de señal no es evidencia de ausencia de efecto, y en los dos casos el arreglo es razonar explícitamente sobre el contrafactual en vez de leer la métrica al pie de la letra.
Los controles además se componían. El requisito de identificación filtraba la base de clientes; una buena base de clientes hacía costeable la política de desecho sin prisas (§5.1) — puedes esperar indefinidamente a que alguien regrese cuando la gente que regresa es razonable. Un taller que se saltara el control de recepción enfrentaría peor material y presión hacia un temporizador fijo de retención, porque no podría costear la paciencia. Los controles río arriba compran holgura río abajo.
Implicación de diseño: el inventario de controles debería registrar la intención de cada control — preventivo, detectivo, disuasivo, correctivo — porque el método de evaluación cambia. Calificar un disuasivo por cuenta de detecciones siempre va a recomendar quitarlo.
5.2 Los niveles de acceso son relaciones distintas
La reparación en mesa y el soporte continuo de escritorio no son la misma autorización. En el taller las hacían personas distintas, en circunstancias distintas, iniciadas de forma distinta — el trabajo de mesa viene después de una recepción; el soporte de escritorio es una invitación continua.
Una propiedad de riesgo observada y útil: los clientes que querían soporte continuo de escritorio generalmente no eran los que tenían secretos. La autoselección significa que los clientes de mayor privacidad cargan la menor exposición continua — lo inverso de lo que resulta cuando el soporte se asigna en vez de elegirse. Cualquier modelo de consentimiento debería preservar esa propiedad en vez de aplanarla en una sola autorización general: AgreementType separados, alcances separados, revocación separada.
5.3 Evidencia simétrica — el registro también tiene que proteger a la parte más débil
El taller estaba cubierto por cámaras de punta a punta, excepto el baño. El planteamiento del operador: «así protegía a todos».
Las dos mitades importan.
Simetría. La grabación cortaba en todas las direcciones: la máquina del cliente demostrablemente no se cambió ni se abrió; el técnico quedaba protegido contra una acusación de robo o mal manejo; el dueño tenía una respuesta ante una disputa o una aseguradora. Un registro que solo le sirve a la parte que lo controla es vigilancia. Un registro que puede exonerar es protección. La meta de diseño es la segunda.
La exclusión es lo que legitima todo lo demás. La cobertura se extendía exactamente hasta donde tenía valor para resolver disputas y se detenía donde se volvía vigilancia por vigilancia — ninguna disputa se resuelve jamás con grabaciones del baño, y de recolectarlas solo sale daño. Definir deliberadamente la zona excluida es la diferencia entre un sistema de evidencia protector y un panóptico, y es el mismo movimiento que «usamos programas automatizados para nunca ver tus datos».
#### Por qué este es el argumento real a favor del registro inalterable
Esto replantea el trabajo de endurecer la bitácora de auditoría (Sprint 2.6 / 3.0) como algo distinto de una ceremonia de cumplimiento.
La evidencia de manipulación protege desproporcionadamente a la parte más débil, porque la parte más fuerte es precisamente la que tiene la capacidad de alterar el registro. Un empleado acusado de un acceso no autorizado puede apuntar al rastro de auditoría que muestra que no lo hizo — pero solo si quien lo acusa no pudo haberlo editado. Sin inmutabilidad, el registro defiende únicamente a quien tiene las credenciales de la base de datos.
Así que el RAISE EXCEPTION en vez de DO INSTEAD NOTHING, la cadena de row_hash, la seq monótona y el disparador de evento que impide que incluso el dueño de la tabla desactive el disparador (#163) no son teatro de auditoría. Son lo que vuelve el registro usable como defensa y no solo como acusación. Una bitácora de auditoría que la dirección puede reescribir en silencio vale menos que ninguna bitácora, porque carga la autoridad de la evidencia sin tener sus propiedades.
(Nota operativa para una construcción moderna: el video y el audio se gobiernan de forma distinta — en muchas jurisdicciones de Estados Unidos el video en áreas de negocio no privadas es ampliamente permisible con aviso, mientras que grabar audio está sujeto a leyes de consentimiento de una o de todas las partes. Un sistema que capture ambos debería tratarlos como alcances de consentimiento separados, no como un solo interruptor de «grabación».)
#### 5.3b Las cámaras se ganaban el sueldo a diario — que es por lo que funcionaron cuando hizo falta
No eran un sistema solo para incidentes. Eran una herramienta de trabajo:
- El personal del mostrador veía el piso para despedir a los clientes y notar a quien
estuviera esperando.
- El dueño, de viaje, manejaba la cámara motorizada para asistir a los técnicos de
forma remota — acercarse a una tarjeta y decir «es ese tornillo, ahí está». Asistencia experta remota, en uso diario.
Por eso funcionó de verdad la función de evidencia. Un sistema que solo se usa durante los incidentes se pudre en silencio: los lentes se ensucian, los ángulos se mueven, un disco se llena, una señal se cae — y nadie lo descubre hasta el día en que hace falta. Un sistema que alguien usa cada hora se verifica continuamente por el uso. El valor operativo es la comprobación de salud.
Esta es la tercera instancia en esta nota de un mismo principio:
| Control | ¿Valor operativo diario? | Resultado |
|---|---|---|
| Captura local rápida de evidencia (§6.5) | Sí — más rápida que la alternativa | Usada en cada paso; registro completo |
| Flujo de desecho (§5.1) | No — puro costo | Aplazado hasta que la capacidad forzó un borrado de emergencia |
| Cámaras (§5.3) | Sí — conciencia del mostrador, asistencia remota | Se mantuvieron apuntadas, encendidas y funcionando; usables como evidencia |
El principio: un control con valor operativo diario se mantiene funcional; un control que es puro costo se degrada hasta que una emergencia lo dispara. Esta es la forma operativa del Gate 3.4 («ninguna capacidad se publica a oscuras») — una capacidad con un consumidor real en la ruta de ejecución se mantiene viva; una sin consumidor se pudre por correcta que fuera al construirla.
Implicación de diseño para el trabajo de declaración de la flota (Sprint 3.0 / red-lab): una declaración que solo corre durante una auditoría se va a pudrir exactamente como una cámara de solo incidentes. Necesita un consumidor diario — un estado visible que alguien de verdad mire, conectado a una rutina existente — o va a estar verde-porque-no-corrió en vez de verde-porque-es-correcta. Construye el consumidor, no solo la comprobación.
(De paso: el flujo de asistencia remota con cámara motorizada es un caso de uso vivo para el trabajo en curso de grabación de video — `forge-nvr`, `frigate-box`, `operations-camera-discovery`. «El experto remoto se acerca y dirige a un técnico» es un requisito de producto real con un usuario conocido, no una hipótesis.)
El no-saber deliberado como arquitectura
«No sabemos qué datos tienes, y no los vamos a saber.» Casi todos los talleres implementan esto como una política que le dice al personal que no mire — lo cual no es un control. Implementado arquitectónicamente, sí lo es, y protege al técnico tanto como al cliente: la exposición incidental a material criminal es un riesgo laboral real, y minimizarla es un objetivo de ingeniería legítimo.
application-dlp ya encarna esto — el T9 del sprint 2.8 (test(dlp-sensor): T9 leak-safety — masked-only screen path emits no raw PAN) es precisamente «la máquina lo ve para que la persona no lo vea», expresado como una prueba de invariante de la §14. El descubrimiento incidental no se puede llevar a cero, y por eso existe el vínculo con la identidad: prepararse para el caso residual en vez de fingir que no existe.
---
6. Reúso entre dominios — una pieza de biblioteca, muchas caras
El mismo objeto con distinto AgreementType:
| Dominio | Acuerdo | Declaración del estado inicial | Custodia |
|---|---|---|---|
| Reparación de computadoras | Términos de reparación más deslinde sobre los datos | Condición del aparato al recibirlo | Fotos del equipo y de la identificación |
Buceo (scuba-fill-station, happydiving.mx, buceo-feliz) | Deslinde de responsabilidad, declaración médica | Nivel de certificación, aptitud médica a la fecha | Imagen de la tarjeta de certificación |
Encargo de seguridad (red-lab, infrastructure-security-scan) | Autorización escrita para probar / reglas de enfrentamiento | Estado del sistema antes de la prueba | Alcance y autoridad de quien firma |
| Remediación del marco (Sprint 3.0) | — | Estado inicial desplegado medido | Registro de evidencia por base de datos |
El caso de seguridad ya tiene una barrera parcial: ScanTarget / ActiveScanGrant en infrastructure-security-scan son unas reglas de enfrentamiento expresadas como un tipo. Esa es la forma que quieren los demás.
---
6.5 Restricción de despliegue — en casa, siempre
El sistema de tickets del taller corría en una computadora del taller. No en un servicio de asistencia en la nube.
La razón principal era operativa, no filosófica: tenía que estar en casa para funcionar. El internet de un taller se cae igual que el de cualquiera. Si el sistema de tickets está alojado en otro lado, entonces durante una caída no puedes recibir a un cliente, no puedes buscar de quién es la máquina que está en la mesa, y no puedes imprimir una orden de trabajo — con una persona parada en el mostrador. Lo mismo aplica cuando el que tiene la caída es el proveedor, cosa que ni controlas ni puedes explicarle al cliente que está esperando. El software de punto de servicio que exige una red para funcionar está no disponible exactamente cuando un negocio pequeño no puede permitírselo.
La privacidad es el beneficio secundario, y es real: un sistema de tickets en la nube significa que el nombre del cliente, su aparato, la descripción del síntoma y cualquier foto de recepción adjunta viven en la base de datos de un proveedor, bajo la exposición a filtraciones de ese proveedor, sujetos a la política de retención de ese proveedor — nada de lo cual el taller controla ni puede describirle honestamente al cliente. Pero lo que fuerza la decisión es la disponibilidad.
Y la velocidad es lo que hizo que el proceso de verdad se siguiera. Tenerlo en casa era lo bastante rápido como para que las fotos se subieran y el sistema se usara en cada uno de los pasos — no solo en la recepción. Las imágenes hacia una máquina en el mismo cuarto son prácticamente instantáneas; el mismo flujo contra un servicio de asistencia alojado, sobre el enlace de un negocio pequeño, es lo bastante lento como para que el personal empiece a saltarse pasos bajo la presión del mostrador. Los pasos que se saltan nunca son al azar: son los que no tienen recompensa inmediata para quien hace el trabajo — que son precisamente la captura de evidencia (la foto de recepción, la nota de condición) que solo importa después, en una disputa.
Esto vuelve la latencia un mecanismo de cumplimiento, no una comodidad. La completitud de la evidencia vino de la velocidad, no de la política. Un control lento es un control que se rodea, y este es el mismo modo de falla que la puerta de avisos de integración continua siempre en rojo que se encontró el 2026-07-23 (28 hallazgos contra ignore = [], uno sin arreglo disponible): un control incómodo se vuelve un control que no se aplica, y su salida deja de leerse por completo.
Cuarto: respaldos físicos que tú controlas. Tenerlo en casa significa que el respaldo es la base de datos de verdad, no el formato de exportación de un proveedor — así que se puede copiar a un medio que tienes físicamente, llevarlo fuera del sitio, y restaurarlo y verificarlo. Esa última parte es el punto: un respaldo sin probar es una afirmación, no una prueba, y un volcado local de fidelidad completa se puede restaurar en otra caja y revisar, donde una exportación de un servicio en la nube a menudo no se puede validar de forma significativa en cuanto a completitud. También sobrevive a los modos de falla que una exportación no: la quiebra del proveedor, la suspensión de la cuenta, una disputa de facturación, un cambio de precio, la descontinuación de una API. Para un taller cuyo negocio es la recuperación de datos, tener tu propia copia recuperable no es una preferencia.
Las reglas de diseño que se siguen:
- Todo lo que esté en la ruta del punto de servicio tiene que funcionar sin red.
Trata una dependencia de red en la recepción, el consentimiento o la búsqueda como un defecto, no como un intercambio.
- La captura de evidencia tiene que ser lo bastante rápida como para usarse siempre,
bajo la presión del mostrador. Si no lo es, el registro va a quedar incompleto de una forma que nadie nota hasta que hace falta. Presupuéstalo como requisito duro, y mídelo — no lo supongas.
- Los respaldos tienen que ser de fidelidad completa, guardados localmente y
probados restaurando. No una exportación; los datos. Una restauración que nunca se ha hecho está sin verificar — márcala como tal, y pruébala.
- Los medios de custodia y los registros de consentimiento tienen que estar
incluidos en ese conjunto de respaldo. Son los artefactos legales; perderlos es perder la evidencia que todo el diseño existe para producir.
Este es el principio operativo que atraviesa todo el portafolio, y aquí ya es lo que hay por omisión: Postgres autoalojado en una jaula local, sin Docker, privacy-explorer atado a 127.0.0.1, la especificación de actuación de escritorio local primero, la ruta hacia integración continua autoalojada. Consistencia, no coincidencia.
Consecuencias de diseño para cualquier cosa construida desde esta nota:
- Los medios de custodia (fotos del equipo y de la identificación) tienen que poder
guardarse y servirse enteramente en sitio — sistema de archivos local o almacenamiento compatible con S3 en sitio, nunca una red de distribución de terceros. La ruta /media con control de acceso ya lo soporta.
- La síntesis de voz tiene que tener una ruta sin conexión. Esto sube la pregunta
abierta 3 de preferencia a restricción: una tienda de buceo en un bote y un mostrador de reparación durante una caída necesitan las dos que la lectura en voz alta funcione sin conectividad. Un diseño que solo use voz en la nube falla en el caso de uso principal.
- Las evaluaciones de comprensión tienen que correr localmente — sin ningún servicio
externo de cuestionarios.
- El registro de consentimiento es el artefacto legal. Tiene que sobrevivir
enteramente a la pérdida del proveedor, porque no hay proveedor.
- Nótese que el sistema de tickets en sí ya es una pieza de biblioteca aquí:
domain-encounters es dueño de Encounter (Ticket / Cita / Visita), y support es un sistema de tickets multiinquilino funcionando, construido como pura composición de piezas de biblioteca. Una recepción de taller es un Encounter con un acuerdo adjunto, una declaración del estado inicial y medios de custodia.
---
7. Preguntas abiertas (para el Gate 1.5, si esto se vuelve un sprint)
1. ¿La declaración del estado inicial es su propia pieza, o una extensión de domain-agreements? 2. ¿Consent gana un registro ligado de ReadingAttestation, o variantes nuevas de ConsentMethod, o las dos cosas? (Un registro ligado preserva la enumeración existente y carga evidencia más rica.) 3. Síntesis de voz: ¿una pieza nueva, o un adaptador sobre un proveedor existente? La capacidad sin conexión importa — una tienda de buceo en un bote puede no tener conectividad. 4. ¿Cuál es la retención por omisión de los medios de custodia, y qué dispara el borrado criptográfico? 5. ¿El resultado de la evaluación debería ser obligatorio para acuerdos de alto riesgo (buceo) y opcional para los de bajo riesgo (términos de servicio)? ¿Política por AgreementType? 6. Barrer buceo-feliz buscando otros invariantes impuestos por la base de datos que la reescritura en Rust dejó caer — dos encontrados hasta ahora (audit_logs, acuerdos firmados), lo que sugiere una clase y no dos incidentes.
---
8. Entradas de inventario de controles que esto implica
agreements.signed_immutable— el estado de un acuerdo firmado no puede cambiar; la
revocación exige un documento firmado nuevo. Caso de mal uso: hacer UPDATE al estado de un acuerdo firmado. Sonda: intentarlo, demostrar que falla, demostrar que tenía éxito antes de que existiera el disparador. Hoy impuesto solo en Django.
custody.media_gated— las imágenes de identificación y de equipo nunca son
alcanzables fuera de la ruta con control de acceso.
custody.view_audited— cada vista de medios de custodia produce un renglón de
auditoría.
consent.version_pinned— el consentimiento referencia unaAgreementVersion
inmutable; los términos no se pueden alterar después de la firma.