Saltar al contenido
oracle

Notas de release#

Una sección por versión, de la más nueva a la más vieja. Las anteriores a 0.20 están en docs/notas/anteriores-a-0.20.md.

<!-- notas_indice:inicio -->

versiónqué trae
0.31.1dos verdes que no habían mirado, y una huella que dependía del checkout
0.31.0un verde que no midió nada ya no sale verde
0.30.0escribí la aritmética como la pensás
0.29.0un modelo como sensor de la prosa, y un lenguaje que avisa mejor
0.28.0retomar es leer una tarea
0.27.0una sombra perdona hasta su cota, y el MCP se pone al día
0.26.0el álgebra puede decir «ninguna»
0.25.2el verificador del diferencial, fijado; y los dos consumidores en verde
0.25.1borradores de las relaciones que faltan declarar, sin fabricar un verde
0.25.0mutar unos sitios sin poder confundirlo con una verificación completa
0.24.0ningún mutante se come la máquina, y el tracker se lee de un vistazo
0.23.1el diferencial ejercita lo que el álgebra agregó, y compara el veredicto entero
0.23.0declarar el ámbito deja de ser cosa de Oracle
0.22.0toda medida lee campos que existen, y un campo ausente se informa igual en todas partes
0.21.0mutante es una relación con variantes, y requiere puede pedir filas de una
0.20.0Motor juzga con el mismo catálogo y las mismas sombras que oracle test
0.19.0 y anterioresen docs/notas/anteriores-a-0.20.md

<!-- notas_indice:fin -->

0.31.1 — dos verdes que no habían mirado, y una huella que dependía del checkout#

VERSION_DISTRIBUCION   0.31.0 → 0.31.1   correcciones: verdes sin mirar, la huella de un directorio
VERSION_ALGEBRA        1.0    → 1.0
VERSION_SINTAXIS       0.7    → 0.7

Dos verdes que no habían mirado, y dos imprecisiones de juzgar#

La huella de un directorio#

Un fixture diferencial cuya referencia es un directorio contaba también los archivos ocultos y __pycache__: el mismo commit daba el fixture al día en un checkout y vencido en otro (lo destapó .obsidian/workspace.json, que Obsidian reescribe al abrir un vault). Ahora se ignoran al recorrer un directorio. Si tu fixture tiene como fuente un directorio con archivos ocultos versionados, su huella cambia una vez: regeneralo.

Documentación#

0.31.0 — un verde que no midió nada ya no sale verde#

VERSION_DISTRIBUCION   0.30.0 → 0.31.0   álgebra 1.0, verdes vacíos cerrados, la web nueva
VERSION_ALGEBRA        0.8    → 1.0
VERSION_SINTAXIS       0.7    → 0.7

El álgebra 1.0#

Sube la mayor del álgebra porque hay medidas que antes daban otro resultado, a veces verde:

⚠️ Si tu evidencia trae null, no subas sin migrar. Oracle te dice qué relación, qué fila y qué campo. LyraGASP y Jam siguen en 0.30.0 hasta migrar.

Los caminos a un verde vacío, cerrados#

La mutación se vigila a sí misma#

Quien llega nuevo#

La especificación contesta más#

Ocho preguntas en las que el núcleo y la implementación de referencia coincidían sin que el texto lo dijera quedan escritas, y las divergencias entre los dos se resolvieron con el álgebra 1.0.

0.30.0 — escribí la aritmética como la pensás#

VERSION_DISTRIBUCION   0.29.0 → 0.30.0   aritmética infija, el repo en el motor y la web al día
VERSION_ALGEBRA        0.8    → 0.8
VERSION_SINTAXIS       0.6    → 0.7

a + 1, como lo escribe un modelo#

Un LLM escribe t2.turno == t1.turno + 1. Hasta 0.29.0 el lector lo rechazaba y había que escribir mas(t1.turno, 1). Ahora la superficie acepta +, - y *, con la precedencia de siempre, asociación a izquierda y paréntesis, y los lee como las escalares mas, menos y por que ya existían. La forma canónica no cambia: a + 1 produce exactamente ["mas", a, 1], así que ninguna medida cambia de significado y el álgebra sigue en 0.8.

