basquetWi + New ticket
movilba MOVILBA-731

Paridad de cuerpo PROD/DEV: 2 de 117 vistas divergen de verdad (las otras 68 diferencias de texto son idioma de deparser PG15 vs PG17), owner 117/117 y grants 108/117

Done normal dmdb03-mba-l-cc

Hallado por db03 el 2026-10-08 en el censo de MOVILBA-123: de 46 vistas medidas, 6 no tienen paridad de cuerpo entre PROD y DEV (v_admin_opciones_list, v_opciones, las tres v_opciones_*, v_temporadas, ocho v_ui_*, v_snapshot_catalog_preflight - la lista nominal exacta esta en la nota de db03 en MOVILBA-123), y el relacl de DEV es NULL donde PROD lleva grants. Regla: la estructura fluye PROD -> DEV, DEV solo puede diferir en FILAS, asi que cada objeto se resuelve nombrando el lado correcto o se marca UNRESOLVED con la razon; db03 NO sobreescribe ninguno de los dos lados hasta que este censado asi. Un CREATE OR REPLACE con cuerpo mas angosto le saca columnas a los lectores de PROD, y un DROP VIEW descarta los grants de PROD. Reportar como censo medido por nombre y diffeado en AMBAS direcciones, no como 'ya coinciden'. Relacionado: MOVILBA-585, MOVILBA-479.

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Activity

  • coder03-mba-l-cc created · 1w ago
  • coder03-mba-l-cc note · 1w ago
    coder03-mba-l-cc 2026-10-08 17:26Z / 14:26 ART - medicion de db03 del 2026-10-08 que cae exactamente en este item: DEV tiene relacl NULL en 11 de las 12 vistas del sufijo, PROD en ninguna. Divergencia de grants, y el lado correcto es PROD - la estructura fluye PROD->DEV y la unica divergencia legitima de DEV son FILAS, nunca objetos ni permisos. Cuidado al arreglarlo, porque es la trampa que ya documentamos: un CREATE OR REPLACE con cuerpo mas angosto le saca columnas a los lectores de PROD, y un DROP VIEW en PROD descarta su relacl, que NO es NULL. El arreglo va en DEV, otorgando los grants que PROD ya tiene; no se toca PROD para igualar.
  • db04-mba-l-ca progress · 1w ago
    db04 2026-10-08 SELECT-only PROD->DEV: fn_archive_vehiculos_datos_colectivos prosrc md5 PROD 2aa26e90a064d6971913281f4bbbc0ea, DEV f3b889a74b800772b04aae642d51e828. Only body delta: PROD archives OLD.observaciones, DEV omits it. This is not an arbitrary missing hunk: MOVILBA-472 deliberately dropped VDC.observaciones in DEV and revised its function; PROD retains the populated physical column (537: 1545 rows), archive column survives both. Correct side for current installed schema: each function is locally correct; unified target UNRESOLVED pending Elazar's MOVILBA-537 PROD data-destructive DROP choice. Do not copy PROD body to DEV (OLD column absent) or DEV body to PROD (would stop archiving populated field). A future 537 migration must converge source column and function together. Evidence /data-lezama/movilba/evidencia/MOVILBA-731/2026-10-08-vdc-archive-trigger-divergence.md; no DDL or data write.
  • db04-mba-l-ca note · 1w ago
    Citation/state correction to db04's earlier progress note: DEV's function-body exception is established by the APPLIED migration docs/migrations/2026-09-18-movilba-472-drop-vdc-observaciones-DEV.sql, not by canceled BWI MOVILBA-472 (folded into 537). MOVILBA-537 is now explicitly BLOCKED on Elazar's word for a populated PROD VDC.observaciones DROP; 731's unified archive-trigger target remains UNRESOLVED until the source column and function can be converged together. Evidence file updated in place: /data-lezama/movilba/evidencia/MOVILBA-731/2026-10-08-vdc-archive-trigger-divergence.md. No DB action.
  • db03-mba-l-cc statusChanged · 1w ago
  • db03-mba-l-cc titleChanged · 1w ago
    Paridad de cuerpo PROD/DEV: 2 de 117 vistas divergen de verdad (las otras 68 diferencias de texto son idioma de deparser PG15 vs PG17), owner 117/117 y grants 108/117
  • db03-mba-l-cc note · 1w ago
    db03-mba-l-cc, host date -u 2026-10-08T21:22:52Z. CENSUS DONE, SELECT-only. The only non-SELECT statements were CREATE TEMP VIEW inside transactions that ended in ROLLBACK. Nothing was written to either base: no CREATE OR REPLACE, no DROP VIEW, no GRANT. DELIVERABLE: docs/reference/movilba-731-censo-paridad-vistas.md, sha256 300d9121fdf570408fca221e08d4b32e5041a211847cfd8c5a67f3515cf03734, UNTRACKED. THIS ITEM'S OWN TITLE WAS WRONG AND I RETITLED IT. It said 6 of 46 views differ. Measured over ALL views of both bases, not the 46 of the MOVILBA-123 census: of 117 shared views the raw text of pg_get_viewdef differs in 70, and only 2 of those are real divergences. The other 68 are a deparser idiom - PROD runs PG 17.6, DEV runs PG 15.17, and the two print the SAME stored tree differently. 67 of them are relation qualification (PG17 prints 'SELECT id' where PG15 prints 'SELECT o.id' for a single-table query) and 1 is the implicit alias of a cast constant. So md5(pg_get_viewdef()) across bases of different major versions is NOT a parity comparator, and every count made that way - MY OWN in MOVILBA-123 above all - counts formatting as drift. Correction also filed on 123. INSTRUMENT. Two independent comparators, same answer. A: collapse whitespace and strip alias qualifiers on both sides, with a positive control (mutate a WHERE literal in a qualification-only view and it still reports differing) and a negative control (the 47 views already equal raw stay equal). B, the one that decides: create PROD's body as a TEMP VIEW inside DEV and diff what DEV re-prints against DEV's own stored body, so both sides pass through one deparser. B needs search_path pinned identically in both renders - my first run of B reported 12 phantom rutap differences that vanished under SET LOCAL search_path = rutap, public, because pg_get_viewdef qualifies by the search_path at READ time. Direction rule, stated because the doc uses it both ways: EQUAL in one direction is conclusive, DIFFERS in one direction is not, because an alias written explicitly in the input text survives the render and reads as drift. THE 2 REAL ONES. 1. public.v_vehiculos_export_vdc - PROD projects observaciones, DEV does not, 32 vs 31 columns, the only view with a different column list. B cannot even create PROD's body in DEV: column vdc.observaciones does not exist. Correct side by the structure rule would be PROD, but marked UNRESOLVED and NOT converged, because MOVILBA-537 asks for that column to be DROPPED in PROD and is blocked on Elazar over 1545 populated values. The view and the column converge together, in whichever direction 537 decides. 2. rutap.v_rutap_latest_norm - DEV is the correct side, by a cited decision. Four columns differ on the same '0' -> NULL branch: id_adas_norm, id_mdvr_norm, id_canbus_norm have an extra btrim(...) = '0' OR branch in PROD, and motor_nro_norm is wrapped in NULLIF(..., '0') in PROD and bare in DEV. docs/migrations/2026-09-03-movilba-191-rutap-latest-norm-literal-zero-DEV.sql, header literal: 'Elazar decision 2026-09-03: literal source 0 is data. It must not become NULL in a derived comparison view.' I checked that 191 is the LAST word on this view rather than citing the first decision I found, which is the mistake I had just corrected on 749: of the twelve migration files naming motor_nro_norm only two replace the view, the 2026-08-14 one and 191, and no verdict on it exists in pending-prod-changes.md or in the 479 census. PROD'S OWN IMPORTER ALREADY AGREES WITH DEV, which is what settles the direction. 492, 535 and 536, all three DEV-Y-PROD, carry the expression without NULLIF inside rutap.proyectar_snapshot. Measured against the INSTALLED function in PROD, not the file: its prosrc matches regexp_replace(btrim(r.motor_nro 1 time and nullif(regexp_replace(btrim(r.motor_nro 0 times. So PROD has two resolvers of the same field and only the view is stale. NOT LATENT, counted on the source and not derived. At the tip snapshot of each base - PROD 11, DEV 21, same book, 5558 rows - cells whose btrim equals '0': id_canbus 5308, id_adas 2974, id_mdvr 1128, motor_nro 18, identical in both bases. Those values read as NULL through PROD's view and as '0' through DEV's. Unlike MOVILBA-282 this one has population today. What I do NOT claim: that 191 being DEV-only violated PROD FIRST - that rule is Elazar's of 2026-09-18 and on 2026-09-03 the standing instruction was the opposite one, so the DEV-only file was right for its date and what is pending is carrying it to PROD under today's rule. CLOSED AS NOT A DIVERGENCE: rutap.v_snapshot_catalog_preflight. Ten UNION branches print 'x'::text AS text in PROD and 'x'::text in DEV. Closed with a TWO-DIRECTION test, because one direction is not enough here: DEV's body re-rendered INSIDE PROD equals PROD's whole stored body, True, and the repo text at 2026-09-18-movilba-494b-vista-preflight-DEV-Y-PROD.sql:176 writes 'linea'::text with no alias, matching DEV. An earlier control of mine, on a fabricated UNION, printed the alias in BOTH versions and made me drop the version hypothesis too early - the idiom depends on the shape, so a control on another shape refutes nothing. TWO OBJECTS ONLY IN DEV, 0 only in PROD: agents.v_vehiculo_lookup and agents.v_rutap_historial_carroceria_normalizacion_invariante. The whole agents schema is absent from PROD. DEV may differ in ROWS, never in objects, so this is drift with its own owner - UNRESOLVED, wants its own item under MOVILBA-585, and I propose neither creating the schema in PROD nor dropping it in DEV without knowing who reads it. OWNER AND GRANTS ARE THE BIGGEST DIVERGENCE AND THEY ARE NOT CONVERGEABLE. relowner differs in 117 of 117 - PROD has movilba_owner 84 and postgres 33, DEV has movilba_user 117. relacl differs in 108 of 117: NULL in 105 of DEV's 117 and in only 9 of PROD's. Two units, not to be mixed: 630 is the count of aclitem ENTRIES, while the per-grantee breakdown is in PRIVILEGES via aclexplode and sums to 1981 - movilba_owner 603 over 78 views, nossesmacchia 388/49, postgres 264/33, svc_nextjs 252/108, 20366097083 128/16, audit_ro 100/100, and 49 each for movilba_readonlyusergroup, penql, 20049796634, 27372742122 and 27308864826, plus 1 SELECT to PUBLIC on public.v_ui_todas_entidades and nowhere else. Correct side is PROD, and the operational consequence stands: a DROP VIEW in PROD discards those grants and the migration has to re-GRANT them explicitly. But the DEV leg is IMPOSSIBLE with the permissions that exist, measured and not assumed: in DEV current_user is movilba_user with rolsuper f, rolcreaterole f, rolcreatedb f, and of PROD's 11 named grantees 10 do not exist as a role in DEV - only postgres does - against a pg_roles listing 70 roles of a shared GCABA cluster. Creating them needs CREATEROLE, which DEV does not have, so 'align DEV to PROD's role model' is not an option I can offer: it lands on GCABA IT, which the project rule forbids. Same for relowner, since movilba_owner is PROD's design under MOVILBA-497. So owner 117/117 and grants 108/117 are a divergence FORCED BY THE ENVIRONMENT, not actionable drift, and the only thing missing is writing it as an override. ONE QUESTION FOR ELAZAR, and it does not block the rest: is DEV's owner/grant model written up as an accepted override - everything under movilba_user with no explicit grants - or does it stay an open MOVILBA-585 finding? View BODY parity does not depend on it: 115 of 117 are equal today. NOT EXERCISED: views only, so this is not an answer to MOVILBA-585's schema parity - tables, columns, functions, triggers, constraints, indexes, sequences and types are all out. pg_roles was measured in DEV and NOT in PROD, so '10 of 11 missing' is measured against DEV's list and nobody checked whether a PROD grantee is a group with members. No column-level ACLs (pg_attribute.attacl) and no default privileges (pg_default_acl), both of which a DROP+CREATE also touches. No reloptions (security_barrier, check_option) and no COMMENTs. No live HTTP request. The §3.2 figures come from rutap.rutap_rows, the SOURCE - I did not read both views and diff their output rows, and I did not measure how many of those rows reach a screen or an export. No ROLLBACK rehearsal of the CREATE OR REPLACE that §3.2 would need; that comes before proposing it.
  • db03-mba-l-cc note · 1w ago
    ADDENDUM measured on MOVILBA-756, 2026-10-08T21:30Z, narrowing my own §3.2 wording above - the divergence is real and its reach is smaller than my note implied. My §3.2 said the literal 0 cells 'read as NULL through PROD's view and as 0 through DEV's'. True of rutap.v_rutap_latest_norm itself, and I had listed as NOT exercised whether any surface shows it. Measured now: the published export emits the literal '0' in BOTH bases. public.v_vehiculos_export has id_canbus = '0' in 2262 of 2424 rows in PROD and 2288 of 2469 in DEV, id_adas 963 / 967, id_mdvr 216 / 216, and id_canbus IS NULL in 0 PROD rows. So the NULLIF('0') that only PROD carries does not reach the export surface, which matches 191's own header calling that view a derived COMPARISON view. What this changes: the direction verdict does NOT change - DEV is still the correct side and PROD's view is still the stale resolver, with PROD's installed proyectar_snapshot already agreeing with DEV. What changes is the severity: this is a divergence in the comparison layer, not a user-visible difference on the export, so it is not an urgent prod fix. There is no base TABLE holding these four fields outside rutap.rutap_rows - they reach consumers only through views - so the remaining exposure is whatever else reads v_rutap_latest_norm (reconciliation, chassis resolution, projection eligibility), which I did NOT walk. And the source question that 756 settles: the book itself carries those zeros, four columns matching the base digit for digit, so nothing here is an import defect.
  • db03-mba-l-cc completed · 1w ago
task
1w ago by coder03-mba-l-cc
1w ago
2026-10-08 21:40