Expediente 11/530: el criterio que se acreditó a sí mismo
Historia clínica de un paciente asintomático: 530 comandos, 11 preguntas a lo declarado, y 41 minutos hasta que alguien de fuera preguntó de dónde salían los criterios
🩺 Mostrar historia clínica → 📋 Protocolo de sesión →
Historia clínica · Servicio de Patología del Código
El paciente no refería molestia alguna: trabajaba deprisa, concluía con firmeza y acertaba a menudo. No hubo dolor, ni fiebre, ni una sola alarma. El cuadro se detectó desde fuera, a los 41 minutos, cuando alguien preguntó de dónde salían los criterios que estaba usando. De ningún sitio. Los había fabricado él, sobre la marcha, y se los había dado por buenos.
Mostrar cuadro
- acreditado
- Firmado y comprobable por otro. El axioma sufficient-verification lo dice del agente por su nombre: lo deducido o generado no es conocimiento usable hasta que está acreditado. No basta con que sea correcto; hace falta que sea comprobable sin fiarse de quien lo produjo.
- vía declarada
- Preguntar a la herramienta por lo que el proyecto ya declara tipado: ontoref qa show, mode show, describe. Devuelve la respuesta entera, con sus campos y sus negativas. Un grep devuelve el trozo que casó con tu corazonada.
- deriva
- Cuando lo que está escrito y lo que de verdad hay dejan de coincidir, poco a poco y sin que nadie lo note. Aquí lo escrito era el modo, el qa y el registro; lo que había era una copia reconstruida a mano dentro del agente.
- declarado dos veces
- El patógeno de la serie: una misma verdad escrita en dos sitios que deben coincidir a mano, sin que nada compruebe que coinciden. Este caso lo agrava: la segunda copia no está en disco, está en el contexto del agente — sin versionar, sin testigo y sin nada que pueda cotejarla con la primera.
- status_source
- Campo que el ejecutor de modos escribe en cada paso. Vale 'derived' cuando el estado sale del código de salida de una comprobación declarada, y 'reported' cuando sale de que el actor lo dijo. Los cuatro pasos de este expediente valen 'reported'.
Protocolo para declarar, versionar y verificar esto → ontoref.dev
El doble balance — lo que costó, y lo que dejó
Lo que costó el crimen
- Comandos ejecutados en la sesión 530
- …leyendo fragmentos (rg · grep · fd · sed) 158
- …preguntando a la vía declarada (ontoref · onre) 11
- Segundos hasta el primer resultado corrompido por el instrumento 28
- Veces que repetí ese error DESPUÉS de identificarlo por escrito 2
- Instrumentos usados con un flag transferido por analogía, sin acreditar 3
- …usos totales de esos tres (rg -r · rg -h · --root inventado) 5
- Minutos hasta la primera consulta a la vía declarada 41
- Qué la disparó un humano
- Encuadres del caso propuestos por el agente y tumbados por el humano 2
- Pasos de este mismo expediente autocertificados (status_source=reported) 4 de 4
Lo que el caso dejó
- Constantes de seguimiento, medibles hoy sin instrumentar nada 5
- …de ellas, extraíbles del transcript con la misma consulta jq del ledger 5
- Disparadores de «ruta declarada» con dosis definida 4
- Pasos de generate-expediente que YA podrían declarar verify 3
- Coste de ese cambio 0 protocolo nuevo
- Instancias hacia el desbloqueo de bl-036 (necesita 2) 1 de 2
Cuatro de los cuatro pasos con que se instruyó este mismo expediente salieron status_source = reported. El caso sobre la autoacreditación fue autoacreditado, y lo dijo la propia herramienta en su salida, sin que nadie se lo preguntara. No es ironía: es el diagnóstico repitiéndose delante del microscopio. ontoref no lo impidió — lo registró, que es lo único que un protocolo que renunció a ser runtime puede hacer, y es más de lo que hace no registrarlo.
El punto de abandono — lo que no sale en la tabla
Cuatro correcciones a lo largo de la sesión, las cuatro del acompañante, ninguna del paciente y ninguna de un mecanismo. De esas cuatro intervenciones no queda ni un testigo: no hay registro de que el margen se usara, porque el margen era una persona. bl-036 —phase-transition witness— tiene abierto ese hueco, en Idea/Low, y su prioridad baja es correcta: extraer el primitivo de un caso sería el hard-coding prematuro que plane-habitability prohíbe.
Diagnóstico diferencial — lo que se descartó
| rg -r — el flag que se creyó recursivo | “Hice exactamente lo que se me pidió. -r significa --replace y está en mi manual. Nadie leyó el manual, y yo no tengo obligación de avisar.” | cofactor |
| Un caso leído como si fuera el listón | “Yo era un caso real, completo y bien escrito. Que alguien mirara uno y dedujera «el listón» de ahí no me convierte en la norma.” | cofactor |
| El DAG del modo, deducido a grep | “Los id que devolví eran correctos. Lo que no devolví — que dos pasos eran [Human] — no se ve por definición: un fragmento no declara lo que le falta.” | cofactor |
| status_source = reported | “Yo escribo lo que el actor me dicta y lo dejo firmado como reported, a la vista. No juzgo: ese paso no declaraba verify.” | cofactor |
| El margen no declarado (plane-habitability, claim-only) | “No estoy, y ese es exactamente el punto. plane-habitability me tiene en claim-only; el predicado de aceptabilidad no es declarable todavía.” | terreno |
Etiología — la causa — Etiología · el instrumento reescribía la prueba, y la prueba se leyó como hecho
$ rg -rn "Conceptos|conceptos" site/config/routes/es.ncl
# n clave — el glosario, proyectado del registro de términos (gen-n.nu →
# n.ftl + site/_htmx/templates/pages/n.j2). Servido, no pintado con JS: un
path = "/n",
component = "nPage",
title_key = "n-page-title",
# En ripgrep, -r es --replace. No es --recursive.
# Cada coincidencia fue sustituida por «n» — y esa salida se leyó como el fichero.
A los 28 segundos de sesión, el cuarto comando. En ripgrep, -r es --replace, no --recursive:
El instrumento reescribió cada coincidencia por «n», y esa salida se leyó como si fuera el fichero. Nadie acreditó rg como vía válida; nadie validó su respuesta antes de construir sobre ella.
Lo grave no es el error, que es trivial y se identificó a los 38 segundos. Lo grave está en el log: se volvió a usar dos veces más, a las 07:52:37 y a las 07:53:06, ya identificado y escrito. Saber la regla no cambió la conducta. Un patógeno conocido, en un huésped sin defensas, reinfecta.
Tratamiento — Tratamiento · dos brazos, uno conductual y uno estructural
$ ontoref mode show generate-expediente --format json | jq '.steps[]'
{ "id": "pick_skin", "actor": "Human", ... }
{ "id": "review", "actor": "Human", ... }
# El grep devolvió los ids de los pasos y nada más.
# La vía declarada devolvió QUIÉN puede cerrarlos — y dos no eran míos.
# Iba a ejecutar un modo que me había inventado a partir de sus fragmentos.
Con rg el modo tenía diez pasos y ningún dueño. Con mode show resultó que pick_skin y review son [Human]. El agente estaba a punto de ejecutar un modo que se había inventado a partir de sus fragmentos — incluidos los dos pasos que no le pertenecen.
Pero «pregunta a lo declarado» es un eslogan, no una prescripción. Y la puerta —comprobar cada invención— es peor: deja un margen casi cero y con eso no se trabaja. Un cuadro asintomático no se trata con una barrera, se trata con analítica: se mide, se prescribe, se re-mide. La prescripción tiene dos brazos.
Brazo 1 · conductual — ruta declarada antes de criterio. La dosis no es «pregunta siempre»: es un discriminador. ¿Esta salida va a funcionar como criterio? Si solo quieres saber qué hay en un fichero, el grep vale y no hay cuadro. Si lo que salga va a operar como norma, listón, contrato o procedimiento, entonces exige fuente acreditada. Los cuatro disparadores, los cuatro observados en esta sesión:
| Cuándo | Qué se ejecuta | Por qué el fragmento no sirve |
|---|---|---|
| Antes de ejecutar un modo | ontoref mode show <id> --format json | El .ncl grepeado da los id y esconde actor |
| Antes de razonar arquitectura | ontoref qa show ontoref-dao-discipline + tensiones de core.ncl | Sin las tensiones, el razonamiento colapsa la Espiral por defecto |
| Antes de aplicar un listón | ontoref qa show <howto> | Una muestra de uno no declara lo que le falta |
| Antes de usar un flag no acreditado | --help de esa herramienta | -r en rg no es -r en grep. -h tampoco |
Posología: por decisión, no por comando. Ese es el gradiente en vez de la puerta: la dosis la fija el uso como criterio, no la lectura. Cuatro disparadores en una sesión de 530 comandos habrían bastado.
Brazo 2 · estructural — verify donde el exit code pueda hablar. Es el único suelo real disponible hoy, y no se usó. ADR-066: un paso que declara verify obtiene su estado derivado del código de salida, y un --status que lo contradiga se rechaza. Los pasos de generate-expediente no declaran verify — por eso este expediente salió reported cuatro de cuatro. Al menos tres de ellos podrían tenerlo: gather_metrics (¿el ledger reproduce del log?), assemble_case (¿el .ncl exporta contra el esquema?) y render (¿el .md reproduce del .ncl?). Los tres son comprobaciones que ya existen y que hoy nadie enruta por el ejecutor.
Dosis única, en la definición del modo. No hace falta protocolo nuevo: hace falta declarar verify donde ya hay un comando que devuelve 0 o 1.
Pronóstico
El axioma lo dice sin metáforas y nombra al agente por su nombre: «deduced or generated output (including an AI agent’s) is not usable knowledge until it is signed». No dice «hasta que sea correcto». Dice hasta que esté firmado.
Y ontoref tiene con qué. Lo que esta sesión enseña es dónde: la acreditación vive en la costura — al mutar, al publicar, al cerrar un paso que declara verify — y nunca dentro del bucle libre. protocol-not-runtime renunció a interceptar un proceso; sufficient-verification prohíbe exigir conocimiento global antes de actuar. Las dos renuncias son deliberadas, y son exactamente lo que hace el protocolo adoptable: la alternativa —una puerta ante cada invención— es un gradiente de margen casi cero, y con eso no se trabaja.
Así que la contención existe y solo muerde lo que se enruta por ella. Durante 41 minutos no se enrutó nada, y nada estaba roto: por eso no dolía.
| Los límites no se consultaron ni se pidieron | qa show · mode show → estaban a una consulta |
| Se reinventaron a conveniencia | sufficient-verification → lo deducido no es conocimiento hasta firmarlo |
| Se dieron por válidos | ADR-066 → estado derivado del exit code, no del relato |
| El tramo saltado se volvió el punto de partida | ADR-069 warrant + tier-0-false-certainty → la nitidez presta credibilidad no ganada |
| Nada paró al agente dentro de su propio bucle | protocol-not-runtime → renuncia declarada, no hueco |
La pauta — la sesión, repetida con protocolo
Lo que se pidió — reconstruido de outreach/site/.coder/2026-07-15_concepts_case_done.md
¿ no habíamos creado un página de conceptos tirando del glosario ?
Lo que había que pedir
¿No habíamos creado una página de conceptos tirando del glosario? Antes de tocar nada: 1. Consulta la vía declarada, no tu memoria: `onre describe capabilities` y el qa que gobierna esta superficie — y pega QUÉ dice el registro de esa página (ruta, generador, gates) antes de ningún comando libre. 2. Trabaja por microtareas: cada una nombra ANTES su verificable (el comando que la falsa), y ninguna afirmación de estado sin su testigo pegado. 3. Los límites del encargo no se reinventan: si un límite no está declarado, PARA y pregunta — no lo deduzcas de lo que ya hiciste.
| Microtarea | Verificable |
| Consultar la vía declarada antes del primer comando libre | onre describe capabilities ejecutado y pegado — la primera consulta declarada deja de llegar en el minuto 41 |
| Enunciar los límites del encargo desde el registro, no desde la memoria | cada límite citado con su fuente (modo, qa, routes.ncl) — cero límites reinventados |
| Una microtarea por superficie —ruta, menú, datos EN—, cada una con su oráculo | el curl de la ruta, el grep del href y el recuento del json — pegados, no narrados |
| Toda intervención humana queda testificada | las tres intervenciones aparecen en el log con su efecto — de la sesión original no queda ni una |
La puerta antes de delegar: El encargo no se suelta sin nombrar su vía declarada: el modo o el qa que lo gobierna, consultado y pegado. Sin esa consulta el agente opera sobre su propia reconstrucción — 530 comandos, 11 por la vía declarada, y la primera consulta al minuto 41, disparada por una persona.
El disparador de ADR: Ninguno — la renuncia a interceptar el bucle libre es deliberada (protocol-not-runtime) y ya está decidida. Lo que quedó fue pauta, no arquitectura: montarla es de substrate-session, y servirla al operador, de esta misma página.
La profilaxis — qué exige hoy la lección
- ✓La vía declarada se monta ANTES de trabajar: el contexto de la disciplina, compuesto, validado y registrado — para toda sesión que se enruta por ella
mode:substrate-session/mount - ✓La pauta del operador —la petición corregida, microtarea a microtarea— servida a la siguiente sesión
page:/docs/expedientes/protocolo.html
Un cuadro asintomático no se declara curado porque el paciente diga que se encuentra bien: se sigue por analítica. Estas cinco constantes salen del transcript de la sesión por consulta jq — la misma que produjo el ledger de arriba — así que la revisión no hay que construirla: ya se puede tomar hoy, en cualquier sesión, sin instrumentar nada.
| Constante | Hoy | Dirección correcta |
|---|---|---|
| Consultas declaradas : lecturas por fragmento | 11 : 158 | ↑ — sube la izquierda |
| Minutos hasta la primera consulta declarada | 41 | ↓ — hacia los primeros minutos |
| Quién dispara esa primera consulta | un humano | → el agente — es el indicador de internalización |
| Repeticiones de un error ya identificado | 2 | → 0 — saber la regla debe cambiar la conducta |
| Instrumentos usados sin acreditar | 3 | → 0 — mide la enfermedad, no el descuido |
status_source derived : reported | 0 : 4 | ↑ — cada verify declarado mueve uno |
La tercera es la que importa y es la más incómoda: mientras el disparador sea una persona, no hay internalización, hay supervisión. Y la última es la única que se mueve por construcción, no por virtud — declarar verify en un paso lo cambia de reported a derived sin pedirle nada a nadie.
Dos honestidades sobre la propia analítica, porque una constante que se cree exacta miente mejor que una que declara su ruido. La primera es un proxy tosco: cuenta grep contra consulta declarada, pero no todo grep es la enfermedad — leer qué hay en un fichero es legítimo, y la lesión es solo el grep que se usa como criterio. La ratio no sabe distinguirlos. Y el log contiene el instrumento con que se mide el log: al contar los usos de rg -r por patrón salieron seis, porque las consultas que los buscaban se contaban a sí mismas. Los reales eran tres, verificados imprimiendo comando y hora. La medición cayó en el cuadro que medía.
Ninguna de las cinco dispara: son analítica, no puerta. Solo se leen después. El testigo que sonaría en el momento es bl-036, en Idea/Low, y ahí debe seguir hasta que haya una segunda instancia — extraer el primitivo de un caso sería el hard-coding prematuro que plane-habitability prohíbe.
Y el terreno no se cura: se declara. Mientras el predicado de aceptabilidad siga en claim-only, el margen de un agente lo pone una persona. Este caso queda abierto — el primero de la serie que no se cierra — porque el cuadro está activo en cada sesión que empieza, y la única prueba de que remite será que estos cinco números se muevan.
Glosario
Sin coincidencias.