El repositorio es el motor#

La raíz tenía el motor mezclado con doce decisiones, dieciocho planes, tres relevos, un compendio generado de 16 000 líneas y más de sesenta entradas en estudios/. Tres modelos (Codex, agy y Claude) propusieron a ciegas dónde va cada cosa y coincidieron en todo salvo en una carpeta:

Los enlaces de la página de PyPI de versiones anteriores a lo que se movió dan 404: GitHub no redirige un archivo movido.

La web#

segtem.github.io/oracle muestra lo que Oracle es hoy: la anti-junta, las cotas de sombra, el MCP medido en tres clientes, el tracker como relevo, oracle test honesto, el primer valor, Jev con sus límites y la aritmética infija. Cada salida de terminal de la página es de una corrida guardada en la tarea web-028.

Verificación#

Cómo se hizo#

Codex (gpt-6-sol) implementó la aritmética, la mudanza del repositorio y la web. Codex, agy y Claude investigaron a ciegas el orden del repositorio. Claude encontró que t1.turno-1 se leía como un campo y lo devolvió a Codex, revisó cada entrega y cortó.

0.29.0 — un modelo como sensor de la prosa, y un lenguaje que avisa mejor#

VERSION_DISTRIBUCION   0.28.0 → 0.29.0   el patrón del sensor de prosa, ergonomía y un MCP medido
VERSION_ALGEBRA        0.8    → 0.8
VERSION_SINTAXIS       0.6    → 0.6

Un modelo como sensor, nunca como juez#

Hay reglas de un catálogo que viven en prosa: si un alcance dice de verdad qué no mira, o si un porque defiende el número. Ninguna medida determinista puede leer eso. El patrón nuevo deja que un modelo lo lea como sensor: emite hechos (afirmacion_prosa: qué texto, qué pregunta, qué respondió, con qué probabilidad) y Oracle los juzga como cualquier otro hecho. Oracle no llama a ningún modelo ni abre la red: el sensor es un programa del proyecto, opcional, que se corre aparte.

El lenguaje avisa mejor#

El MCP, medido en tres clientes#

oracle_tareas listar ya no devuelve los cuerpos (−87 %) y las descripciones son más cortas. El contrato de docs/mcp-contrato.md se genera desde el código (tools/mcp_contrato.py --check). Qué ve el modelo en cada cliente, medido con marcas aleatorias en cada parte de la respuesta: ninguno recibe outputSchema; Claude Code ve sólo structuredContent, agy sólo el texto y Codex los dos. Por eso se conservan las dos copias: quitar cualquiera deja ciego a un cliente.

La especificación, leída por un tercer autor#

Codex escribió una implementación del álgebra 0.8 desde cero, aislado, con la especificación y sin ver la referencia. El contraste encontró tres preguntas que el texto no contestaba y que ahora contesta con lo que el núcleo ya hacía: ambito va después de requiere y antes de alcance; y/o aceptan dos o más operandos; min/max aceptan booleanos homogéneos, con false < true. La tercera escondía un defecto de la referencia del diferencial, que rechazaba esos booleanos aunque el núcleo los aceptaba; está corregido. Ninguna versión sube: el lenguaje no cambió, se escribió. Detalle en vault-kb/estudios/0.26.0-codex/entrega-2026-09-24/.

Mantenimiento#

Verificación#

Cómo se hizo#

Codex (gpt-6-astra y gpt-6-sol) implementó el patrón de prosa, su distribución, la ergonomía, el refactor, el timeout y init --help. agy investigó Jev, inventarió las fricciones del lenguaje y escribió la primera versión de la relación de prosa. Claude corrió el juicio a ciegas y la medición del MCP en tres clientes, revisó cada entrega —una relación mal ubicada, un inventario con afirmaciones falsas, ejemplos inventados— y cortó.

0.28.0 — retomar es leer una tarea#

VERSION_DISTRIBUCION   0.27.0 → 0.28.0   el tracker como relevo, oracle test honesto y el tope de memoria
VERSION_ALGEBRA        0.8    → 0.8
VERSION_SINTAXIS       0.6    → 0.6

