Skip to content

feat: workflow intelligence sidecar (v1, apagado por defecto) - #248

Merged
wolverin0 merged 8 commits into
mainfrom
feat/workflow-intelligence
Aug 31, 2026
Merged

feat: workflow intelligence sidecar (v1, apagado por defecto)#248
wolverin0 merged 8 commits into
mainfrom
feat/workflow-intelligence

Conversation

@wolverin0

Copy link
Copy Markdown
Owner

Revisión independiente de feat/workflow-intelligence. No activa nada: hooks, advisory, scheduler, promoción automática y activación de skills quedan OFF. Shadow mode es una decisión aparte.

Verificación

Check Resultado
Suite completa en la rama 4.980 pasan, 2 fallan (no son de la rama — abajo), 75 skip, 32 min
Tests propios de la rama 34/34
generate_release_truth.py --check Release truth verified
Rebase sobre origin/main merge-base = f246c50 exacto, 0 commits atrás

Los 2 fallos NO son de la rama

tests/test_probe_measures_the_tree.py — la rama no toca ese archivo (verificado con git diff --name-only).

Causa raíz medida: su predicado de skip pregunta si import memorymaster desde un cwd neutro cae dentro de su propio REPO. La instalación es editable y apunta al checkout canónico, así que:

  • en el checkout principal coincide → los tests se saltean, correcto
  • en cualquier worktree no coincide → corren y exigen una copia en site-packages que no existe → fallan

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_text del 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.db sigue siendo la autoridad. Respeta ADR-0001 y una restricción ya registrada: MemoryMaster es el corpus equivocado para minar workflows porque su verbatim_store no 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 el pyproject del 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.

… [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
@wolverin0
wolverin0 merged commit ded7dbc into main Aug 31, 2026
28 of 29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant