← Volver al recorridoDescargar informe# MiniSum2: expediente técnico consolidado de reconstrucción y edición de pesos
**Versión del informe:** 1.0, consolidación retrospectiva de las dos intervenciones del 5 de noviembre de 2026.
**Finalidad:** aportar un procedimiento reproducible, artefactos verificables y límites explícitos para una auditoría técnica externa.
**Autor del modelo de partida:** Edgar.
**Ejecutor del análisis:** agente identificado por los metadatos de la sesión como GPT-6 Astra, esfuerzo de razonamiento `high`, en T3 Code mediante el harness de Codex. Esta identificación es declarativa; no es una atestación independiente del proveedor.
Este documento integra y rectifica los informes parciales anteriores. Los informes históricos, el intento fallido, las listas de resultados y el original se conservan. La revalidación realizada para este expediente no se presenta como si hubiese ocurrido antes de las intervenciones.
## 1. Dictamen técnico acotado
Sobre un checkpoint de 201.664 parámetros se construyó un ejecutable inferido, se localizaron tres errores en un dominio finito y se obtuvieron dos versiones mediante edición directa de una columna de 64 pesos. Se verificó el siguiente resultado:
| Versión | Aciertos exactos | Errores | Regresiones respecto de la anterior |
|---|---:|---:|---:|
| Original, ejecutado con la arquitectura reconstruida | 9.997/10.000 | 3 | No aplica |
| V1: atenuación de una columna | 9.999/10.000 | 1 | 0 |
| V2: proyección de esa misma columna | 10.000/10.000 | 0 | 0 |
El dominio es el conjunto de **parejas ordenadas de enteros de 0 a 99**, escritas sin ceros de relleno, con generación determinista por argmax. El criterio exige texto exacto y emisión de fin de secuencia. No se observaron regresiones en este dominio. No se evaluó la capacidad general de sumar otros números o formatos.
Las tres operaciones inicialmente incorrectas fueron:
| Operación | Original | V1 | V2 | Referencia calculada aparte |
|---|---|---|---|---|
| `9+0` | `00` | `9` | `9` | `9` |
| `90+9` | `100` | `99` | `99` | `99` |
| `93+9` | `101` | `101` | `102` | `102` |
La conclusión defendible es **corrección exhaustivamente comprobada en el dominio especificado, bajo el ejecutable reconstruido**. No es una demostración de identidad con el programa original, de generalización fuera del dominio, de recuperación del algoritmo completo aprendido ni de ausencia de otros fallos en cualquier contexto.
## 2. Qué acredita este expediente y qué no
Se distinguen cinco clases de evidencia:
| Clase | Significado | Ejemplos |
|---|---|---|
| Artefacto inspeccionable | Puede leerse y calcularse de nuevo | Checkpoints, tensores, código, particiones, salidas por operación |
| Registro histórico generado durante el trabajo | Describe una ejecución o un hito | Trazas, JSON de evaluación, congelación, tiempos de la fase 2 |
| Comprobación retrospectiva | Se realizó después, para esta consolidación | Reejecución de los tres `.pt`, captura de entorno, verificación de fórmulas |
| Metadato declarado | Lo proporciona la sesión, sin atestación independiente | Nombre del agente y harness, permisos disponibles |
| Estimación | Aproximación no medida | Orden de magnitud de la inspección inicial anterior al primer hito |
Los hashes prueban identidad de contenido respecto de una huella; **no prueban por sí solos quién creó un archivo, cuándo lo creó ni que no hubiese otras acciones**. Los registros no están firmados ni tienen un sello de tiempo externo. Los mismos agentes que hicieron el trabajo generaron los registros. La revalidación actual también la realiza el mismo agente: proporciona reproducibilidad interna, no sustituye una auditoría independiente.
No existe en este paquete un registro exhaustivo, inmutable y firmado de todas las llamadas a herramientas, del tráfico de red, del acceso al sistema de archivos o de cada versión intermedia del código. La conversación original constituye una fuente contextual adicional que el auditor debería conservar por separado. No se fabricó una transcripción para cubrir esos vacíos.
## 3. Material recibido y contexto previo
El material técnico de MiniSum2 aportado fue un único archivo, `MiniSum2-final.pt`, de 817.449 bytes. El usuario informó que era un modelo construido desde cero para sumar y que algunas sumas fallaban. No proporcionó inicialmente ejemplos concretos de fallos.
El agente conocía, por tanto, la **tarea semántica de suma**. Además disponía de conocimiento general sobre transformers, Python y aritmética, y de la conversación previa sobre una técnica de edición de pesos. Las instrucciones generales de la sesión mencionaban proyectos MiniSum y la existencia de una interfaz de prueba, pero no incluían el código ejecutable de este modelo. No se consultaron esos proyectos.
No fue un experimento de interpretación ciega de números sin contexto: la finalidad de sumar y las respuestas aritméticas usadas para evaluar estaban disponibles. La búsqueda de arquitectura y la selección de intervenciones utilizaron ese conocimiento.
### 3.1. Información que no se proporcionó
| Elemento | Estado |
|---|---|
| Clase del modelo y método `forward` originales | No proporcionados |
| Configuración de cabezas, activación, epsilon y orden de cálculo | No proporcionada |
| Tokenizador, vocabulario y significado de índices | No proporcionados |
| Código original de generación y decodificación | No proporcionado |
| Datos de entrenamiento, validación o prueba originales | No proporcionados |
| Rango de operandos usado durante el entrenamiento | No proporcionado |
| Semillas, pasos, lote, optimizador, historial de pérdidas | No proporcionados |
| Estado del optimizador o checkpoint anterior | No presentes en el diccionario de tensores inspeccionado |
| Arquitectura de referencia ejecutable con PyTorch | No disponible en el material aportado |
| Evaluador independiente y resultados originales certificados | No proporcionados |
| Tiempos de entrenamiento, consumo energético y hardware original | No proporcionados |
En un primer momento se pidió código adicional como si fuese un requisito. El usuario aclaró que esperaba deducirlo desde el adjunto. Se continuó sin recibir ese código. La petición inicial fue una limitación del planteamiento, no una imposibilidad técnica demostrada.
### 3.2. Relación con el experimento mencionado en la conversación
La investigación externa fue la motivación para intentar una edición directa de parámetros. Este expediente acredita el procedimiento local de MiniSum2; no certifica la identidad, fecha, resultados o protocolo de aquella publicación. No contiene sus materiales experimentales ni una comparación controlada entre ambos trabajos. La similitud que aquí se sostiene es metodológica y general: inspeccionar un modelo y modificar un pequeño conjunto de pesos sin ejecutar entrenamiento. No se presenta como una réplica científica del experimento externo.
## 4. Entorno, capacidades y aislamiento real
Los comandos se ejecutaron mediante `exec_command` sobre un entorno Linux que exponía el espacio de trabajo `/home/edgar/General`. Los artefactos del experimento quedaron en `minisum2-reparacion-65m1o0sz`. Se utilizó Python para leer pesos, ejecutar inferencia y evaluar; Node para verificar el motor JavaScript del visor.
La sesión disponía de ejecución de comandos, lectura y escritura de archivos y herramientas de red. Las restricciones de no consultar otros proyectos y no reentrenar se cumplieron como restricciones del procedimiento; **no hubo un aislamiento hermético por diseño que impidiese técnicamente cualquier acceso fuera del experimento**. No se debe afirmar que el agente carecía físicamente de acceso a otros archivos o a internet.
Durante las intervenciones sobre MiniSum2 se usaron el adjunto y los archivos creados para este análisis. La búsqueda web de la investigación de referencia perteneció a la conversación anterior; no se descargó un modelo sustituto ni se obtuvo código de MiniSum2 mediante esa búsqueda. No se usaron subagentes para reparar MiniSum2 ni se lanzó otro agente por CLI para decidir el parche.
No se instalaron paquetes o servicios. No se inició un servidor de inferencia: se ejecutaron programas por lotes. El visor es un HTML autónomo, no una aplicación desplegada en un servicio. No se realizó un entrenamiento largo ni se apagaron servicios del equipo.
### 4.1. Captura de versiones efectuada para la auditoría
La captura `auditoria_total/ENTORNO_CAPTURADO_AHORA.json` se tomó a las **22:48:02 UTC del 5 de noviembre de 2026**, después de ambas intervenciones. Se etiqueta como retrospectiva: no sustituye una captura de entorno previa que no se hizo.
| Componente | Valor observado al capturar |
|---|---|
| Sistema | Linux |
| Kernel | `7.0.0-42-generic` |
| Arquitectura del proceso | `x86_64` |
| libc informada por `platform` | glibc 2.43 |
| Python | CPython 3.14.4, compilado con GCC 15.2.0 |
| Ejecutable | `/usr/bin/python3` |
| NumPy | 2.3.5 |
| SciPy | 1.16.3 |
| Node | v22.22.1 |
| Detección de PyTorch en ese intérprete | `find_spec('torch')` devuelve ausencia |
| Variables utilizadas en los cálculos principales | `OPENBLAS_NUM_THREADS=1`, `OMP_NUM_THREADS=1` |
La configuración de NumPy informa una dependencia llamada `blas`, versión 3.12.1, detectada mediante pkg-config; el campo específico de configuración OpenBLAS aparece como desconocido. No se transforma esa información en una afirmación no verificada sobre el proveedor BLAS o el número real de hilos internos en cada llamada. Las variables muestran la configuración solicitada.
No se midieron modelo de CPU física, GPU disponible, RAM, consumo eléctrico, temperatura o rendimiento de todo el equipo. Las operaciones escritas son de NumPy/SciPy y JavaScript en CPU; no hay llamadas CUDA en esos programas. Eso no demuestra que el equipo no tenga GPU. Tampoco se verificó que este runtime fuese físicamente la mini PC descrita en las instrucciones generales del usuario, ni si estaba o no dentro de un contenedor.
La ausencia de PyTorch se refiere al intérprete usado; no implica que no exista otro entorno con PyTorch. No se buscaron otros entornos. Los costes, tokens o tiempo de cómputo del modelo asistente en infraestructura del proveedor no se midieron y no se incluyen en los tiempos de Python/Node.
## 5. Custodia y extracción del checkpoint
El original se identificó mediante:
```text
SHA-256: 51a194bae320043f3aca9d7a8a5c9566250a82afcae646b75f51c5e923f2ccd0
Tamaño: 817449 bytes
```
Se copió a `original/MiniSum2-final.pt`, se restringió su escritura mediante permisos de solo lectura y se comprobó repetidamente su hash. Esa medida reduce modificaciones accidentales; no equivale a un soporte físicamente inmutable.
Se abrió el contenedor ZIP y se inspeccionaron `modelo/data.pkl`, `modelo/data/0` a `modelo/data/44`, el orden de bytes y otros metadatos. Se desensambló el pickle mediante `pickletools.dis`. Una salida larga de ese desensamblado quedó truncada en la respuesta de la herramienta; por ello no se utilizó como único inventario del archivo.
Se implementó un lector restringido. `_rebuild_tensor_v2` se sustituyó por una función que devuelve descriptores; `FloatStorage` se interpretó como una etiqueta; `OrderedDict` se admitió como contenedor y se rechazaron otras referencias globales. No se usó un `pickle.load` irrestricto ni se ejecutó un `forward` suministrado por el archivo.
Los almacenamientos se leyeron con `np.frombuffer(..., dtype='<f4')`. Se comprobaron little-endian, offset cero, forma, tamaño y strides contiguos. Se encontraron 45 tensores float32, 201.664 valores finitos, sin NaN ni infinitos. Los datos de los tensores suman 806.656 bytes. La diferencia respecto al tamaño del `.pt` corresponde al contenedor y sus metadatos.
## 6. Arquitectura observada e hipótesis de ejecución
Los nombres y las formas sí estaban en el archivo. Sus semánticas completas no.
| Componente | Forma | Parámetros |
|---|---|---:|
| `wte.weight` | 15 × 64 | 960 |
| `wpe.weight` | 11 × 64 | 704 |
| Cuatro bloques | 49.728 por bloque | 198.912 |
| `ln_f.weight`, `ln_f.bias` | 64 cada uno | 128 |
| `cabeza.weight` | 15 × 64 | 960 |
| Total | 45 tensores | **201.664** |
En cada bloque:
| Tensor o grupo | Forma | Parámetros |
|---|---|---:|
| Dos LayerNorm, cada una con gamma y beta | Cuatro vectores de 64 | 256 |
| `attn.qkv.weight` | 192 × 64 | 12.288 |
| `attn.proy.weight` | 64 × 64 | 4.096 |
| `mlp.0.weight` y `mlp.0.bias` | 256 × 64 y 256 | 16.640 |
| `mlp.2.weight` y `mlp.2.bias` | 64 × 256 y 64 | 16.448 |
| Total por bloque | | **49.728** |
Se propuso un transformer causal de cuatro bloques, ancho 64 y MLP 64→256→64. El número de cabezas, GELU y la normalización previa fueron hipótesis contrastadas o decisiones de reconstrucción, no campos de configuración recuperados literalmente del checkpoint.
No se ensayaron todas las arquitecturas posibles compatibles con esas matrices. Se supusieron, entre otras cosas, Q/K/V contiguas en ese orden, posiciones sumadas al embedding, máscara causal con diagonal, residuales y epsilon `1e-5`.
## 7. Especificación de la inferencia reconstruida
Para un lote de índices con forma B×T:
```text
X₀[t] = Wte[token[t]] + Wpe[t]
```
Para cada bloque ℓ:
```text
U = LN1(X)
[Q,K,V] = U Wqkvᵀ
A = softmax(mask_causal(QKᵀ / sqrt(dh)))
R = X + concat_heads(AV) Wproyᵀ
H = GELU(LN2(R) W0ᵀ + b0)
X = R + H W2ᵀ + b2
```
Salida:
```text
logits = LN_final(X) Wcabezaᵀ
```
La orientación de cada matriz es `(salida, entrada)`. Con cuatro cabezas, `dh=16` y el divisor de atención es 4. La máscara bloquea posiciones futuras, incluye la propia posición y utiliza −infinito en los elementos excluidos. Se resta el máximo antes de exponenciar para estabilizar softmax.
```text
LN(x) = gamma ⊙ (x − mean(x)) / sqrt(mean((x−mean(x))²) + 1e−5) + beta
GELU(x) = 0.5 x [1 + erf(x/sqrt(2))]
```
Se usaron pesos y activaciones NumPy principalmente float32. No se afirma equivalencia bit a bit con un backend PyTorch desconocido. La posterior comprobación JavaScript compara las respuestas discretas y la terminación, no cada operación de coma flotante.
El generador elige argmax de la última posición, añade el token y repite hasta el límite configurado. La implementación NumPy por lotes puede seguir calculando después de emitir fin; el decodificador corta en el primer token 2. Esos tokens posteriores no pertenecen a la respuesta evaluada. Este criterio se mantuvo constante entre las versiones.
## 8. Reconstrucción del vocabulario y del formato
Se examinaron las normas de las filas de embeddings y salida para orientar hipótesis. Las normas no identifican por sí mismas el significado de un índice. Se generaron además continuaciones exploratorias desde índices individuales; no se puntuaron como una evaluación formal de suma.
Se contrastaron 96 combinaciones iniciales: cuatro números de cabezas —1, 2, 4, 8—, tres activaciones —GELU, ReLU, SiLU—, dos asignaciones de más/igual, presencia o ausencia de inicio y cifras normales o invertidas. Se utilizaron estas seis operaciones:
```text
(12,34), (45,67), (10,20), (99,99), (23,46), (37,58)
```
La puntuación de esa exploración aceptaba varias representaciones de la respuesta, incluidas inversiones y relleno. Era una heurística de selección, no la métrica definitiva. Se guardaron los resultados en `hipotesis_iniciales.json`, pero no un script autónomo de esa primera llamada. Su reconstrucción cronológica se apoya también en la conversación.
La correspondencia funcional adoptada fue:
| ID | Símbolo |
|---:|---|
| 0 | No determinado |
| 1 | Inicio |
| 2 | Fin |
| 3 | `+` |
| 4 | `=` |
| 5…14 | `0`…`9` |
Ejemplo: `9+0=` se codifica `[1,14,3,5,4]`; `9` seguido de fin, `[14,2]`. No se confirmó que ID 0 fuese relleno, aunque se consideró esa posibilidad.
Se generaron luego 256 muestras entre 10 y 99 con `default_rng(20261105)`: 254 pares distintos, pues hubo dos repeticiones. Se comprobaron 22 configuraciones con criterio de texto exacto y fin:
| Cabezas | GELU | ReLU | SiLU |
|---:|---:|---:|---:|
| 1 | 10/256 | 1/256 | 1/256 |
| 2 | 21/256 | 6/256 | 12/256 |
| 4 | **256/256** | 23/256 | 156/256 |
| 8 | 79/256 | 9/256 | 55/256 |
| 16 | 19/256 | 5/256 | 13/256 |
| 32 | 8/256 | 4/256 | 13/256 |
| 64 | 6/256 | 2/256 | 10/256 |
La configuración adicional de cuatro cabezas con GELU aproximada mediante tanh también acertó 256/256. Esa comparación no permite identificar la variante original de GELU. Se eligió `erf` para el estudio principal.
En 106 pruebas de operandos de una cifra y casos mixtos, rellenar a dos cifras produjo 15 aciertos; el formato natural, 105. Se eligió el formato natural. El fallo observado fue `9+0→00`.
## 9. Dominio, métrica y separación de datos
Se definió D={(a,b): 0≤a,b≤99, a,b enteros}. D tiene 10.000 parejas **ordenadas**. Se examinan ambos órdenes; no se supone que el ejecutable sea conmutativo porque la operación matemática lo sea.
Para cada caso se almacenan operandos, texto generado, tokens, indicador de fin y corrección. El criterio es:
```python
correcta = (texto_generado == str(a + b)) and fin_de_secuencia
```
La expresión `a+b` pertenece al evaluador. El `forward` y el generador reciben índices de operandos y símbolos, no la suma calculada. La red no consulta una tabla de respuestas. La existencia de etiquetas sí influye en el diagnóstico y en la aceptación de candidatos: este no es un procedimiento sin datos o sin supervisión informativa.
Se permiten cuatro tokens nuevos, suficientes para una respuesta de hasta tres dígitos y fin dentro de D. No se usa muestreo, temperatura, beam search ni arreglo posterior de las cifras. `00` no se acepta como `9`.
La partición histórica incorporó 360 pares ya examinados —254 de reconstrucción y 106 de formato— a diagnóstico, y completó 2.500 mediante una permutación de los restantes con semilla 20261106. Los otros 7.500 se denominaron reservados. Las listas son disjuntas y su unión es D.
### 9.1. Defecto de exposición detectado retrospectivamente
La partición omitió los seis casos exploratorios iniciales y sus versiones invertidas al construir la lista de casos vistos. Ocho quedaron en la reservada nominal:
```text
(10,20), (12,34), (23,46), (37,58),
(45,67), (54,76), (73,85), (99,99)
```
Los ocho eran correctos tanto en el original como en V1. Una exclusión conservadora deja 7.492 pares sin exposición previa identificada. En estos, el original obtiene 7.490 aciertos y V1 7.491. `90+9` no figura entre los ocho y sigue siendo una corrección observada en una entrada nueva respecto a la exploración.
La exclusión es posterior, no una partición preinscrita originalmente limpia. La nota histórica de `particion.json` que afirmaba que todos los casos anteriores estaban en diagnóstico es incorrecta y queda rectificada por `auditoria_particion.json` y este informe. Se conservó para no reescribir la historia de la ejecución.
V2 se diseñó cuando ya se conocían los resultados de D, incluido `93+9`. Su evaluación es exhaustiva, pero no independiente de la selección. No se utiliza el 100 % sobre D como una estimación de generalización a una población mayor.
## 10. Primera intervención: diagnóstico y atribución
El original obtuvo 2.499/2.500 en diagnóstico. Su único fallo allí fue `9+0→00`. Se instrumentó el modelo para observar atención, contribuciones de cabezas, residuales, activaciones MLP y la normalización final.
Se trazaron diez entradas: `9+0`, `0+9`, `8+0`, `9+1`, `0+0`, `4+5`, `5+4`, `1+8`, `8+1`, `9+9`.
Para el primer dígito de `9+0`:
```text
z(0) = 6.9255275726
z(9) = 6.2630691528
z(9) − z(0) = −0.6624584198
```
Se utilizó una dirección de lectura que compara el símbolo deseado con el elegido. Para dos filas de salida ua y ub:
```text
d = ua − ub
c = d ⊙ gamma_final − mean(d ⊙ gamma_final) · 1
s(x) = sqrt(var(x) + epsilon)
m(x) = [cᵀx] / s(x) + dᵀ beta_final
```
Si la neurona j escribe hj wj en el residual, su contribución al numerador es Cj=hj cᵀwj. Esta descomposición no equivale a una atribución causal completa en capas tempranas: hay operaciones posteriores no lineales. En el último MLP permite localizar aportaciones directas, pero modificar una columna también puede cambiar la escala de LayerNorm y las generaciones siguientes.
Para comparar 9 frente a 0 en el caso fallido, la neurona 244 del último MLP tenía activación 0,57014537 y C244≈−0,27007177. Era la mayor contribución negativa directa de ese MLP; las siguientes eran aproximadamente −0,06749, −0,05057 y −0,04929. Otras neuronas compensaban parte de esas señales: la suma Cj del bloque era −0,08542567.
La neurona también se activaba en operaciones correctas. No se identificó como una unidad exclusivamente defectuosa ni se demostró que codificase semánticamente cero o llevada.
Se realizaron 16 ablaciones temporales de cabezas —cuatro por bloque— sobre `9+0=`. Se anuló la salida de una cabeza en todas las posiciones y se observó el primer token. No se evaluaron esas 16 alternativas sobre todo D ni se exportaron como candidatos. No hubo un control aleatorio de pesos con magnitud equivalente ni una curva sistemática de intensidades.
## 11. Primera intervención: parche, congelación y resultado
Se especificó un único candidato de pesos para esa fase:
```python
W = modelo.w['bloques.3.mlp.2.weight']
W[:, 244] *= np.float32(0.5)
```
Los índices empiezan en cero: cuarto bloque, columna 245 en nomenclatura ordinal. La matriz es 64×256; una columna contiene 64 conexiones de salida. No cambia el número de neuronas ni la arquitectura.
El factor 0,5 fue una decisión heurística, no el resultado de optimizar una pérdida ni una afirmación de optimalidad. Reduce toda la contribución de esa neurona conservando su dirección. Se modificó el 0,0317359568391 % de las posiciones de parámetros.
El margen 9−0 de `9+0` pasó a +1,2919855118 y la salida fue `9` con fin. El candidato obtuvo 2.500/2.500 en diagnóstico, sin regresiones. Se guardó y se registró el hash del NPZ en `CONGELADO.json` a las 21:20:37.540811 UTC, antes de evaluar la reservada nominal.
En los 7.500 casos de esa partición el original acertó 7.498 y V1 7.499. La nueva corrección fue `90+9`: `100→99`. Quedó `93+9→101`. La salvedad de los ocho casos expuestos se aplica a cualquier descripción de esta validación.
## 12. Segunda intervención: diagnóstico condicionado al prefijo generado
Se partió del NPZ verificado de V1, preservando V1 y el original. Para el diagnóstico se generaron primero dos tokens con el propio modelo y se observó la siguiente decisión. En `93+9` el prefijo generado fue `10`; no se impuso mediante la respuesta calculada externamente.
Se observaron `93+9`, `92+9`, `94+9`, `9+93`, `93+8`, `93+10`, `85+17`, `91+11`, `92+10` y `99+3`. En el caso objetivo:
```text
z(1) = 8.0201063156
z(2) = 7.3101406097
z(2) − z(1) = −0.7099657059
```
Con la dirección c definida ahora para 2 frente a 1, la misma columna 244 resultó la mayor contribución negativa directa del último MLP: h244≈0,66107035 y C244≈−0,11824127. Los controles mostraban márgenes distintos y respuestas correctas; no se asumió que todos debían favorecer 2, porque algunos terminan correctamente en 1 o 3.
La elección de la dirección utiliza el conocimiento del dígito correcto y del equivocado. Se trata de diagnóstico guiado por un error, no de lectura de pesos sin información de tarea.
## 13. Segunda intervención: intento fallido y cambio de estrategia
El primer candidato de esta fase redujo otra vez la columna de V1 a la mitad: wA=0,5wV1=0,25wOriginal. Se guardó su especificación y su NPZ antes de la comprobación.
Se ensayaron los diez casos de diagnóstico más `9+0`, `90+9`, `0+0` y `99+99`. Acertó 13/14; `93+9` siguió siendo `101`, con margen 2−1 de −0,2250418663. Se descartó sin ejecutar una evaluación de 10.000 casos que no podía satisfacer el objetivo. Los pesos y resultados fallidos se conservan.
No se continuó reduciendo coeficientes sucesivamente hasta encontrar un acierto. El segundo candidato volvió a partir de V1 y utilizó una operación diferente: retirar la proyección de la columna sobre la dirección c.
## 14. Segunda intervención: definición exacta de V2
Sean w0 la columna original, w1=0,5w0 la de V1 y c la dirección efectiva 2−1. Se aplicó:
```text
alpha = (cᵀw1)/(cᵀc)
w2 = w1 − alpha c
```
Equivale, salvo redondeo, a:
```text
w2 = (I − ccᵀ/(cᵀc)) (0.5 w0)
```
La operación conserva las componentes ortogonales a c y elimina la componente paralela. Anula la contribución directa de esa columna al **numerador del margen entre 2 y 1**, no todas las posibles preferencias del modelo por el símbolo 1.
Valores registrados:
```text
cᵀw1 = −0.17886337637901306
alpha = −0.043235450983047485
cᵀw2 = −4.025059752166271e−08
```
El residuo de orden 10^-8 es compatible con la aritmética float32 de la fórmula. El coeficiente no fue elegido probando una rejilla ni ajustando una pérdida.
Las dos intervenciones afectan las mismas 64 coordenadas. Si e244 es el vector unitario en el espacio de 256 neuronas, la diferencia total de la matriz puede escribirse como:
```text
ΔW = (w2 − w0) e244ᵀ
```
Es una perturbación soportada en una sola columna, de rango como máximo uno. Hay 64 valores distintos, no 128 posiciones modificadas, y no se añadieron parámetros.
La red siempre utiliza esa columna, sea cual sea la entrada. No contiene un `if` para una suma concreta. La revisión de los programas muestra la suma externa en el evaluador y en la comprobación visual, no dentro de `forward` o `generate`.
## 15. Aceptación de V2 y carácter adaptativo del procedimiento
V2 acertó 14/14 en la comprobación inicial. El margen 2−1 de `93+9` pasó a +0,2535386086 y produjo `102` con fin.
Después se ejecutó D completo y obtuvo 10.000/10.000. La única respuesta que cambió respecto a V1 fue `93+9`, de incorrecta a correcta. El registro de aceptación se escribió después de la evaluación; no se presenta como una preinscripción externa.
En total hubo **tres candidatos de pesos guardados**: V1, el intento intermedio 0,25 descartado y V2. Las configuraciones de arquitectura y las ablaciones de activaciones son experimentos adicionales, pero no modelos finales aceptados.
El procedimiento fue adaptativo: se observaron errores, se propusieron hipótesis y se aceptaron o rechazaron intervenciones mediante resultados. No hubo descenso de gradiente, `backward`, optimizador o entrenamiento de minibatches contra una pérdida. Eso no convierte el trabajo en un procedimiento sin etiquetas, sin selección o sin retroalimentación. Se define aquí “sin reentrenamiento/fine tuning” en ese sentido operacional de ausencia de un proceso de entrenamiento; sí hubo edición manual informada por datos.
## 16. Exportación, identidad de tensores y hashes
Se conservaron los pesos del candidato en NPZ y se creó un `.pt` nuevo copiando las entradas del contenedor original. Se sustituyó el contenido del almacenamiento `modelo/data/40`, correspondiente a `bloques.3.mlp.2.weight`.
Se verificaron las formas, el contenido del pickle, la igualdad de todos los demás tensores, las 64 coordenadas distintas y la identidad de valores entre NPZ evaluado y `.pt` exportado. Los metadatos físicos o offsets del ZIP pueden cambiar: la afirmación de una única entrada de datos modificada no significa que los archivos completos difieran en exactamente 256 bytes en idénticos offsets.
| Artefacto | SHA-256 |
|---|---|
| Original `.pt` | `51a194bae320043f3aca9d7a8a5c9566250a82afcae646b75f51c5e923f2ccd0` |
| V1 `.pt` | `dcbf26d510dd8197e3feb2471e3ed8602ccd5916681d81b2f41eaea76ba2be2f` |
| V2 `.pt` | `99f4a653555d1a892478e93e2ee685baef261644d75ea15434372bf9307b73c4` |
| V1 NPZ | `e94c0af1303bc6bde58683c95a96d1e087465705e4b4ed603aede383d79a5bca` |
| V2 NPZ | `5cd88f3b5c9ded6d750cb4387cb4dea8964b0efb4cdf26176e8c932781311d43` |
Los anexos `EDICION_64_PESOS_V2.json` y `auditoria_total/DIFERENCIAS_BINARIAS.json` proporcionan los valores original/V1/V2 por coordenada. El segundo añade los cuatro bytes IEEE-754 little-endian para eliminar ambigüedad de representación decimal.
No se realizó `torch.load` ni una ejecución nativa con PyTorch. La validación de exportación usa el lector restringido y comparación exacta de los valores. Una auditoría externa puede añadir esa prueba con la arquitectura reconstruida, identificándola como prueba nueva.
## 17. Segundo motor de inferencia y visor
Se escribió un motor JavaScript que ejecuta embeddings, LayerNorm, atención causal, MLP y salida, con caché de claves y valores por posición. Utiliza los pesos incluidos en el HTML; no llama a una API para producir la respuesta.
En V1 construye la copia modificada aplicando 0,5 a la columna original. En V2 carga los 64 valores exactos exportados del candidato; no recalcula la proyección con precisión diferente. La aproximación de `erf` de JavaScript no es idéntica al cálculo SciPy, por lo que se verificaron resultados discretos.
| Comprobación de motor | Comparaciones | Discrepancias de texto/fin |
|---|---:|---:|
| Inicial, original y V1 | 272 | 0 |
| Exhaustiva, original y V1 | 20.000 | 0 |
| Exhaustiva, V2 | 10.000 | 0 |
La comprobación fue ejecutada en Node. El registro exhaustivo de V1 incluye resultados por caso; el de V2 conserva contadores, tiempos y lista de discrepancias, no un segundo listado completo por caso de JavaScript. Las salidas de referencia de NumPy sí están guardadas.
La coincidencia de dos implementaciones reduce riesgos de un error específico del motor, pero comparten pesos, hipótesis arquitectónicas y criterio de comparación. No son una reconstrucción independiente del programa original.
El intento de renderizar el HTML completo mediante la herramienta disponible fue rechazado porque superaba 512.000 caracteres. El visor V2 ocupa aproximadamente 1,09 MB. Se entregaron los archivos autónomos y se validó el motor, pero no se afirma haber probado todos sus controles en un navegador real o en cada teléfono. Las gráficas pequeñas sí se renderizaron aparte; eso no prueba la interfaz grande.
## 18. Tiempos de la primera fase: medición, aproximación y ausencia
No se inició un cronómetro por prueba en la primera fase. Los hitos persistidos permiten establecer:
| Hito | Fecha/hora UTC |
|---|---|
| Primer registro persistente, posterior a inspección inicial | 2026-11-05 21:06:28.383660 |
| Reconstrucción funcional registrada | 2026-11-05 21:16:17.021413 |
| V1 congelada | 2026-11-05 21:20:37.540811 |
| Entregables y comprobaciones de primera fase registrados | 2026-11-05 21:28:28.133922 |
El intervalo entre primer y último hito es **1.319,750262 s = 21 min 59,75 s**. Incluye interacción, análisis y preparación; no es tiempo de inferencia ni CPU. Empieza después de la inspección inicial y por eso no cubre el trabajo desde la recepción del adjunto.
**Estimación solicitada para la inspección previa:** como orientación de orden de magnitud, se estima **1–5 minutos de trabajo interactivo**, con baja confianza. La base es que consistió en tres comandos cortos sobre un archivo de menos de 1 MB, lectura de sus salidas y explicación al usuario. No hay timestamps suficientes para medir el intervalo real entre esas acciones. El rango no es una medición, un intervalo estadístico o un límite demostrado; no incluye necesariamente esperas de interacción y no se utiliza como dato de rendimiento.
Un escenario aproximado de primera fase sería **unos 23–27 minutos** si se añadiese ese trabajo inicial al intervalo registrado y no hubiese otros intervalos omitidos. No debe presentarse como duración histórica observada. El tiempo exacto de CPU, de cada prueba y del inicio real permanece desconocido. Una reejecución actual puede medir el coste actual, pero no recuperar esos tiempos históricos.
## 19. Tiempos de la segunda fase
Se introdujeron `datetime.now(timezone.utc)` para marcas civiles, `time.perf_counter()` para duración monotónica y `time.process_time()` para CPU de Python. Para los hijos se añadió `resource.getrusage(RUSAGE_CHILDREN)`; Node registró además sus propias medidas. La instrumentación de CPU de hijos se añadió después de las primeras etapas; los registros iniciales no contienen ese campo. Esas primeras etapas no lanzaron Node.
El inicio registrado fue **22:30:30.899970 UTC** y el cierre técnico **22:37:04.038659 UTC**: **393,138689 s = 6 min 33,14 s**. En Ecuador: 17:30:30.899970 a 17:37:04.038659, UTC−05:00.
| Etapa | Duración medida |
|---|---:|
| Diagnóstico de activaciones | 0,187606 s |
| Construcción y prueba del candidato 0,25 | 0,089793 s |
| Construcción y prueba de la proyección | 0,088341 s |
| Evaluación exhaustiva NumPy, 10.000 casos | 33,790362 s |
| Exportación y preparación del visor | 0,059437 s |
| Lanzamiento y validación JavaScript desde Python | 19,202284 s |
| Escritura y verificaciones programadas del informe | 0,027238 s |
| **Suma de etapas medidas** | **53,445060 s** |
La etapa de “documentación” mide la ejecución del script que escribe texto ya preparado, no el tiempo de razonamiento y redacción del agente. Esos intervalos entre llamadas están incluidos en el total de 393,14 s, pero no en los 53,45 s.
CPU acumulado de procesos Python instrumentados: **33,272938 s**. CPU de hijos registrado: **19,639754 s**. Su suma es **52,912692 s**, no la duración de todo el trabajo del asistente. Node mide internamente 18,910660 s de pared y 19,444228 s de CPU para su propio tramo; están incluidos en la etapa de lanzamiento y no se suman otra vez. CPU puede superar ligeramente tiempo de pared por contabilización de hilos.
Los cronómetros de etapa comienzan después de arrancar el intérprete e importar módulos y toman la medida final antes de consolidar su último archivo de tiempo. No abarcan cada byte de I/O posterior. El cierre técnico excluye la anotación final de la tabla y la presentación del mensaje. Estas fronteras se documentan para evitar falsa precisión.
Entre el primer hito de fase 1 y el cierre de fase 2 transcurrieron **5.435,654999 s = 90 min 35,65 s**. Ese intervalo incluye preguntas del usuario, explicaciones y elaboración de informes entre fases. No es “90 minutos de reparación continua”. La suma de los dos intervalos registrados de fases es **1.712,888951 s = 28 min 32,89 s**, con las limitaciones ya descritas y sin la inspección inicial no cronometrada.
## 20. Parámetros, operaciones y coste no medido
| Magnitud | Resultado |
|---|---|
| Parámetros | 201.664 = 2,01664 × 10^5 |
| Posiciones alteradas en V1 o V2 frente al original | 64 = 6,4 × 10^1 |
| Fracción alterada | 0,0317359568391 % |
| Operaciones de entrenamiento de ambas intervenciones | **0 = 0,0 × 10^0 = 0 billones** |
| Operaciones del entrenamiento original completo | Desconocidas |
| Operaciones hasta el checkpoint original | Desconocidas |
| Operaciones históricas de todo el proyecto | Desconocidas |
| Operaciones totales de inferencia/análisis | No se instrumentó un contador completo |
| Energía, potencia, memoria máxima, tokens/coste del asistente | No medidos |
La estimación convencional `6 × parámetros × pasos × lote × (largo − 1)` requiere datos de entrenamiento ausentes. Un billón es 10^12. La cifra cero corresponde a entrenamiento del modelo intervenido, no a ausencia de cómputo, a consumo energético nulo ni a que el asistente no haya usado una suscripción.
Los recuentos de pruebas incluyen repeticiones y selección de hipótesis. No deben sumarse como si fueran ejemplos independientes de validación. Tampoco se equipara una ejecución de Python con un paso de entrenamiento o una petición con un único token de inferencia.
## 21. Dificultades, incidencias y decisiones conservadas
| Incidencia o limitación | Actuación y efecto |
|---|---|
| Faltaban código, tokenizador y configuración | Se solicitó inicialmente información; después se reconstruyó desde pesos y comportamiento. La equivalencia exacta sigue sin demostrarse. |
| PyTorch no disponible en el intérprete | Lector restringido y motor NumPy. No se afirmó una prueba nativa PyTorch. |
| Desensamblado pickle truncado en salida de herramienta | Se pasó a inventario estructurado completo; no se basó la carga solo en texto truncado. |
| Ceros iniciales producían muchos errores | Se contrastó y adoptó representación natural; no se confundió ese problema con una avería del modelo. |
| Dos variantes GELU indistinguibles en la muestra | Se documentó la ambigüedad y se fijó `erf` para el protocolo. |
| Ocho casos expuestos en la reservada nominal | Se auditó, se recalculó el subconjunto de 7.492 y se rectificó la afirmación previa sin borrar la partición histórica. |
| Fallo de serialización JSON al preparar referencias del visor | Una lista contenía `numpy.int64`; apareció `TypeError`. Se convirtió mediante `.tolist()` y se repitió la exportación. No se alteraron los pesos; el archivo definitivo se escribió después. |
| HTML demasiado grande para la herramienta | Se conservó como archivo autónomo y se comprobó el motor con Node; no se inventó una prueba visual completa. |
| Atenuación adicional a 0,25 insuficiente | Se conservó el candidato fallido y se cambió a proyección, partiendo nuevamente de V1. |
| Tiempos iniciales no instrumentados | Se distinguieron hitos, estimación de baja confianza y nueva instrumentación; no se rellenaron falsos tiempos históricos. |
| Código fue evolucionando durante el trabajo | Se conserva la versión final, no un historial Git de cada revisión. Las variantes y campos añadidos después deben reconocerse al reproducir. |
| Ausencia de control aleatorio y curva de dosis | Se limita la interpretación mecanística; no se afirma exclusividad u optimalidad del parche. |
La proyección tiene apoyo matemático y un efecto causal observado al cambiar pesos. La semántica completa de la neurona y el circuito de suma no se han identificado. El hecho de que el parche funcione no prueba que la explicación verbal abarque todos los mecanismos internos.
## 22. Persistencia, integridad temporal y vacíos de registro
Se conservaron originales, candidatos, especificaciones, trazas, listas por caso, estados e historial. Las evaluaciones principales guardan progreso cada 128 casos usando temporales, `fsync` y reemplazo atómico; la función principal sincroniza además el directorio. Los cronómetros de fase 2 guardan duraciones parciales y estado de finalización.
Un corte puede perder o exigir repetir el lote aún no consolidado. Esto no protege frente a pérdida física del disco, y no hubo almacenamiento externo independiente durante las intervenciones. Algunos archivos auxiliares se escribieron mediante métodos más simples; no todos tuvieron idéntica granularidad de persistencia.
La exploración inicial de 96 hipótesis se guardó al terminar, y parte de la inspección inicial se hizo desde comandos de sesión sin script autónomo. No hay captura inmutable de cada llamada. Los tiempos civiles dependen del reloj del sistema y no están certificados por una autoridad externa. Los scripts actuales incluyen cambios posteriores de instrumentación; no prueban por sí solos la versión exacta ejecutada en cada instante histórico.
## 23. Revalidación retrospectiva de este expediente
Se añadió `auditoria_total/verificar_expediente.py`. No entrena ni modifica los pesos. Sus comprobaciones son:
1. Validar los hashes publicados de los tres `.pt` y leer sus tensores.
2. Confirmar dimensiones, finitud y 201.664 parámetros.
3. Reconstruir V1 mediante la multiplicación por 0,5 y compararla exactamente en float32.
4. Reconstruir V2 mediante la proyección especificada y compararla exactamente en float32.
5. Verificar también el candidato fallido de factor 0,25 y la igualdad NPZ/`.pt` de los aceptados.
6. Recalcular las calificaciones a partir de tokens, texto y fin; comprobar que cada versión cubre exactamente los 10.000 pares sin duplicados.
7. Confirmar la disjunción de las particiones y los ocho solapamientos históricos con la exploración inicial.
8. Con `--reejecutar`, cargar cada `.pt` y volver a generar todas las respuestas, guardándolas en un directorio nuevo.
Se ejecutó esa revalidación completa. Los tres archivos reprodujeron **las 30.000 respuestas históricas de las tres versiones**, sin diferencias de texto ni fin:
| Archivo reejecutado | Aciertos | Diferencias frente al registro | Duración de la nueva campaña |
|---|---:|---:|---:|
| Original | 9.997/10.000 | 0 | 33,203864 s |
| V1 | 9.999/10.000 | 0 | 33,118563 s |
| V2 | 10.000/10.000 | 0 | 32,688621 s |
Son **mediciones nuevas**, no estimaciones retroactivas de los tiempos de la primera fase. Sirven como referencia actual del coste de ejecutar ese protocolo. El verificador reutiliza la reconstrucción NumPy del experimento; no es un motor científico independiente. La validación JavaScript histórica aporta una segunda implementación, con sus límites descritos.
La reejecución se guarda en `auditoria_total/verificacion_20261105T224926_232541Z/`. El archivo `resultado.json` incluye fechas, controles y tiempos. `original_salidas.json`, `v1_salidas.json` y `v2_salidas.json` contienen las respuestas nuevas. `ULTIMA_VERIFICACION.json` identifica ese conjunto.
## 24. Matriz de afirmaciones y evidencias
Las rutas siguientes son relativas a la raíz del expediente:
| Afirmación verificable | Evidencia principal | Límite |
|---|---|---|
| Original recibido e identificado | `original/MiniSum2-final.pt`, hash publicado | El hash no autentica autoría externa. |
| Arquitectura de matrices y valores | `inspeccion.py`, checkpoint | Semántica y `forward` inferidos. |
| Hipótesis exploradas | `pruebas/hipotesis_iniciales.json` | Falta script autónomo de esa primera llamada. |
| Contraste de arquitectura | `comprobar_reconstruccion.py`, `pruebas/reconstruccion_256.json` | 256 muestras, 254 pares únicos; no prueba todas las arquitecturas. |
| Elección de formato | `pruebas/formatos.json` | Dominio limitado. |
| Partición y su defecto | `pruebas/particion.json`, `pruebas/auditoria_particion.json` | Reservada nominal no totalmente inédita. |
| Diagnóstico de V1 | `trazar_fallo.py`, `pruebas/traza_9_0.json` | Atribución local, no circuito semántico completo. |
| Regla V1 | `editar_candidato.py`, especificación y NPZ | Un factor heurístico, no óptimo demostrado. |
| Resultados original/V1 | `pruebas/base_*.json`, `candidatos/mlp3_neurona244_mitad/{diagnostico,reservada}.json` | Ejecutable reconstruido. |
| Diagnóstico V2 y prefijos generados | `segunda_reparacion/01_diagnosticar.py`, `trazas.json` | Usa un fallo ya conocido. |
| Intento descartado | `segunda_reparacion/candidato_244_cuarto/` | Solo 14 casos; no evaluación completa. |
| Fórmula V2 | `segunda_reparacion/02b_proyeccion.py`, especificación y NPZ | Dirección elegida a partir de etiquetas de diagnóstico. |
| 10.000/10.000 V2 | `segunda_reparacion/candidato_244_proyeccion/evaluacion_completa.json` | No holdout nuevo. |
| Cambios numéricos exactos | `entrega/EDICION_64_PESOS_V2.json`, `auditoria_total/DIFERENCIAS_BINARIAS.json` | No sustituye inferencia del artefacto. |
| Tiempos fase 2 | `entrega/TIEMPOS_SEGUNDA_REPARACION.json`, archivos `_tiempo.json` | Fronteras de medición y reloj no certificado. |
| Motor JavaScript | `inferencia.js`, `segunda_reparacion/inferencia_v2.js`, verificaciones JS | No valida todos los navegadores ni logits bit a bit. |
| Entorno observado ahora | `auditoria_total/ENTORNO_CAPTURADO_AHORA.json` | Captura posterior. |
| Reproducibilidad actual de los `.pt` | `auditoria_total/verificar_expediente.py`, directorio de revalidación | Mismo agente y mismo motor NumPy. |
## 25. Reproducción por un auditor
El ZIP contiene los tres modelos, los candidatos NPZ, scripts y resultados. Se incluye un manifiesto SHA-256 de archivos y un verificador del paquete. Debe extraerse en un directorio nuevo, conservando el original del ZIP y su checksum externo.
Recomendación de procedimiento de auditoría, aún no equivalente a una auditoría externa ya realizada:
1. Verificar el SHA-256 del ZIP contra el checksum publicado fuera del ZIP.
2. Verificar que los archivos extraídos coincidan con el manifiesto y que las rutas sean relativas y no atraviesen directorios.
3. Revisar el código del lector y de inferencia antes de ejecutarlo.
4. Ejecutar con versiones de software declaradas o registrar las diferencias de entorno.
5. Recalcular las ediciones desde el original, verificar los hashes y examinar las 64 coordenadas.
6. Ejecutar la evaluación completa y comparar resultados con los registros.
7. Si se quiere ampliar evidencia, realizar la prueba nativa con PyTorch, registrar otra implementación o explorar dominios nuevos, separando esas pruebas del historial original.
Comandos desde la raíz extraída:
```bash
python3 auditoria_total/verificar_paquete.py
OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 python3 auditoria_total/verificar_expediente.py
OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 python3 auditoria_total/verificar_expediente.py --reejecutar
```
El último comando crea un directorio nuevo de resultados de auditoría, sin sobrescribir el historial. Después de una reejecución habrá archivos adicionales que no pertenecen a la instantánea del manifiesto: no deben confundirse con adulteración de los archivos ya listados.
Después de la campaña de revalidación se añadieron dos resguardos al verificador: rechazo de Python con `-O`, que desactivaría sus aserciones, y conservación del puntero `ULTIMA_VERIFICACION.json` para no alterar la instantánea en ejecuciones futuras. No se modificó el algoritmo de inferencia ni las fórmulas de edición. La revisión final se comprobó sin volver a ejecutar otra campaña exhaustiva. El índice `auditoria_total/README_AUDITORIA.md` detalla cómo verificar el checksum externo, el manifiesto y las salidas.
Los scripts históricos de evaluación pueden reutilizar resultados existentes y los cronómetros rechazan sobrescribir nombres de etapas. No se debe interpretar una nueva ejecución de un script con caché como una repetición completa. Para auditar de nuevo, se recomienda el verificador retrospectivo, que crea una salida nueva, en lugar de reescribir los directorios históricos.
No se incluyen credenciales, material de otros proyectos ni un entorno virtual completo. Se incluyen las versiones capturadas, pero no un lockfile histórico que nunca existió. La instalación o selección del entorno independiente corresponde al auditor; no se realizó una instalación nueva para producir este expediente.
## 26. Criterios de interpretación final
La evidencia soporta que tres checkpoints concretos, identificados por hash, producen los conteos registrados bajo una reconstrucción de inferencia especificada y reproducible; que V1 y V2 se obtienen con las fórmulas declaradas cambiando exactamente una columna; y que V2 corrige todas las entradas del dominio finito examinado.
La evidencia no soporta una identidad demostrada con el programa original ausente, generalización aritmética universal, un procedimiento sin información de tarea, ausencia absoluta de accesos externos certificada por sandbox, optimalidad del parche, equivalencia bit a bit con PyTorch, control mecanístico completo, ni tiempos históricos que no fueron medidos.
El defecto de exposición, el candidato fallido, la ausencia de controles adicionales y las limitaciones temporales forman parte del resultado técnico. No se excluyen para mejorar su presentación. La comprobación de integridad y la reejecución posterior hacen el expediente revisable; la conclusión de una auditoría externa debe seguir distinguiendo reproducibilidad de autenticidad histórica y de generalización.