El tracker es el relevo#

El estado del trabajo vivía repartido entre la memoria de cada agente, RELEVO.md, planes y .md sueltos. Ahora vive en las tareas: se retoma con oracle tarea listar y oracle tarea ver <id>, y cada tarea termina con una sola sección ## Próximo paso. El protocolo está en AGENTS.md, los RELEVO*.md quedaron en un puntero, y LyraGASP y Jam tienen su propio tracker.

oracle test dice lo que no midió#

El postmortem de una batalla naval hecha por un agente con Oracle encontró un verde que no medía nada del juego: el catálogo estaba vacío y el verde validaba un caso por su sintaxis. Ahora:

Memoria de la mutación#

Cuatro rondas en paralelo podían sumar 16 GB: el tope por mutante era 4000 MiB por proceso, trece veces lo que la suite necesita. La línea base completa midió 742,51 MiB de memoria virtual máxima; el tope baja a 1024 MiB (37,9 % de margen), en un solo lugar —estaba duplicado entre el perfil y el CLI—, y docs/mutacion-memoria.md dice cuántas rondas lanzar según la memoria disponible y cómo ponerlas bajo un techo común de systemd. Las rondas de este corte corrieron así.

Verificación#

Cómo se hizo#

Codex (gpt-6-astra) implementó buscar-sufijo, test-alcance, cierre-medidas y memoria, y verificó primer-valor, que escribió agy. agy diseñó cierre-medidas. Claude revisó cada entrega —corrigió la sintaxis del diseño, la salida documentada del recorrido y un paso que faltaba—, unió y cortó.

0.27.0 — una sombra perdona hasta su cota, y el MCP se pone al día#

VERSION_DISTRIBUCION   0.26.0 → 0.27.0   juzgar honesto, historia superficial y el MCP
VERSION_ALGEBRA        0.8    → 0.8
VERSION_SINTAXIS       0.6    → 0.6

oracle juzgar y Motor#

⚠ Un proyecto con una sombra por encima de su cota pasa de verde a rojo en oracle juzgar y en Motor. Es el cambio buscado.

El tracker#

oracle tarea hechos --git sobre un clon superficial declara la omisión (.git) y deja la lectura incompleta, en vez de contar commits de menos en silencio. Probado sobre un clon de profundidad 1 de este repositorio: la lectura sale roja y la política de cierres, 31 contra una cota de 4.

El MCP#

oracle-mcp no cambiaba desde 0.7.0. Ahora:

Las cinco siguen siendo de sólo lectura, y el contrato (docs/mcp-contrato.md) dice por qué: los falsos verdes de un agente ocurren al leer, y en el tracker crear o cerrar una tarea sólo vale junto con su commit.

Verificación#

Cómo se hizo#

Claude hizo juzgar, Motor y el tracker. El MCP lo implementó agy (vault-kb/estudios/0.27.0-mcp/); Claude escribió 24 tests de revisión antes de leer la entrega. La entrega armaba mal el Informe de la sombra —toda evaluación de una medida en sombra fallaba— y la refactorización de juzgar convertía un error de evaluación en «sin medidas aplicables»; un test que ya existía lo atrapó. Las dos cosas se corrigieron, junto con siete tests de la entrega que tenían fixtures equivocadas.

0.26.0 — el álgebra puede decir «ninguna»#

VERSION_DISTRIBUCION   0.25.2 → 0.26.0   la anti-junta, y lo que la acompaña
VERSION_ALGEBRA        0.7    → 0.8      un paso nuevo: sin
VERSION_SINTAXIS       0.5    → 0.6      una cláusula nueva: sin … donde …

sin#

El álgebra sabía decir «hay una fila de B que corresponde a esta de A» (unir + donde) y no sabía decir lo contrario. Cinco medidas lo necesitaban y lo resolvían con un conteo calculado en Python, fuera del alcance del diferencial, de la mutación de medidas y del propio catálogo. Ahora es un paso:

medida seguimiento.toda_tarea_cerrada_tiene_su_commit_de_cierre:
    de tarea_seguimiento t
    donde t.estado_declarado == "CERRADA"
    sin commit_seguimiento c donde c.tarea_nombrada == t.id y c.es_cierre == true
    resumen contar(1)
    …

