PROD: 122 objetos de esquema pertenecen al rol personal 'elazar' - pasarlos a un rol de servicio, y PROD no tiene el 'movilba_user' que DEV usa
ORDEN DE ELAZAR, CLI 2026-09-18, verbatim: 'elazar is my first name, not best practices to have that as the owner, dont change it now, or whatever is faster, i dont care, if you dont change it now create bwi'. Se elige NO cambiarlo ahora y dejarlo fichado: cambiar el owner de 122 objetos en PROD no es una linea, y hacerlo apurado en el medio de otro trabajo es como se rompen los grants. QUE HAY, MEDIDO EN PROD 2026-09-18 (db02, SELECT-only): - esquema public: 86 relaciones y 12 funciones de 'elazar'; 78 relaciones y 11 funciones de 'postgres'. - esquema rutap: 14 relaciones y 10 funciones, TODAS de 'elazar'. Total a mover: 122 objetos. Y ademas el esquema public esta partido entre dos owners, que es un problema distinto y anterior: no hay UN owner de aplicacion, hay dos, y uno es una persona. POR QUE ES UN PROBLEMA Y NO SOLO FEO. (1) Un rol personal es nominativo: cuando la persona se va, o se le rota la credencial, o se le quita un privilegio, 122 objetos quedan colgando de una identidad que ya no deberia existir. (2) Los agentes escriben con esa misma cuenta, asi que la firma de una fila no dice quien la hizo - ya fichado aparte. (3) DEV y PROD divergen: DEV usa 'movilba_user' y PROD NI SIQUIERA TIENE ese rol (pg_roles no lo lista), lo que convierte a cualquier migracion que nombre un owner literal en un fork por entorno. Eso ya paso hoy: la primera version de la migracion de MOVILBA-494 aborto en PROD con 'role "movilba_user" does not exist'. Se arreglo derivando el owner de los objetos del esquema en vez de escribirlo, que es el patron correcto y queda como precedente - pero el patron tapa el sintoma, no la causa. LO QUE HAY QUE DECIDIR ANTES DE TOCAR NADA, y no lo decide el carril db solo: cual es el rol de servicio destino. Candidatos que YA existen en PROD: movilba_app_user, svc_nextjs, svc_api, next_app. No se crea uno nuevo sin saber cual de esos es el que la aplicacion usa de verdad, y no se elige por el nombre - se mide contra las conexiones reales y contra lo que el deploy configura. Crear 'movilba_user' en PROD solo para que coincida con DEV seria un rol vacio inventado para satisfacer un literal de un archivo: descartado explicitamente. RIESGO A MEDIR ANTES: ALTER ... OWNER TO cambia quien puede hacer DDL y puede alterar el efecto de los GRANT existentes y de las policies; hay que censar relacl objeto por objeto ANTES y DESPUES y comparar, no confiar en que 'solo cambia el owner'. Tambien decidir que pasa con los 78+11 objetos de 'postgres' en public: mezclarlos en el mismo movimiento o dejarlos, pero dicho, no por olvido. NO BLOQUEA nada de lo que esta en curso. Es deuda de infraestructura con fecha.
Activity
-
coder03-mba-l-cc
-
Elazar ruling (CLI 2026-09-19, reply '6a'): reassign the 122 PROD objects owned by the personal role 'elazar' to a service role; db03 writes the migration. Boundary: writing and rehearsing it is covered by this ruling, but the APPLY is PROD DDL and still needs its own explicit GO - the 2026-09-19 no-GO amendment covers DATA replayed from a verified DEV fix, not DDL.
-
Elazar GO in CLI 2026-09-19. Relayed to db03-mba-l-cc to execute on PROD, exact md5 1e70029a494564584d5a4e31b02ab599. MOVILBA-495 PROD stays queued behind it; db02 re-rehearses on the post-497 state.
-
APLICADO EN PROD 2026-09-19 por db02-mba-l-cc, con GO de Elazar relevado por coder03-mba-l-cc. Lock de hub movilba-497-owner tomado antes y liberado despues. md5 REALMENTE CORRIDO: 1e70029a494564584d5a4e31b02ab599 (copia fresca del blob committeado 7cba2797, hasheada antes y despues, nunca desde el checkout compartido). Mismos bytes que el ensayo. exit 0, COMMIT. POST identicos al ensayo: (a) unico residuo pg_default_acl 1, nombrado ("default privileges on new relations belonging to role elazar in schema public"); (b) postgres sin cambio 256/11/154/1; (c) censo de ACL identico origen->destino, 1733 entradas / 177 objetos; (c2) default ACL igual, 2 entradas en el origen; (d) 0 violaciones sobre 88 vistas/matviews movidas y 34 dependencias no movidas; (e) CONTROL POSITIVO VISTO FALLAR Y RECUPERARSE tambien en la corrida real (public.accounts); (g) 302 pares rol-relacion, 186 con SELECT, antes = despues. CENSO DE PROPIEDAD POST-COMMIT, medido aparte del archivo: elazar posee 0 objetos. movilba_owner (rolcanlogin=f, rolsuper=f, rolcreaterole=f) posee VIEW 75, TABLE 63, FUNCTION 24, SEQUENCE 16, MATVIEW 13, SCHEMA 2. postgres sin cambio en 117 relaciones. DIFERENCIA ENTRE EL ALCANCE APROBADO Y EL MEDIDO, explicada y NO plegada al 177: el GO nombro 177 objetos y se movieron 193. Los 16 de diferencia son SECUENCIAS ARRASTRADAS por el ALTER de su tabla, no un ALTER extra - 177 alterados explicitamente + 16 arrastradas. Medido: ALTER TABLE ... OWNER TO arrastra tanto las secuencias serial (deptype a) como las de IDENTITY (deptype i), en pg_class.relowner y en pg_shdepend. LECTURAS POST-COMMIT: svc_nextjs por CONEXION REAL lee public.v_monitor_historial_anomalias (813 filas) y public.v_vehiculos_export (2413) - la app sigue leyendo. audit_ro y movilba_owner por SET ROLE (no hay login propio para ellos): monitor 813 los dos. NO ES REGRESION: svc_nextjs y audit_ro siguen sin poder leer DIRECTO rutap.v_vehiculo_historial_normalizado_fuente_actual, cuyo relacl sigue en NULL exactamente como antes del cambio; esos roles llegan solo por owner-chaining y el 813 ES esa cadena funcionando. has_table_privilege: monitor t/t/t, fuente_actual f/f/t para svc_nextjs/audit_ro/movilba_owner. ACL del monitor tras el movimiento: {svc_nextjs=r/movilba_owner, movilba_owner=arwdDxtm/movilba_owner, audit_ro=r/movilba_owner} - mismos grants, grantor reescrito al nuevo dueno. GAPS ABIERTOS, NO CERRADOS: (1) las ramas EXECUTE y USAGE del chequeo de cadena NUNCA SE VIERON FALLAR - (e) solo ejercito la rama tabla/SELECT. (2) el cuerpo de fn_refresh_catalog_matviews no lo verifica ningun gate y NO SE LLAMO. Diferencia DEV/PROD DECLARADA, no deriva: DEV conserva movilba_user como dueno porque es un cluster GCABA compartido donde no podemos CREATE ROLE (movilba_user: rolsuper=f, rolcreaterole=f, 0 membresias; los unicos superusers son datco y postgres). DDL futuro en PROD va con SET ROLE movilba_owner.
-
Aplicado en PROD 2026-09-19 (md5 1e70029a494564584d5a4e31b02ab599, commit 7cba2797, GO de Elazar via coder03). elazar pasa a poseer 0 objetos; movilba_owner queda con 193: 177 alterados explicitamente (75 vistas, 63 tablas, 24 funciones, 13 matviews, 2 schemas, bkp incluido) + 16 SECUENCIAS ARRASTRADAS por el ALTER de su tabla - la diferencia entre el 177 del GO y el 193 real esta explicada, no plegada. Detalle, censo y lecturas post-commit en el evento verified. GAPS ABIERTOS que NO cierra este ticket: las ramas EXECUTE y USAGE del chequeo de cadena nunca se vieron fallar (solo se ejercito la rama tabla/SELECT), y el cuerpo de fn_refresh_catalog_matviews no lo verifica ningun gate y no se llamo.
-
ACLARACION DE DENOMINADORES pedida por audit-mba-l-ca: el evento verified dice "POST (b) ok: objetos de postgres sin cambio (relaciones 256 ...)" y mas abajo "postgres sin cambio en 117 relaciones". Los dos numeros son correctos y cuentan cosas distintas. Medido en PROD post-apply: - 256 = el conteo de POST (b), que es pg_class ENTERO para el rol postgres sobre los esquemas no-sistema, INCLUYENDO indices. Desglose por relkind: r 43 + v 34 + S 40 + i 139 = 256. - 117 = mi censo propio, restringido a las clases de negocio r/v/m/S en public+rutap+bkp y por lo tanto SIN los 139 indices: 43 + 34 + 40 + 0 = 117. O sea la unica diferencia es que 256 incluye indices y 117 no. Ninguno de los dos cambio con el apply, que es lo que ambos afirmaban. Nota al margen, medida en el mismo chequeo y util para cualquier gate futuro sobre pg_shdepend: el rol postgres tiene CERO filas en pg_shdepend (es un rol pinned, y pg_shdepend no registra propiedad para esos). Un gate que mida "que posee postgres" via pg_shdepend da 0 y parece que no posee nada; para postgres hay que contar pg_class directo. Esto NO afecta a POST (a), que mide el rol ORIGEN (elazar, no pinned) y por eso si aparece ahi.
-
Limitacion medida por db03-mba-l-cc el 2026-09-23 aplicando el artefacto de MOVILBA-145b en PROD, y vale para TODO reemplazo futuro de una vista de public: movilba_owner tiene USAGE pero NO CREATE sobre el schema public, y CREATE OR REPLACE VIEW exige CREATE sobre el schema incluso cuando la vista YA EXISTE. O sea el diseno 'DDL futuro con SET ROLE movilba_owner' no alcanza para reemplazar una vista de public: hubo que correrlo con el superuser. El REPLACE conservo owner movilba_owner. NO se otorgo nada - esto queda anotado como restriccion conocida, no como un arreglo. Si alguna vez se decide que movilba_owner haga sus propios reemplazos de vista, la decision es un GRANT CREATE ON SCHEMA public, y esa es una decision de Elazar, no un tramite.
-
db03 2026-10-08 ART: the owner design surfaced as a real blocker, not a hypothesis. The MOVILBA-282 apply failed with 'permission denied for schema rutap' at the CREATE OR REPLACE when run with PROD_DATABASE_URL, which is svc_nextjs: it has no CREATE on schema rutap and is not a member of movilba_owner, the owner of rutap.proyectar_snapshot. The preflight had already passed, so the failure was privilege, not bytes. It took SUPERUSER_ELAZAR_URL plus PGOPTIONS='-c role=movilba_owner' to apply. Consequence for this item: every PROD DDL on a rutap object owned by movilba_owner needs a superuser connection with SET ROLE today, so the lane cannot apply PROD DDL with the credentials the project documents first, and a migration file that documents only 'psql $URL -f' is incomplete for PROD. DEV is unaffected: there the function belongs to movilba_user, which is the DEV_DATABASE_URL role. No grant was requested and no credential was rotated.