basquetWi + New ticket
movilba MOVILBA-224

BLOQUEANTE DE ARRANQUE: ninguna columna distingue lo que escribio una PERSONA de lo que escribio un import, y el import ahora borra y reconstruye

Done urgent dmdb03-mba-l-cc

DIRECTIVA DE ELAZAR, 2026-09-03, CLI, verbatim: 'truncate tables, disable the borrado_en borardo_por and all that triggers until we finish, hard delete old records before we import new records, i am tired of this. only keep catalogs and personas, empresas, etc. re-build vehiculos and cdv or whatever the colectivos data table is called anew each import, else it is hell'. LA DIRECTIVA ES CORRECTA y es la regla que ya teniamos, bien ejecutada: el libro RUTAP es un SNAPSHOT, no un ledger, y el import REEMPLAZA. Reconciliar estado acumulado contra un libro que lo re-declara entero era el trabajo infinito. Esto NO es un item para frenar el rebuild. ES EL ITEM QUE LE PONE FECHA DE VENCIMIENTO. Todo lo que el rebuild borra vuelve DEL LIBRO. Lo que escribio una persona no vuelve de ningun lado. HOY ES CASI GRATIS, MEDIDO: de las 4225 filas de vehiculo_historial en PROD, 4224 las escribio un importador o una migracion y UNA sola vino de la app. O sea el rebuild hoy cuesta una fila. Y NO PODEMOS DISTINGUIRLAS. Medido por mi el 09-03 contra PROD: creado_por IS NOT NULL en 4225 de 4225 filas, asi que esa columna NO discrimina. Es lo mismo que ya reporta MOVILBA-182 desde el otro lado - creado_por dice 'system_import' en 24 de los 29 vehiculos que la app creo por pantalla. Y reference_creado_por_afirma_system_import_donde_no_sabe ya lo dice como regla: creado_por NO prueba origen y audit_log es TESTIGO, no censo. LA CONSECUENCIA, en una linea: despues del arranque, lo primero que edite un usuario es lo primero que el proximo import borra en silencio. Sin error, sin log, sin diferencia visible - el mismo modo de falla que el no-op silencioso de MOVILBA-221, a escala de tabla. QUE HACE FALTA (la forma la decide el carril de base, no este ticket): una marca de PROCEDENCIA por fila que el import no pueda escribir, y una regla de rebuild que preserve lo marcado en vez de truncarlo. 'Lo escribio una persona' tiene que ser una pregunta que la tabla conteste sola, no una que se deduzca de creado_por, de un timestamp o del audit_log. GATE DE ARRANQUE, y esta es la unica parte no negociable: mientras esto no exista, un import de reemplazo despues del 09-07 destruye trabajo de usuario. Antes del arranque hay que tener la marca, O una prohibicion explicita de correr el import de reemplazo con usuarios adentro. Una de las dos, escrita. CONTROL: hoy la afirmacion '4224 de 4225 son de import' se sostiene por conteo, no por la columna. Cuando exista la marca, el control positivo es una edicion REAL por pantalla que quede marcada y SOBREVIVA a un rebuild en DEV. Sin esa prueba el gate pasa por ausencia de input.

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Activity

  • wi-cli-venus created · 6w ago
  • wi-cli-venus note · 6w ago
    NOTA MAL ARCHIVADA, la puse en MOVILBA-225 (el bug de la vista) cuando es de ESTE item. TRES CORRECCIONES DE db02-mba-l-cc, medidas, que abaratan mucho este bloqueante. 1. EL PATRON DE PROCEDENCIA YA EXISTE EN ESTE ESQUEMA. Las tres tablas de vehiculos no tienen NINGUNA columna de actor (cero matches de actor|usuario|user|persona|editad|modific), pero validadoras_historial ya trae actor_id, actor_nombre y actor_email, y validadoras, validadoras_historial y validadoras_historial_ubicaciones ya llevan triggers *_append_only y *_no_truncate. O sea este item NO es 'inventar un mecanismo de procedencia': es 'aplicarle a las tablas de vehiculos el patron que las tablas de validadoras ya shipean'. Eso tambien abarata MOVILBA-182. 2. CORRECCION AL CONTEO, conclusion sin cambios. No son 4224 de import y 1 de la app. creado_por en PROD: import-rutap-2026-08-14-prod 2274, system_import 1599, snapshot5 171, import-movilba-19 164, movilba-104-prod 7, import-movilba-18 4, import-movilba-24 3, 'Elazar (GO 2026-08-25 via db02-mba-l-ca)' 2, '20394678369' 1. O sea 4222 de import/migracion, 2 escritas por un agente bajo GO, 1 de la app. creado_por sigue sin discriminar. 3. YA TENEMOS 233 FILAS DEL PROBLEMA, HOY, EN DEV. rendiciones.deudas_dominios tiene 233 filas con FK a vehiculos y NO sale del libro. No es un riesgo futuro: es el primer dataset concreto que un import de reemplazo destruye. Se salva porque esa tabla ya trae una columna dominio al lado del vehiculo_id. LA REGLA GENERAL: ATRAVESANDO UN REBUILD, LA CLAVE ESTABLE ES dominio; EL id SUBROGADO NO. Un import de reemplazo reasigna vehiculos.id, asi que cualquier cosa que guarde un vehiculo_id guarda un puntero que el rebuild invalida EN SILENCIO - sin error de FK, porque el id se reusa para otro vehiculo. Todo lo que no venga del libro se aparca por dominio antes del delete y se re-resuelve despues.
  • wi-cli-venus note · 6w ago
    EL DISCRIMINADOR YA EXISTE Y ES CONFIABLE - db02-mba-l-cc, medido en PROD 2026-09-03. Esto cambia el item de 'diseñar un mecanismo de procedencia' a 'poblarla desde current_user en un trigger'. vehiculos_datos_colectivos_archive.archived_by en PROD: 1271 NULL, 4 'import-2026-08-05', 2 'svc_nextjs', 1 'import-2026-06-29'. svc_nextjs es el rol de base de la app, o sea esas 2 filas estan marcadas como escritas POR LA APP, en una columna donde creado_por no discrimina nada. EL MECANISMO ES EL PUNTO, NO LA COLUMNA. archived_by lo escribe el TRIGGER desde el rol de la conexion. creado_por es un string que pasa el llamador - y es exactamente asi como el importer escribio 'system_import' encima de 24 de los 29 vehiculos que la app creo por pantalla (MOVILBA-182). UN VALOR QUE ELIGE EL QUE ESCRIBE NO ES EVIDENCIA DE QUIEN ESCRIBIO. Esa es la regla, y es la que hace que este item sea barato: el patron ya esta visible dos veces en el esquema, aca y en las columnas actor_* de validadoras_historial. Y AMPLIA EL ALCANCE DEL DAÑO: las tablas de archivo son justo la clase que este bloqueante protege - son el registro de QUE cambio, no salen del libro, y no tienen FK, asi que ninguna lista de dependencias las encuentra. Ver MOVILBA-226 para el detalle y la restriccion de orden.
  • wi-cli-venus note · 6w ago
    DECISION DE ELAZAR, 2026-09-04: **despues del arranque no hay mas imports.** Eso cambia lo que este item es. Deja de ser un bloqueante de arranque y pasa a ser limpieza, porque el riesgo que describia -que un import futuro pise trabajo de una persona sin que nada lo distinga- se termina el dia del go-live. Tambien pidio usar la cuenta de import que ya existe. **YA EXISTE Y YA ESTA UNIFICADA** (medido 2026-09-04, DEV y PROD): id `system_import` | email `system_import@movilba.local` | name `Sistema - Importacion` | is_active=false | creada 2026-08-12 **Mismo id y mismo nombre en los dos entornos. NO hay duplicados que borrar.** DEV tiene ademas `99999999999 / Test Admin Dev`, que es fixture de test y no es cuenta de import. LO QUE SI FALTA, y es todo el trabajo que queda: 1. **`vehiculos.creado_por` NO tiene FK contra `users`.** Otras tablas si (`entidades_creado_por_fkey`, `opciones_creado_por_fkey`, `instalaciones_*`, etc.). Por eso hoy PROD guarda 8 valores distintos: `system_import` (2248), `import-movilba-19` (131), CUITs sueltos, y una frase entera: `Elazar (GO 2026-08-25 via db02-mba-l-ca)`. 2. Los importers escriben etiquetas inventadas por corrida (`import-movilba-19`, `import-rutap-snapshot-7`, `import-rutap-faltantes-2026-08-21-dev`) en vez del id `system_import`. PLAN, en este orden: a. El loader de MOVILBA-227 escribe `creado_por = 'system_import'`. Sin excepcion, sin sufijo de corrida. **Que corrida fue** es dato del snapshot (`rutap.snapshots`), no de la fila de negocio - meterlo en `creado_por` es lo que produjo las 8 variantes. b. Backfill de los valores `import-*` a `system_import` (PROD 136 filas: 131+4+1). Los CUITs NO se tocan: son personas reales. c. Recien despues, `ALTER TABLE vehiculos ADD CONSTRAINT vehiculos_creado_por_fkey FOREIGN KEY (creado_por) REFERENCES users(id)`. Con la FK puesta, una frase suelta no entra nunca mas y un CUIT solo entra si es un usuario real. La FK es el gate: mientras no este, cualquier acuerdo sobre que escribir es una convencion que el proximo script rompe sin enterarse. OBJECION QUE SI TENGO, chica: `system_import` tiene `is_active=false`. Correcto para que nadie loguee con ella, y no impide la FK. Pero si alguna vista o consulta filtra `users` por `is_active`, la atribucion del import se ve vacia. **Verificar eso ANTES del backfill**, no despues. No lo medi.
  • wi-cli-venus note · 5w ago
    MOVILBA-168 parte 2 (formulario unico de edicion de colectivo: persistir expediente/motivo de una edicion hecha por pantalla) quedo BLOQUEADA por este item, y es el primer consumidor concreto que lo necesita en vez de argumentarlo en abstracto. coder03 llego a la parte 2 y no tiene donde escribir: la tabla ancha es un espejo de snapshot que el import reemplaza, asi que un writer de usuario contra ella es perdida de datos silenciosa por construccion. Vale como el CONTROL POSITIVO que este item pedia y no tenia: 'cuando exista la marca, el control positivo es una edicion REAL por pantalla que quede marcada y SOBREVIVA a un rebuild en DEV'. La edicion por pantalla de 168 parte 2 ES esa edicion. Los dos items se prueban con la misma corrida. Estado al 2026-09-05 05:00: sin dueno ejecutando. Asignado a db03-mba-l-ca, que esta ejecutando MOVILBA-125 paso 3. Arranque tentativo 09-07.
  • wi-cli-venus verified · 5w ago
    db02 2026-09-05, DEV, medido - no cierra ni desbloquea el item; lo re-encuadra. 1. LA MARCA YA EXISTE CON LA FORMA CORRECTA Y NO SE USA. rutap.vehiculo_historial_normalizado tiene normalizado_por (text NOT NULL, SIN DEFAULT), normalizacion_estado (NOT NULL, CHECK resuelto/pendiente/conflicto) y normalizado_en. NOT NULL sin default obliga a TODO escritor a declarar un valor, que es exactamente la forma que 224 pide. Hoy no discrimina nada: 1 solo valor distinto, 'movilba-203', en las 5370 filas. Es la misma falla que creado_por y por la misma razon - un solo escritor la uso. 2. LA MARCA QUE EL IMPORT NO PUEDE FALSIFICAR NO ES UNA COLUMNA. La tabla lleva raw_* verbatim al lado de cada columna tipada, y el import DERIVA la tipada DESDE la raw. Entonces 'la tipada no coincide con el transform de su propia raw_' es una senal de edicion por CONSTRUCCION, no por convencion. No hay que construir nada para DETECTAR una edicion. 3. Y HOY ESA SENAL ESTA CONTAMINADA, POR NOSOTROS. Medido: la tipada difiere de la raw en 271 filas (expte_alta), 203 (expte_baja) y 172 (observaciones), denominador 5370. TODAS son MOVILBA-248. CERO son ediciones de usuario. Un detector construido hoy sobre esta senal reporta 100% de falsos positivos. Eso vuelve a MOVILBA-252 (el transform en el loader) PREREQUISITO de 224, no un item hermano: recien cuando el loader aplique la regla de 248 vuelve a valer tipada == transform(raw), y la divergencia vuelve a significar 'aca escribio una persona'. 4. LA MITAD DIFICIL ES PRESERVAR, NO MARCAR. vh_norm_raw_fk es (rutap_snapshot_id, rutap_fila_excel) REFERENCES rutap.rutap_rows MATCH FULL ON DELETE CASCADE. Un rebuild que borre las rutap_rows de un snapshot se lleva las filas marcadas con el, sin error y sin log. Cualquier diseno de 224 tiene que sobrevivir a ese cascade, y source_fingerprint (5370 distintos, uno por fila) es el unico ancla por fila contra el contenido del que la fila se derivo. 5. La evidencia de borrado_por citada en el hub es sobre public.vehiculo_historial, otra tabla. Muestra que ESA tabla puede contestar una pregunta de origen; no dice nada de la ancha, que no tiene borrado_por. NO EJERCITADO: no se probo ninguna edicion real de usuario, ni un rebuild, ni el comportamiento del cascade con filas marcadas. Todo lo de arriba es estructura de esquema mas conteos de hoy en DEV.
  • wi-cli-venus spec · 5w ago
    db02-mba-l-cc midio la tabla ancha, 2026-09-05 (filed por coder02). CAMBIA LA FORMA DEL ITEM: la deteccion ya existe, lo que falta es la PRESERVACION. 1. LA MARCA NO TIENE QUE SER UNA COLUMNA NUEVA. rutap.vehiculo_historial_normalizado guarda raw_* verbatim al lado de cada columna tipada, y el import DERIVA la tipada DE su raw_. Entonces 'la tipada no coincide con el transform de su propia raw_' es una senal de edicion POR CONSTRUCCION, no por convencion, y ningun import la puede falsificar sin dejar de ser el import. 2. LAS COLUMNAS QUE PARECIAN LA RESPUESTA NO DISCRIMINAN: normalizado_por (text NOT NULL, sin default), normalizacion_estado (NOT NULL, CHECK resuelto/pendiente/conflicto) y normalizado_en existen y tienen la forma correcta - NOT NULL sin default obliga a todo escritor a declarar un valor - pero hoy hay UN solo valor distinto, 'movilba-203', en las 5370 filas. Mismo fracaso que creado_por y por el mismo motivo: un solo escritor las uso. 3. LA SENAL ESTA CONTAMINADA HOY Y LA CONTAMINAMOS NOSOTROS. tipada != raw en 271 filas (expte_alta), 203 (expte_baja) y 172 (observaciones) en DEV, y TODAS son MOVILBA-248a, cero son ediciones de usuario. Un detector construido hoy sobre esta senal da 100% de falsos positivos. NO es que falte el transform en el loader - eso esta hecho (248c cablea rutap.expediente_desde_libro/observaciones_desde_libro en el writer del snapshot ancho, MOVILBA-252 cerrado): es que el writer NO SE VOLVIO A CORRER desde que 248a arreglo las filas. La divergencia se limpia sola en el proximo wide-refresh, que es una escritura en DEV con su propia decision. 4. EL PROBLEMA DURO, Y ES EL QUE NO TIENE DISENO: vh_norm_raw_fk es (rutap_snapshot_id, rutap_fila_excel) REFERENCES rutap.rutap_rows MATCH FULL ON DELETE CASCADE. Un rebuild que borra los rutap_rows de un snapshot SE LLEVA LAS FILAS MARCADAS con el, sin error y sin log. Cualquier regla de preservacion que 224 defina tiene que sobrevivir ese cascade. source_fingerprint (5370 distintos, uno por fila) es el unico ancla por fila al contenido del que la fila se derivo. 5. LIMITE DE LA EVIDENCIA DE borrado_por que aporte antes: es sobre public.vehiculo_historial, otra tabla. Demuestra que ESA tabla puede contestar una pregunta de origen; no dice nada de la ancha, que no tiene borrado_por. RECOMENDACION DE db02 PARA EL 09-07, que comparto: tomar la salida barata del gate - la PROHIBICION ESCRITA de correr el import de reemplazo con usuarios adentro. Shipear una marca en dos dias la pondria encima de una senal que nuestra propia migracion esta falseando hoy, y el cascade es una pregunta de diseno, no una columna.
  • wi-cli-venus note · 5w ago
    db02 2026-09-05, CORRECCION DE MI EVENTO ANTERIOR, verificada en el codigo y no tomada del reporte. DIJE QUE MOVILBA-252 ERA PREREQUISITO DE 224. ES FALSO: 252 ESTA HECHO. Verificado en origin/dev, commit a2649f19: docs/migrations/2026-09-04-movilba-203-wide-refresh-snapshot10-DEV.sql lineas 236-238 escriben las columnas tipadas como rutap.expediente_desde_libro(expte_alta), rutap.expediente_desde_libro(expte_baja) y rutap.observaciones_desde_libro(observaciones, expte_alta, expte_baja), y el UPDATE de lineas 271-272 deja raw_expte_alta/raw_expte_baja/raw_observaciones como espejo verbatim. Las tres funciones existen en DEV y son IMMUTABLE. Mi grep dio cero porque el checkout compartido esta atrasado: era pregunta de RAMA, no de disco. O sea que las 271/203/172 divergencias NO son un transform faltante: son que EL WRITER NO CORRIO desde que 248a reparo las filas. Un refresh de la tabla ancha vuelve a derivar la tipada desde la raw a traves del transform y la divergencia se va sola. 224 no esta parado detras de nada. Y ESO MISMO ES LA DEMOSTRACION DEL PROBLEMA DE PRESERVACION, no un aparte: el writer hace DELETE (lineas 112 y 115) y despues INSERT. La corrida que probaria la linea base cero del detector es LA MISMA OPERACION que borraria cualquier edicion de usuario que viviera en la tabla ancha. No hace falta el cascade de vh_norm_raw_fk para perder las marcas - alcanza con el DELETE propio del writer. La regla de preservacion tiene que sobrevivir a las DOS cosas. NO EJERCITADO: no corri el writer ni verifique que despues de correrlo la divergencia efectivamente de cero. Eso es una escritura en DEV y no fue pedida.
  • wi-cli-venus spec · 5w ago
    db02-mba-l-cc, 2026-09-05, leido del codigo (filed por coder02). EL CASO FRECUENTE ES PEOR QUE EL DRAMATICO. El writer del snapshot ancho BORRA Y REINSERTA: DELETE en las lineas 112 y 115 del archivo de wide-refresh, despues el INSERT. O sea que la regla de preservacion de este item no tiene que sobrevivir solamente al ON DELETE CASCADE de vh_norm_raw_fk cuando alguien tira los rutap_rows de un snapshot - tiene que sobrevivir al DELETE PROPIO DEL WRITER en un refresh RUTINARIO DEL MISMO SNAPSHOT. El cascade es el caso dramatico; el refresh ordinario es el que va a pasar de verdad, y hoy se lleva puesta cualquier edicion de usuario que viva en la tabla ancha. CONSECUENCIA PARA EL DISENO: 'preservar lo marcado' no puede implementarse como una excepcion al cascade. Tiene que ser una regla que el propio writer ejecute - o el dato editado por una persona no vive en esta tabla. Las dos salidas son legitimas y el item tiene que elegir una explicitamente. CONSECUENCIA OPERATIVA HOY: correr el wide-refresh para limpiar los 271/203/172 de divergencia tipada-vs-raw (que son 248a y no ediciones) NO es una operacion neutra - es exactamente la operacion cuya semantica este item todavia no decidio. Queda fuera de esta noche. 252 QUEDA CONFIRMADO COMO HECHO, no como prerequisito: db02 leyo a2649f19, el writer escribe las tipadas por rutap.expediente_desde_libro x2 y rutap.observaciones_desde_libro (lineas 236-238) y deja el espejo raw_* verbatim (271-272); las tres funciones existen en DEV y son IMMUTABLE. El grep que sugeria lo contrario salio del checkout compartido, que esta atrasado - 'que codigo esta vivo' es una pregunta de RAMA. NO EJERCITADO: nadie corrio el writer, asi que 'la divergencia se limpia sola en el proximo refresh' esta leido del codigo y sin medir.
  • wi-cli-venus statusChanged · 5w ago
    db03 executing the 09/07 gate document: explicit prohibition on replacement imports while users exist; preservation-rule design follows without DB writes.
  • wi-cli-venus progress · 5w ago
    Gate document written: docs/design/movilba-224-import-prohibition.md. It prohibits any replacement import/refresh in an environment with user-authored data until an edit is proven identifiable and durable through rebuild.
  • wi-cli-venus assigned · 4w ago
    db03-mba-l-cc
  • wi-cli-venus assigned · 4w ago
    db02-mba-l-cc
  • wi-cli-venus note · 4w ago
    MEDICION DE LA PREMISA DE ESTE ITEM - db02-mba-l-cc, 2026-09-12, DEV (movilba_dev 10.9.10.54, PG 15.17) y PROD (movilba 10.78.42.168, PG 17.6), SOLO LECTURA. Nada ejecutado. Se mide porque la directiva de este item -truncate, deshabilitar triggers, hard delete y reconstruir- descansa sobre 'ninguna columna distingue lo que escribio una PERSONA de lo que escribio un import', y esa frase resulto ser cierta en unas tablas y falsa en otras. Una directiva destructiva fundada en una premisa que vale a medias tiene que nombrar EN QUE TABLAS vale. 1. HAY EXACTAMENTE UNA TABLA CON DISTINCION DE VERDAD. rutap.vehiculo_historial_normalizado tiene origen ademas de normalizado_por, y los tiene en LOS DOS entornos. Ahi la pregunta se contesta sin adivinar: origen='import' contra origen='app'. En DEV hoy hay 70 filas con origen='app' y rutap_snapshot_id NULL - 22 'app-create-colectivo' y 48 'app-editar-colectivo', del 2026-09-11. El espejo ancho YA resolvio este problema. 2. TODO EL RESTO TIENE SOLO creado_por, y creado_por NO ES UNA DISTINCION: es una sola columna de texto que guarda CUATRO clases de valor a la vez. (a) un id de cuenta numerico de 11 digitos - no transcribo valores, son datos personales; (b) una etiqueta de import (system_import, import-rutap-2026-08-14-prod, import-movilba-19, import-2026-06-29); (c) una etiqueta de corrida de un carril (db-mba-l-cc-snapshot5-nuevos-eslabones-2026-08-25); (d) prosa libre que nombra una decision humana - en PROD hay filas que dicen literal 'Elazar (GO <fecha> via <carril>)'. Separar persona de import ahi es pattern-matching sobre un prefijo, y eso se rompe en silencio el dia que alguien inventa una etiqueta nueva. Ya hay cuatro convenciones conviviendo. 3. CONTEO, solo filas vivas (borrado_en IS NULL), formato total / NULL / cuenta-de-persona / etiqueta-de-import / otro / valores-distintos: DEV vehiculos 2425 / 0 / 26 / 2395 / 4 / 10 DEV vehiculos_datos_colectivos 2425 / 2180 / 14 / 227 / 4 / 12 DEV vehiculo_historial 5484 / 0 / 3 / 5481 / 0 / 5 PROD vehiculos 2407 / 0 / 12 / 2393 / 2 / 8 PROD vehiculos_datos_colectivos 2407 / 2179 / 0 / 226 / 2 / 7 PROD vehiculo_historial 1740 / 0 / 1 / 1565 / 174 / 9 4. LO MAS IMPORTANTE DEL CUADRO, y es sobre la tabla que la app edita de verdad: en vehiculos_datos_colectivos creado_por esta en NULL en 2180 de 2425 filas vivas en DEV y 2179 de 2407 en PROD. Y en PROD, CERO filas de esa tabla llevan una cuenta de persona. Ahi la distincion no es poco confiable: esta AUSENTE. Es la misma tabla de MOVILBA-259 y MOVILBA-435, donde un usuario edita el estado por pantalla. 5. La autoria humana es ademas rarisima donde existe: 26 filas de 2425 en DEV vehiculos, 12 de 2407 en PROD. Coherente con MOVILBA-354 y MOVILBA-182 - la recarga pisa creado_por y deja la etiqueta del import. 6. QUE SIGNIFICA PARA LA DIRECTIVA. El reconstruir-de-cero no destruye una distincion que exista en las tablas del nucleo, porque ahi no existe; en vehiculos_datos_colectivos no hay nada que perder porque ya es NULL. Pero SI destruiria las 70 filas origen='app' del espejo ancho, que es el unico lugar donde la distincion es real y esta poblada. O sea que la premisa de este item se invirtio: el problema no es que falte la columna en todos lados, es que existe en UN lado y el rebuild pasaria por encima justo de ese lado. 7. Vale la regla ya escrita: creado_por identifica una CUENTA, jamas a un operador, porque los carriles navegan dev01 con la cuenta de Elazar. Nada de lo de arriba dice quien tuvo el teclado; dice que camino de escritura quedo registrado. Este carril no ejecuta nada de este item. Queda para que Elazar re-decida sobre la fila.
  • wi-cli-venus note · 4w ago
    CORRECCION AL PUNTO 6 DE MI NOTA ANTERIOR - db02-mba-l-cc, 2026-09-12, mismo dia. Escribi que el rebuild 'SI destruiria las 70 filas origen=app del espejo ancho'. Eso es una AFIRMACION, no una medicion, y la retiro como estaba escrita. La directiva de Elazar, citada de la descripcion de este item, nombra: 'only keep catalogs and personas, empresas, etc. re-build vehiculos and cdv or whatever the colectivos data table is called anew each import'. Nombra vehiculos y cdv. NO nombra rutap.vehiculo_historial_normalizado, ni para incluirla ni para excluirla. La forma correcta del punto 6: el rebuild no destruye una distincion que no existe en las tablas del nucleo, y en vehiculos_datos_colectivos no hay nada que perder porque creado_por ya es NULL en la enorme mayoria. Y SI el alcance del rebuild incluye al espejo ancho, entonces pasaria por encima del unico lugar donde la distincion es real y esta poblada. El alcance no esta dicho en la directiva, y ESA es la pregunta para Elazar, no una consecuencia que yo pueda declarar. Dato relacionado que tampoco lo resuelve solo: DEV tiene el trigger vh_norm_reject_app_delete armado justamente para impedir borrados sobre esa tabla, y la directiva dice deshabilitar triggers. O sea que la proteccion existente es exactamente la que la directiva manda apagar - por eso el alcance hay que decirlo, no deducirlo.
  • wi-cli-venus note · 4w ago
    AGREGADO A LA MEDICION DE creado_por - db02-mba-l-cc, 2026-09-12, DEV. Falta una clase de valor en mi nota: dije 'id de cuenta numerico de 11 digitos', y el id de cuenta NO siempre tiene esa forma. public.users.id es TEXT y en DEV hay 35 usuarios: 32 con id de 11 digitos y 3 con un id alfanumerico corto. Filas de public.vehiculos creadas el 09-08 llevan en creado_por uno de esos ids alfanumericos. Por que importa y no es un detalle: cualquier clasificacion de creado_por que separe persona de import con un patron -que es lo unico que se puede hacer con una columna sobrecargada- va a clasificar esos ids alfanumericos como 'etiqueta', o sea como import, cuando son personas. El unico patron correcto no es un regex sobre el valor sino un JOIN contra public.users, y eso no esta declarado en ningun lado: la columna es text libre, sin FK. No cambia ninguna de las conclusiones anteriores. Empeora la misma: creado_por no distingue, y el intento de hacerla distinguir a posteriori falla en silencio justo con las cuentas mas nuevas.
  • wi-cli-venus note · 4w ago
    db02-mba-l-cc, 2026-09-18, verificacion INDEPENDIENTE en PROD (no solo DEV como reporto audit) contra los dumps propios del censo MOVILBA-479, misma sesion: origen (columna), vh_norm_origen_ck, vh_norm_app_snapshot_ck (la que hace que un import jamas pueda escribir origen='app', porque exige origen='import' siempre que rutap_snapshot_id no sea NULL) y el trigger vh_norm_reject_app_delete (ENABLED, cuerpo byte-identico salvo whitespace, RAISE EXCEPTION sobre OLD.origen='app') estan presentes en LOS DOS lados, no solo DEV. Esto es un backstop de trigger a nivel DB, mas fuerte que un comentario en proyectar_snapshot, y cubre el DELETE propio del writer de wide-refresh, no solo el cascade de vh_norm_raw_fk. NO CIERRO el item: el propio texto del ticket exige un control positivo -una edicion real por pantalla que sobreviva un rebuild en DEV- y ni yo ni audit lo ejecutamos. Mecanismo verificado estatico en los dos entornos; control positivo pendiente. Enviado a audit para decidir ruteo a coder03/Elazar.
  • wi-cli-venus note · 4w ago
    coder03-mba-l-cc, 2026-09-18: no se puede fabricar el control positivo desde un carril - un INSERT directo con origen='app' probaria el constraint, no el writer, mismo fallo sintetico ya registrado en MOVILBA-344. Necesita una edicion real por pantalla en DEV via UI, que ningun carril puede hacer (sin credenciales de app, sin correr dev server). Escalado a Elazar como una sola accion concreta: una edicion a un vehiculo en DEV via UI, despues db02 corre rutap.proyectar_snapshot y verifica que la fila conserva origen='app' y sobrevive. ESTADO ACTUAL - declaracion de cobertura, no veredicto: columna origen, CHECK vh_norm_origen_ck, CHECK vh_norm_app_snapshot_ck y trigger vh_norm_reject_app_delete (enabled, cuerpo identico) VERIFICADOS presentes en DEV y PROD. El camino de escritura real (la app efectivamente estampando origen='app' en una edicion real y esa fila sobreviviendo un rebuild) NO fue ejercitado. No cerrar 224 ni mover 168 a done sobre la evidencia estatica.
  • wi-cli-venus note · 3w ago
    audit-mba-l-cc, 2026-09-22 05:18 ART, leido de docs/migrations/2026-09-19-movilba-516-reconciliar-snapshot-origen-agnostico-DEV-Y-PROD.sql, la funcion instalada mas reciente. RESPUESTA A LA PREGUNTA DEL ITEM (columna nueva vs repurpose): 1. rutap.vehiculo_historial_normalizado (origen + los dos CHECK + trigger vh_norm_reject_app_delete) SIGUE protegiendo esa tabla, con UNA excepcion ya decidida: cuando un vehiculo desaparece del libro, 516 (Opcion A, Elazar 2026-09-19) hace DELETE fisico 'sin distinguir procedencia' y para eso DESHABILITA el trigger por nombre (lineas 700-705), borra, y lo re-habilita (760-765). Esto es el camino documentado, no un agujero nuevo. 2. EL AGUJERO REAL sigue vivo en public.vehiculos_datos_colectivos (vdc), que es la tabla que la UI edita segun el propio 224 (nota db02 09-12, punto 4). vdc NO tiene columna origen ni equivalente. El UPDATE del reconciliador (lineas ~655-673) pisa SIN GATE de procedencia, para todo vehiculo que SIGUE en el libro: interno, consumo, identificacion_camaras_adas, ip_canbus, ip_mdvr, conexiones_usb, adas_presente_id, cabina_antivandalica_id, camaras_adas_cantidad, camaras_internas, mdvr_id, pantallas_id, wifi_id, regimen_servicio_modalidad_id, estandar_emisiones_id, identidad_id, expte_alta, expte_baja, fecha_vigencia_desde/hasta, estado_id -- toda columna 'del libro'. Si un usuario edita cualquiera de esas por pantalla en un vehiculo que sigue en el libro, el proximo import la pisa en silencio, sin error, sin log: exactamente el modo de falla que el item nombra. 3. HALLAZGO NUEVO: ya existe una particion de facto en el propio UPDATE. Columnas de vdc NUNCA tocadas por el reconciliador: observaciones, creadoEn, creadoPor, borradoEn, borradoPor, subeIdValidadora, subeMountingKit, openpassIdValidadora, openpassMountingKit -- los cuatro campos de validadora/SUBE/openpass y observaciones quedan fuera del UPDATE, o sea son de facto 'de la app' hoy. 4. RESPUESTA: origen de la tabla ancha NO se puede repurposear para vdc -- vive en otra tabla con semantica de historial por fila (multiples filas por vehiculo), vdc es una fila overlay unica por vehiculo. vdc necesita SU PROPIO mecanismo, y la forma minima ya esta insinuada por el punto 3: una lista explicita y nombrada de columnas 'del libro' (las que el UPDATE ya toca, siempre pisables por import) vs columnas 'de la app' (las que ya deja en paz), en vez de decidirlo por ausencia accidental en un UPDATE escrito para otro fin. Eso NO resuelve el caso donde un usuario necesite corregir una columna 'del libro' -- esa es la decision de diseno que Elazar tiene que tomar, no una que audit resuelva. No ejecutado nada, solo lectura de la migracion instalada. db03: coordinar diseno de la particion antes de implementar.
  • wi-cli-venus assigned · 3w ago
    db03-mba-l-cc
  • wi-cli-venus note · 3w ago
    db03-mba-l-cc, 2026-09-22, re-medido en vivo DEV+PROD (SUPERUSER_POSTGRES_URL): origen CHECK (vh_norm_origen_ck), vh_norm_app_snapshot_ck y los 3 triggers (reject_app_delete, reject_book_column_update, reject_unresolved_catalogs) presentes, enabled, byte-identicos en las dos bases. DEV 4 filas origen='app' vivas / 5528 import; PROD 0/5528 (cero = sin trafico de app aun, no evidencia de que el mecanismo funcione). GAP REAL ENCONTRADO: la nota del 09-05 decia "Gate document written: docs/design/movilba-224-import- prohibition.md" y ese archivo NUNCA se commiteo - cero rastro en git log --all, ningun branch, ningun worktree. Lo escribi y commiteo ahora: dev@4455df50, docs/design/movilba-224-import-prohibition.md. Sigue sin ejercitarse el control positivo (edicion real via UI en DEV que sobreviva un rebuild) - requiere credenciales de app y dev server, accion de Elazar, escalada desde 09-18. No cierro el ticket. Coordinando con audit-mba-l-cc sobre la pregunta de reconciler logic / provenance column del handoff de researcher.
  • wi-cli-venus note · 3w ago
    db03-mba-l-cc, 2026-09-22. Confirmo el hallazgo de audit leyendo el archivo directamente: docs/migrations/2026-09-19-movilba-516-...sql L637-671. El UPDATE de reconciliar_snapshot sobre public.vehiculos_datos_colectivos pisa 20 columnas derivadas del libro (interno, consumo, identificacion_camaras_adas, ip_canbus, ip_mdvr, conexiones_usb, adas_presente_id, cabina_antivandalica_id, camaras_adas_cantidad, camaras_internas, mdvr_id, pantallas_id, wifi_id, regimen_servicio_modalidad_id, estandar_emisiones_id, identidad_id, expte_alta, expte_baja, fecha_vigencia_desde/hasta, estado_id) para cualquier vehiculo que siga en el libro, sin gate de provenance. vdc no tiene columna de origen (grano distinto a rutap.vehiculo_historial_normalizado, que es por fila; vdc es una sola fila overlay por vehiculo, no repurposable). El de-facto split que audit señala (observaciones/creadoEn/creadoPor/borradoEn/borradoPor/sube*/openpass*, nunca tocadas por el reconciler) ya existe pero es implicito-por-omision, no una lista nombrada. NO IMPLEMENTO una lista de columnas book-owned/app-owned sin decision de Elazar (mismo criterio que 224 ya pedia: "la forma la decide el carril de base" pero el ALCANCE -que campos puede tocar un usuario via UI hoy- no es una medicion de base, es producto). Escalado a Elazar por CLI.
  • wi-cli-venus note · 3w ago
    Closed per Elazar CLI 2026-09-22: origen='app' is only a label (user edit = explained delta, nothing to investigate, gets overwritten). Already in place: live rutap.reconciliar_snapshot (MOVILBA-517, md5 cd18795a DEV=PROD) deletes every origen='app' row when applied and asserts 0 remain. No DDL: vh_norm_reject_app_delete stays because the reconciler asserts it exists and disables it by name, so dropping it would abort every import. The prohibition doc was based on a false premise; coder03 is deleting it. Blackboard bb-db03-mba-l-cc-mucunusk-bxlomw item 1 retracted.
  • wi-cli-venus completed · 3w ago
    completed
bug
6w ago by wi-cli-venus
3w ago
2026-09-22 15:51