Deja pasar cada fila para la que ninguna fila de la relación cumple la condición, y la deja tal como llegó: el alias nuevo sólo existe dentro de la condición. Los bordes, en §3:

Lo acompañan meta.sin_nunca_agrega_filas sobre la traza (con sus dos casos, 507 y 508), el mutador propio quitar_antijunta (los mutadores pasan de 29 a 30) y la entrada en el vocabulario y el manual.

La prueba de valor#

seguimiento.toda_tarea_cerrada_tiene_su_commit_de_cierre se reescribió con sin, y el emisor del tracker dejó de emitir commits_de_cierre y commits_que_la_nombran en tarea_seguimiento. Sobre la historia real da lo mismo que daba el conteo: 4, las mismas cuatro tareas, dentro de su sombra. Las otras cuatro medidas con conteos del sensor quedan como tarea aparte.

⚠ Quien leía esos dos campos de oracle tarea hechos tiene que cruzar con commit_seguimiento.

La referencia, re-derivada#

agy, en un proyecto nuevo y confinado a un directorio fuera del repositorio, llevó diferencial/referencia/ a 0.8 leyendo sólo la especificación, sin que se le dijera qué había cambiado. Sus 41 tests pasan sin tocar su código. El fixture del diferencial suma un mundo y tres medidas que pasan por sin —directa, después de agrupar y con una condición que levanta detrás de una fila que corresponde—: 10 mundos × 8 medidas, en acuerdo.

Las sondas a sus nueve decisiones nuevas dieron cuatro desacuerdos:

Lo demás#

Verificación#

Cómo se hizo#

agy implementó sin en el núcleo, la superficie, la traza y la reescritura del tracker; Claude escribió 17 tests de revisión antes de leer la entrega (pasaron sin cambios), corrigió dos tests de la entrega que usaban una API que no existe, movió el mutador —agy lo había dejado en la carpeta de los de otros autores, donde nadie lo cargaba— y escribió §3, el corpus, los mundos y el corte. La referencia la re-derivó otra instancia de agy, aislada.

0.25.2 — el verificador del diferencial, fijado; y los dos consumidores en verde#

VERSION_DISTRIBUCION   0.25.1 → 0.25.2   el informe del diferencial fijado y medido en CI
VERSION_ALGEBRA        0.7    → 0.7
VERSION_SINTAXIS       0.5    → 0.5

El que comprueba el acuerdo, comprobado#

tools/diferencial.py es quien dice si Oracle y la implementación independiente coinciden. Declarado custodia en 0.24.0, dio 57 mutantes y 32 sobrevivientes, todos en lo que imprime y en con qué código sale: la marca ✓/✗, las cuentas, cuántas fallas lista y los return. Un informe que dice ✓ con un desacuerdo, o sale 0 con fallas, es el falso verde que el diferencial existe para evitar, contado por su propio verificador.

Lo demás#

Los dos consumidores, en verde#

Subidos a 0.25.1 con el mismo resultado que en 0.24.0. Y los dos quedaron con su suite entera:

Verificación#

Cómo se hizo#

Claude cerró informe y cronica; la nota del vault de Jam la convirtió agy (vault-kb/estudios/vault-jam/) y la verificó Claude. Este corte se hizo desde un worktree limpio de main, mientras agy trabaja en la anti-junta del álgebra 0.8 en el árbol principal.

0.25.1 — borradores de las relaciones que faltan declarar, sin fabricar un verde#

VERSION_DISTRIBUCION   0.25.0 → 0.25.1   oracle relaciones --escribir
VERSION_ALGEBRA        0.7    → 0.7
VERSION_SINTAXIS       0.5    → 0.5

Los dos consumidores conocidos tapan con sombra meta.toda_cantidad_comparada_tiene_unidad_derivable —60 comparaciones en LyraGASP, 54 en Jam— con la misma razón: declarar las relaciones «se hace por relación, no de golpe». Ninguno declara una sola: no tienen carpeta relaciones/, y sin relaciones declaradas no hay unidades que derivar.

