feat: workflow intelligence sidecar (v1, apagado por defecto) - #248
Merged
Conversation
… [no-witness] El guard contract-witness marco dos modulos cambiados con su testigo homonimo intacto. Verificado uno por uno: `rule_miner.py` era un hueco REAL. `_transcript_confidence` gano seis kwargs obligatorios de linaje y NADA lo cubria: cero referencias en tests/test_rule_miner.py y cero en tests/test_rule_observation_lineage.py, que prueba la capa de storage (`record_rule_observation`) pero no que el minero la LLAME bien. El testigo pasaba 49/49 sin tocar la funcion cuyo contrato cambio — verde por no mirar. Tres tests nuevos, uno por rama del contrato: - registra la observacion con su linaje (provider/scope/session_kind) - la MISMA raiz incrementa event_count y no crea soporte independiente: el anti-gaming medido desde el minero, no desde el storage - un store Postgres (DSN) no registra y devuelve la confianza base — el bail-out silencioso que, si se rompe, deja un despliegue Postgres sin acumular linaje para siempre y sin que nada falle Barra roja verificada: sacando el `record_rule_observation` del minero, caen 2 de los 3 (el de Postgres sigue verde correctamente: retorna antes de registrar). `setup_hooks.py` es la excepcion declarada: solo AGREGA `configure_workflow_receipts`, que ya esta cubierta por tests/test_workflow_receipt_hook.py. Cobertura real, en otro archivo. El testigo homonimo sigue describiendo bien lo existente y no tiene nada que actualizar. 17/17 en el testigo.
El generador cuenta funciones de test. Agregue tres y no regenere, que es la CUARTA vez hoy con la misma trampa — y esta vez costo 6 jobs de CI, uno de ellos de 1h10m.
wolverin0
added a commit
that referenced
this pull request
Aug 31, 2026
`release-truth` corre `generate_release_truth.py --check` en unos 30 segundos, pero tenia `needs: test`. La MISMA staleness la detecta `tests/test_release_truth.py` dentro de la suite, asi que `test` fallaba primero y este job quedaba `skipped` — justo en la unica situacion donde servia. Medido hoy sobre el PR #248: 6 jobs de test en rojo, el de Windows 3.12 tras 1h10m, para reportar exactamente lo que este job reportaba en medio minuto. Verificado en la corrida 33405024683: contract-witness success 14:51, release-truth SKIPPED 16:01. Es la cuarta vez en un dia que caigo en la misma trampa: el generador cuenta funciones de test, agregar una sin regenerar deja el archivo viejo. La leccion no es "acordarse" — es que el chequeo que ya existia no podia dispararse. Sin `needs`, el job es independiente: hace checkout, instala y corre --check. No consume nada que produzca `test`.
El registro de linaje quedo ANTES del gate de bootstrap —que es la semantica que la rama quiso, y no se toca— pero eso convirtio un `return` inmediato en una conexion SQLite abierta y cerrada POR ITERACION dentro del bucle de `mine_transcript_rules`. `service.py:797` muestra que `run_cycle` recorre ese bucle, asi que el costo entra en cycle_p95. Firma del perf en CI que lo delato (PR #248, tres umbrales, no dos): ingest_p95 0.1636 > 0.120 ingest_throughput 18.62 < 40 cycle_p95 6.5482 > 6.000 <- este no se rompia antes MEDIDO, fail-first, mismo benchmark antes y despues (benchmarks/bench_transcript_confidence.py, 200 llamadas, raiz distinta cada una): ROJO 12.585 ms/llamada 79.5/seg VERDE 3.213 ms/llamada 311.2/seg -> 3.9x Como: `_lineage_connection(service)` es un context manager que cede la conexion o None (Postgres), y se suma al `with` que ya estaba — sin re-indentar el cuerpo del bucle. `_transcript_confidence` acepta `conn` opcional: si se la pasan la reusa y NO la cierra; sin ella abre y cierra como antes. El gate de bootstrap sigue exactamente donde la rama lo puso. Dos tests nuevos para que un refactor no lo revierta en silencio: la conexion izada sigue usable despues del lote (nadie la cerro adentro) y un store Postgres cede None sin romper el bucle. 19/19 en el testigo, ruff limpio, release-truth regenerado.
…gence # Conflicts: # docs/generated/release-truth.json # docs/generated/release-truth.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Verificación
generate_release_truth.py --checkmerge-base=f246c50exacto, 0 commits atrásLos 2 fallos NO son de la rama
tests/test_probe_measures_the_tree.py— la rama no toca ese archivo (verificado congit diff --name-only).Causa raíz medida: su predicado de skip pregunta si
import memorymasterdesde un cwd neutro cae dentro de su propioREPO. La instalación es editable y apunta al checkout canónico, así que:Es un artefacto de correr la suite desde un worktree. Bug latente de
main, no de esta rama, y por eso no lo toco acá (la instrucción era arreglar sólo problemas demostradamente de la rama).Revisión del diseño
Migración 0024 — puramente aditiva (
CREATE TABLE IF NOT EXISTS rule_observations, sin ALTER/DROP/UPDATE) y con paridad Postgres, cumpliendo el Boundaries del repo.Redacción — reusa
redact_textdel filtro canónico en vez de reimplementarlo, agrega paths absolutos e IP privadas, y trunca después de redactar: truncar antes podría partir un secreto y dejar un fragmento que ya no matchea. Tope duro de 400 chars.Frontera de confianza — sidecar desechable en
~/.memorymaster/workflow-intelligence.db;memorymaster.dbsigue siendo la autoridad. Respeta ADR-0001 y una restricción ya registrada: MemoryMaster es el corpus equivocado para minar workflows porque suverbatim_storeno tiene metadata de ejecución de tools — esto lee transcripts crudos en su lugar.Gobierno de candidatos — el listón es evidencia estructural, no juicio de un modelo: 3 raíces humanas independientes por candidato de proyecto, +2 proyectos para user/global. Minar repetido sobre el mismo
(provider, root)incrementa un contador y no crea soporte independiente. Observaciones de subagentes y automatización son diagnósticas. Filas históricas no se backfillean como evidencia autoritativa.release-truth— pasa de leer metadata instalada a parsear elpyprojectdel checkout, con test propio. Es la misma dirección que el repo ya tomó para el conteo de tests, y arregla el gotcha registrado de metadata global vieja contra código del worktree.Lo que queda fuera de este PR
Aplicar la migración por la vía gobernada (
migrate) y el scan inicial metadata-only van después del merge: correr una migración desde código sin integrar contra la base de producción sería el orden equivocado.