oracle relaciones --escribir deja un borrador de cada relación que la evidencia trae y el proyecto no declara, en relaciones-por-revisar/:

La primera versión de esta herramienta declaraba directo y escribía sin_unidad en todo. Sobre LyraGASP bajaba la deuda de 60 a 0, afirmando que medidas en centímetros no tenían unidad: eso no es pagar una deuda, es fabricar un verde, y la propia declaración de una relación dice «no hay defaults silenciosos». Con los borradores, completar uno y moverlo baja la deuda por lo que de verdad se decidió —en la prueba, de 60 a 58—, y el guardián de cotas avisa enseguida que la sombra del consumidor quedó más alta que su deuda.

Verificación#

Cómo se hizo#

Tarea 20260916-035758-declarar, que salió del estudio de las tres sombras que los dos consumidores comparten (vault-kb/estudios/TRES-MEDIDAS-QUE-TODOS-PONEN-EN-SOMBRA.md). La escribió Claude.

0.25.0 — mutar unos sitios sin poder confundirlo con una verificación completa#

VERSION_DISTRIBUCION   0.24.0 → 0.25.0   rondas parciales declaradas, y los commits como hechos
VERSION_ALGEBRA        0.7    → 0.7
VERSION_SINTAXIS       0.5    → 0.5

Rondas parciales#

--objetivo aceptaba archivos enteros y nada más fino. Cada simplificación de unas pocas líneas obligaba a relanzar la ronda completa del archivo —una hora en los grandes— o a aplicar el mutante a mano sobre una copia, que no queda registrado como ronda. En el corte 0.21.0 pasó tres veces; la noche del 15 al 16 de septiembre, cuatro más.

Los commits, como hechos del tracker#

oracle tarea hechos --git emite commit_seguimiento: una fila por commit alcanzable desde HEAD con lo que su asunto declara —si nombra una tarea, cuál, si existe, en qué estado está y si el resumen es exactamente done—. Sin repositorio la relación viene vacía y no se inventa nada.

Con eso, el proyecto de ejemplo gana tres políticas escritas en el lenguaje: ningún commit nombra una tarea inexistente, toda tarea cerrada tiene su commit de cierre, y ningún done deja la tarea abierta. El catálogo distribuido no cambia.

El límite que la tarea quería medir: el álgebra no tiene anti-junta. «Una tarea que ningún commit nombra» no se puede escribir uniendo dos relaciones, así que el tracker cuenta (commits_que_la_nombran, commits_de_cierre) y la medida compara contra cero. Es la división de siempre —el sensor observa, el lenguaje juzga—, pero acá no fue una elección.

Sobre la historia real de Oracle: 459 commits, 87 nombran tarea, ninguno nombra una inexistente y 4 tareas cerradas no tienen su done —tres anteriores a la convención y una con la firma pegada en el asunto—. Queda declarado con sombra y cota 4.

Verificación#

Cómo se hizo#

Las rondas parciales las implementó agy (tarea 20260915-201030-sitios; encargo, avance e informe en vault-kb/estudios/0.25.0-sitios/), y Claude revisó, corrigió y midió: el detalle está en REVISION-CLAUDE.md. Los commits como hechos (20260915-010452-commits) los escribió Claude.

0.24.0 — ningún mutante se come la máquina, y el tracker se lee de un vistazo#

VERSION_DISTRIBUCION   0.23.1 → 0.24.0   tope de memoria en el arnés, y seis deudas cerradas
VERSION_ALGEBRA        0.7    → 0.7
VERSION_SINTAXIS       0.5    → 0.5

El tope de memoria#

tools/mutar_codigo.py limitaba el tiempo y la salida de cada mutante, pero no su memoria. Medido el 2026-09-15 mutando tools/tareas_consulta.py: el mutante not in → in de la línea 65 deja a tokenizar sin avanzar y agrega tokens sin fin; hasta el timeout de 300 s se come la RAM de la máquina, y el sistema mató la ronda dos veces arrastrando procesos ajenos. Desde entonces cada ronda se corría con ulimit -v puesto a mano desde afuera, que no estaba escrito en ninguna parte.

Lo demás que cierra el corte#

Verificación#

Cómo se hizo#

El tope de memoria lo implementó agy (tarea 20260915-112728-memoria, encargo y entrega en vault-kb/estudios/0.24.0-memoria/); Claude revisó, corrigió lo que no corría y lo midió: el detalle está en REVISION-CLAUDE.md. Las otras seis tareas salieron del tracker por prioridad.

0.23.1 — el diferencial ejercita lo que el álgebra agregó, y compara el veredicto entero#

VERSION_DISTRIBUCION   0.23.0 → 0.23.1   fixtures que guardan el veredicto, no sólo el ok
VERSION_ALGEBRA        0.7    → 0.7
VERSION_SINTAXIS       0.5    → 0.5

El álgebra 0.7 agregó requiere con condición y relaciones con variantes, y la implementación de referencia se re-derivó contra esa versión. Pero los cuatro mundos del diferencial no usaban nada de eso: el fixture decía «de acuerdo» sin que la referencia pasara una sola vez por lo nuevo. Es el agujero que documenta b250e6c: cada extensión del lenguaje apaga un pedazo del diferencial si nadie agrega mundos.

Las dos formas del veredicto conviven a propósito: la corta es lo único que afirmaron los fixtures anteriores —y los que siguen emitiendo los consumidores—, así que reclamarles la larga los habría invalidado a todos sin que nada hubiera cambiado.

Verificación#

Cómo se hizo#

Tarea 20260915-201030-diferencial. El dueño decidió que las medidas del contraste vivan junto a los mundos y no en el catálogo distribuido, y que el fixture compare el veredicto entero. El contraste no encontró ningún desacuerdo: en los nueve mundos, las dos implementaciones coinciden en el ok, en el valor y en cuándo levantar. Queda abierta la tarea 20260916-014153-veredictos: los fixtures de los consumidores siguen guardando sólo el ok.

0.23.0 — declarar el ámbito deja de ser cosa de Oracle#

VERSION_DISTRIBUCION   0.22.0 → 0.23.0   la medida del ámbito obliga a todos
VERSION_ALGEBRA        0.7    → 0.7
VERSION_SINTAXIS       0.5    → 0.5

meta.toda_medida_declara_su_ambito se declaraba a sí misma del_origen desde 0.5.0. Era deliberado: si hubiera sido universal, los consumidores se habrían puesto en rojo al instante por medidas escritas antes de que la cláusula existiera. El propio plan de 0.5.0 avisaba que era la clase de decisión temporal que se vuelve permanente por olvido, y que nada registraba cuándo debía terminar.

Un consumidor que actualice con medidas sin ambito va a ver un rojo nuevo, y el remedio es declararlo: universal si la regla obliga a todo proyecto que aporte esa evidencia, del_origen si juzga la instalación de quien la escribió.

Verificación#

Cómo se hizo#

Tarea 20260915-155111-ambito, que existía justamente porque el plan de 0.5.0 dejó la deuda escrita. Se midió primero: 0 medidas sin ámbito en Oracle y en el ejemplo, 27 de 27 en LyraGASP y 41 de 41 en Jam. El dueño eligió declararlas y recién después promover la medida, en vez de anotar el paso con fecha y cota. Cada medida se leyó para decidir su ámbito; el criterio quedó en los commits de cada consumidor.

0.22.0 — toda medida lee campos que existen, y un campo ausente se informa igual en todas partes#

VERSION_DISTRIBUCION   0.21.0 → 0.22.0   campos de las relaciones y medidas que no pudieron juzgar
VERSION_ALGEBRA        0.7    → 0.7
VERSION_SINTAXIS       0.5    → 0.5

Una medida se declaraba aplicable por el nombre de la relación aunque leyera un campo que la evidencia no trae, y nada lo decía antes de evaluar. Al evaluar, cada herramienta lo trataba distinto: mutar y mutar_codigo lo listaban aparte, juzgar salía 2 y la aceptación terminaba en traceback.

Medido antes del cambio: ninguna medida de Oracle, LyraGASP ni Jam lee hoy un campo inexistente en una relación con campos conocidos; los consumidores leen 121 campos de 39 relaciones sin declarar, que la regla no juzga.

Verificación#

Cómo se hizo#

Tarea 20260915-155654-campos. El dueño decidió el alcance de la regla —las relaciones declaradas y las que emite Oracle, no las sin declarar de un consumidor— y que el álgebra siga levantando ante un campo ausente, con una sola forma de informarlo. Implementó agy (el primer lanzamiento cortó por falta de capacidad del servidor; el segundo entregó). Claude revisó con tests escritos antes de leer la entrega y corrigió: los tests que acompañaban la entrega usaban una API que no existe y se reescribieron; un envoltorio en la aceptación hacía que un caso que no se podía juzgar contara como fijado; había lectores duplicados; y el plan dejaba sin declarar dos relaciones de proceso que el volcado real mostró leídas.

Verificación#

Álgebra y sintaxis no cambian: campo_leido es una relación de hechos, como sombra o verbo_del_cli. La publicación en PyPI la realiza el dueño.


0.21.0 — mutante es una relación con variantes, y requiere puede pedir filas de una#

VERSION_DISTRIBUCION   0.20.0 → 0.21.0   relación mutante con variantes
VERSION_ALGEBRA        0.6    → 0.7      requiere con condición, relaciones con variantes
VERSION_SINTAXIS       0.4    → 0.5      requiere <relación> <alias> donde <condición>

La relación mutante la producían dos herramientas con campos incompatibles —la mutación de medidas y la de código—, y el catálogo de Oracle tenía dos medidas universales sobre ella. El lenguaje no cortocircuita y/o y levanta al comparar un campo ausente, así que cada ronda de mutación terminaba con una medida que «NO pudo juzgar» la evidencia de la otra.

Cómo se hizo#

Tarea 20260915-155111-mutante. El dueño eligió la relación común después de ver lo que costaba, y aprobó el requiere con condición cuando la medición mostró que «requiere sobre las filas filtradas» habría pasado a SIN EVIDENCIA las 20 medidas que ya lo usaban. Implementó agy; Claude revisó con tests escritos antes de leer la entrega y corrigió cuatro defectos (la condición recorría el nodo clave, un resultado no booleano pasaba, una validación nueva subía la MAYOR, y tools/mutar.py contaba un SIN EVIDENCIA como política incumplida).

La referencia independiente del diferencial la re-derivó agy en una conversación nueva y aislada, con sólo la especificación y las decisiones (Codex, el autor original, sin cuota). Encontró dos puntos que la especificación no decidía y en los que el núcleo estaba mal: la condición de requiere se evalúa en todas las filas y en todas las entradas antes de decidir, para que el orden de la bolsa no cambie el veredicto. Se corrigió el núcleo y §2 lo dice.

Verificación#

Un proyecto que declara "algebra": "0.6" sigue cargando. La publicación en PyPI la realiza el dueño.


0.20.0 — Motor juzga con el mismo catálogo y las mismas sombras que oracle test#

VERSION_DISTRIBUCION   0.19.0 → 0.20.0   veredicto de la fachada Motor
VERSION_ALGEBRA        0.6    → 0.6
VERSION_SINTAXIS       0.4    → 0.4

LyraGASP y Jam juzgan su evidencia con la fachada pública Motor.desde_proyecto, y esa fachada no juzgaba igual que oracle test sobre el mismo proyecto:

| proyecto | Motor en 0.19.0 | catálogo efectivo | sombras ignoradas | |---|--:|--:|--:| | LyraGASP medidas/ | 84 | 64 | 3 | | Jam medidas/ | 101 | 81 | 3 |

Los consumidores no cambian una línea: con 0.20.0, Motor carga 64 medidas en LyraGASP y 81 en Jam, las mismas que su catálogo efectivo, con sus tres sombras. Motor.desde_datos y desde_medidas no tienen proyecto y siguen sin sombras.

Verificación#

Álgebra y sintaxis no cambian. La publicación en PyPI la realiza el dueño.



Las notas de 0.19.0 y anteriores siguen en docs/notas/anteriores-a-0.20.md.

Esta página se genera desde NOTAS-DE-RELEASE.md.