basquetWi + New ticket
movilba MOVILBA-575

El import matchea las grafias equivalentes de chasis por regla en normalizar_clave_chasis, en vez de un alias curado a mano por grafia

Done normal dmdb03-mba-l-cc

Orden de Elazar, 2026-09-24, literal: "fine, document it and in the future match those toghether, add it to the import process and documentation". El caso que la motiva es K280 В4x2 (GAS) de AI230WN. La documentacion YA ESTA: docs/reference/chasis-equivalencias.md, creada en este mismo turno. Este item es la otra mitad, el import. QUE SE PIDE: que el import matchee solo las grafias equivalentes, en vez de depender de un alias curado a mano en rutap.chasis_resolver por cada grafia nueva. Las cuatro equivalencias aprobadas estan en el doc: homoglifo cirilico a latino, espaciado, GAS/GNC/CNG a un solo token, y el parentesis del sufijo de combustible. DONDE: rutap.normalizar_clave_chasis(text), que hoy hace solo upper + NBSP a espacio + colapso de espacios. NO se toca rutap.chasis_modelo_desde_libro(text), que es override de PRESENTACION de MOVILBA-536 y vive en ssot-overrides.md. NO se tocan las columnas raw_*, rutap.rutap_rows ni public.parque_rutap_*_raw: la fidelidad al libro se mide contra esas. LA TRAMPA, MEDIDA, Y ES LA RAZON DE QUE ESTE ITEM NO SEA TRIVIAL: el texto del modelo NO identifica al chasis. chasis_id 115 es K 280 B4x2 (diésel) y chasis_id 124 es K 280 B4x2 (GNC), misma designacion Scania, dos chasis. El resolver ya tiene la grafia pelada K 280 B 4X2 apuntando a los DOS, separada unicamente por unidad_propulsora_id, 124 contra 157. Agrale repite la forma: 123 MT 17.0 LE GNV, 127 MT 17.0 LE, 129 MT 17.0 LEe. O sea que un normalizador que borre el token de combustible funde el diesel con el gas. La clave es el PAR (modelo normalizado, unidad_propulsora_id), y ausencia de token no es equivalencia sino ambiguedad. PRECONDICION OBLIGATORIA antes de aplicar cualquier DDL: correr la consulta de colision del final del doc y demostrar que ninguna clave nueva junta dos chasis_id con la MISMA unidad_propulsora_id. Con la fusion propuesta, medida en DEV el 2026-09-24, colisionan tres claves - K280B4X2 con {115,124}, MT170LE con {123,127,129} y MT170LE6000 con {123,127} - y las tres se separan por unidad propulsora. Si alguna NO se separara, el cambio se frena y vuelve como decision. SECUENCIA: va DESPUES del import del libro 2026-09-24 (MOVILBA-155). Cambiar la normalizacion de la clave mientras un import corre re-keyea el resolver debajo del proceso en vuelo. NO EJERCITADO: no se escribio ni una linea de DDL, no se corrio nada contra PROD, y no se verifico que los cinco dominios que el libro escribe (GAS) sean fisicamente la variante a gas. La equivalencia establecida es de DESIGNACION; la asignacion de cada vehiculo a 115 o 124 la sigue decidiendo la unidad propulsora de su fila.

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Activity

  • coder03-mba-l-cc created · 3w ago
  • audit-mba-l-ca audited · 3w ago
    audit fail: Pre-implementation reasoning/docs audit; no DDL or book vehicle-to-fuel assignment exercised. Block on reproducible collision gate and corrected reference guidance.
    payload
    {"scope":"Pre-implementation reasoning/docs audit; no DDL or book vehicle-to-fuel assignment exercised. Block on reproducible collision gate and corrected reference guidance.","outcome":"fail","evidence":"Read-only resolver query in DEV and PROD: SCANIA bare 'K 280 B 4X2' maps unit 124 to chasis 115 and unit 157 to 124. Independent prospective key surrogate (Cyrillic translate, strip whitespace/dot/parentheses, GAS/GNC/CNG suffix to GNC) flags model collisions K280B4X2 {115,124}, MT170LE {123,127,129}, MT170LE6000 {123,127}; 0 collisions on (key,unit), clean control K280B4X2GNC/unit157->{124} in BOTH bases. But chasis-equivalencias.md promises a collision query at its end and contains no SQL, so it is not rerunnable. Its assertion that GAS is not a factory designation is contradicted by Scania Argentina's official bus technical-sheet listing (https://www.scania.com/ar/es/home/products/buses-and-coaches.html), which explicitly labels K 280 B4x2 GAS. The rutap-transform-rules.md trim removes dated 09-04 snapshot md5 f7e9ead4ddcefecbc2350b726ae8d825 and WhatsApp evidence path, and at line 257 calls the obsolete 09-04 verbatim expediente equality gate useful despite MOVILBA-248 at line 226 moving that phrase to NULL/observaciones. Correct/reconcile docs and add exact collision SQL before implementation. audit-mba-l-ca, 2026-09-24 ART.","reportRef":null}
  • audit-mba-l-ca audited · 3w ago
    audit fail: Uncommitted docs/SQL re-review. Ran SQL read-only in DEV+PROD, mutation negative control in DEV, PK check, diff check and old/new token comparison. No importer, DDL, lint, typecheck or vehicle assignment exercised.
    payload
    {"scope":"Uncommitted docs/SQL re-review. Ran SQL read-only in DEV+PROD, mutation negative control in DEV, PK check, diff check and old/new token comparison. No importer, DDL, lint, typecheck or vehicle assignment exercised.","outcome":"fail","evidence":"Previous blockers fixed: new SQL gives the three expected model collisions, each max_chasis_por_unidad_propulsora=1 in both bases; deleting fuel token yields AGRALEMT170 {123,143}, max=2 in DEV. GAS source claim corrected; obsolete 09-04 expediente gate retired; missing historical identifiers restored. NEW BLOCKER: chasis-equivalencias.md:7 and rutap-transform-rules.md:121 call (modelo normalizado, unidad_propulsora_id) the complete key. Actual rutap.chasis_resolver PK, independently queried, is (fabricante_normalizado, modelo_normalizado, unidad_propulsora_id); the new SQL includes fabricante at line 23. Docs/BWI would guide an implementation to match across manufacturers. State the triple consistently, or qualify the pair as within a fixed manufacturer. audit-mba-l-ca, 2026-09-24 ART.","reportRef":null}
  • audit-mba-l-ca audited · 3w ago
    audit fail: Round 3: docs/SQL and BWI implementation brief; read-only text/diff checks. Prior DEV+PROD SQL and mutation controls stand. No importer, DDL, lint, typecheck or vehicle assignment exercised.
    payload
    {"scope":"Round 3: docs/SQL and BWI implementation brief; read-only text/diff checks. Prior DEV+PROD SQL and mutation controls stand. No importer, DDL, lint, typecheck or vehicle assignment exercised.","outcome":"fail","evidence":"Docs and SQL now correctly use the resolver PK triple (fabricante, modelo, unidad_propulsora), cite SUPERUSER_ELAZAR_URL, and git diff --check passes. But bwi show MOVILBA-575 --full still says 'La clave es el PAR (modelo normalizado, unidad_propulsora_id)', points to a query at the end of the doc rather than tools/chasis-clave-colision.sql, and says no PROD query ran. This is the implementation contract and could reintroduce cross-manufacturer matching. Correct the ticket description; do not change the docs back.","reportRef":null}
  • coder03-mba-l-cc assigned · 2w ago
    db03-mba-l-cc
  • coder03-mba-l-cc assigned · 2w ago
    db04-mba-l-ca
  • coder03-mba-l-cc assigned · 1w ago
    db03-mba-l-cc / db
  • db03-mba-l-cc note · 1w ago
    db03 2026-10-08: precondition re-measured fresh, PLUS a new blocking design gap found that the precondition itself does not test. Leaving OPEN, no DDL applied - matches the ticket's own "si alguna [colision] NO se separara, el cambio se frena y vuelve como decision", extended to this. PRECONDITION COLLISION QUERY re-run fresh (tools/chasis-clave-colision.sql, not trusting the 09-24 numbers): still passes in both bases (every colliding key separates cleanly by unidad_propulsora_id), but the result SET changed since 09-24 - a 4th key appeared, AGRALEMT17, {123,143} in DEV / {123,135} in PROD (new catalog rows "MT 17" added to each base independently since 09-24, same designation, different ids - a DEV/PROD catalog-id divergence, separate issue, not filing it here). max_chasis_por_unidad_propulsora=1 on all 4 keys in both bases - gate still PASSES. NEW FINDING, not caught by the precondition query or by any of the three prior audit FAILs on this ticket: the collision query's "clave" is NOT what normalizar_clave_chasis would actually produce if I only add translit+GAS/GNC/CNG+paren-removal to the existing collapse-whitespace behavior. Measured directly (drafted the proposed function body in pg_temp, ran it against the motivating example): normalizar_clave_chasis('K280 В4x2 (GAS)') -> 'K280 B4X2 GNC' normalizar_clave_chasis('K 280 B4x2 GNC') -> 'K 280 B4X2 GNC' <- NOT EQUAL to the line above Equivalence #2 in docs/reference/chasis-equivalencias.md ("K280, K 280, K280 B 4X2 y K280 B4X2 son la misma designacion") requires equating DIFFERENT space counts AT DIFFERENT POSITIONS, including zero spaces between a letter-prefix and a digit run ("K280" vs "K 280"). Collapsing-repeated-whitespace-to-one (the current function's only space handling) cannot do that - it only normalizes 2+ spaces down to 1, it never inserts or removes a SINGLE space. So a function that adds only translit+GNC+parens on top of the current body does NOT achieve the ticket's own motivating case: "K280..." and "K 280..." stay two different keys, same bug as today. The precondition query's "clave" achieves it a different way: it strips ALL non-alphanumeric characters (`'[^A-Z0-9]', '', 'g'`), not just whitespace - full strip, not whitespace-collapse. That is a BROADER change than what the ticket's own "DONDE" section describes editing (normalizar_clave_chasis with four additive equivalences on top of its current collapse-only space handling). If the real fix is "strip spaces entirely, like the precondition key does," that has consequences nobody has measured yet: - `rutap.chasis_resolver.fabricante_normalizado`/`modelo_normalizado` are STORED columns (confirmed via \d), populated at curation time with the OLD function's output. Changing the function's output SHAPE (not just adding equivalences on top of the same shape) breaks every existing join (`c.modelo_normalizado = rutap.normalizar_clave_chasis(r.chasis_modelo)`) against every row curated so far, unless those stored columns are ALSO backfilled to the new shape in the same migration - a second DML pass this ticket's SEQUENCE section does not mention. - `rutap.v_rutap_chasis_resuelto` has a hardcoded MOVILBA-578 override comparing `rutap.normalizar_clave_chasis(r.chasis_modelo) = ANY (ARRAY['FU-BMO 368 VERSION 1', 'FU-BMO 368 VERSION 1721 L62 CA'])` and `... = 'MERCEDES BENZ'` - literals that contain spaces. A full-strip normalizer makes these ANY()/= comparisons permanently false (space-stripped output never equals a space-containing literal), silently disabling the AF178SI override with no error - exactly the "defecto 2 del 441" class this same file warns about one section up (a silent mismatch, not a logged one). The ARRAY literals would need rewriting to the stripped form in the same DDL. NOT APPLYING ANY DDL this turn. This is a real, unmeasured scope expansion (function-shape change + resolver-table backfill + a dependent view's literal rewrite, not just the single CREATE OR REPLACE the ticket's "DONDE" section names) on a function that gates ALL chasis resolution, already FAILED three times for under-exercise. Reporting to coder03 for a decision: either (a) scope the ticket up to cover the backfill + 578-override rewrite explicitly and re-dispatch with that wider scope, or (b) accept a narrower fix that achieves #1/#3/#4 (translit, fuel-token unification, paren-strip) but explicitly leaves #2 (space-count equivalence) unresolved, documented as a known gap in chasis-equivalencias.md.
  • coder03-mba-l-cc note · 1w ago
    coder03 12:19 ART: scope decision - ship #1/#3/#4 only; #2 (K280 vs K 280 equivalence) stays documented as a gap because the curated chasis_resolver approved-mapping table already resolves that case by row; no re-shape of normalizar_clave_chasis, no 578 rewrite, no backfill.
  • db03-mba-l-cc note · 1w ago
    db03 2026-10-08: APPLIED in PROD and DEV, PROD first, per coder03's 12:19 decision (ship #1/#3/#4, document #2 as a gap). Pending audit PASS. Migration: docs/migrations/2026-10-08-movilba-575-normalizar-clave-chasis-equivalencias-PROD-Y-DEV.sql (untracked, needs coder03's commit along with the two doc edits below). WHAT SHIPPED: rutap.normalizar_clave_chasis now applies equivalences 1 (cyrillic homoglyph translit), 3 (GAS|GNC|CNG to one GNC token) and 4 (strip the parens wrapping that token) on top of its existing upper + NBSP + whitespace-collapse. md5(prosrc) = 9f125727dba826c7ad229c7c8942fdf4, IDENTICAL in both bases. Owner and ACL unchanged in both (verified in-transaction, aborts otherwise). #2 (spacing) NOT shipped, as decided, and written down in docs/reference/chasis-equivalencias.md with the reason: achieving it generally means stripping all whitespace from the key, which changes the function's output SHAPE and silently falsifies the space-containing literals v_rutap_chasis_resuelto hardcodes for the MOVILBA-578 AF178SI override. The migration carries a control that ABORTS if those three literals change shape, and a negative control that ABORTS if the new normalizer does equate a pure spacing difference - so the gap is enforced, not merely documented. BACKFILL - this is the part the ticket did not anticipate and the precondition query could not see. Measured by running the proposed new body against every stored key in both bases rather than by regex-guessing which rows looked affected (an earlier regex pass with \yGAS\y MISSED one row, because there is no word boundary between '0' and 'G' in 'K280GAS'): 3 resolver rows invalidated, identical set in both bases. - 'K280 B4X2 (GAS)' and 'K280 В4X2 (GAS)' (cyrillic) BOTH land on 'K280 B4X2 GNC', which ALREADY EXISTED as its own curated row - so a 3-way merge, not the 2-way one I first wrote (the first PROD rehearsal caught it: duplicate key on chasis_resolver_pkey). Resolved by unioning dominios_evidencia into the pre-existing survivor and deleting the two old-shape rows. - 'K280GAS' lands on 'K280GNC', which had no row - a plain in-place rename. Postcheck in both bases: SCANIA's six K280 rows are now four (K280 B 4X2, K280 B4X2, K280 B4X2 GNC, K280GNC), all still chasis_id 124 / unidad_propulsora 157 / aprobado; survivor dominios_evidencia = {AG225BW,AI230WL,AI230WM,AI230WN,AI357FL,AI357IV}; and 0 resolver rows disagree with the new normalizer (the migration raises if that count is not 0). Without this backfill the CHECK (modelo_normalizado = normalizar_clave_chasis(modelo_normalizado)) would have been violated on those rows' next touch, and the curated rows would have been unreachable by any new book row written in the new shape - the exact opposite of this ticket's purpose. PRECONDITION re-measured fresh before applying (tools/chasis-clave-colision.sql, both bases): passes, every colliding key still separates by unidad_propulsora_id. The 09-24 result set had 3 keys; today it has 4 - AGRALEMT17 appeared, {123,143} DEV / {123,135} PROD (new 'MT 17' catalog rows added to each base independently since 09-24, same designation, different ids). max_chasis_por_unidad_propulsora = 1 on all 4 in both bases. That DEV/PROD catalog-id divergence is a separate convergence question, not filed here. REHEARSED under ROLLBACK in PROD then DEV before either apply, with both controls seen to run. NOT EXERCISED: no import was run with the new normalizer - what is demonstrated is that the resolver keys agree with the function and that the 578 literals and the spacing gap are both guarded, not that a full book import behaves. The next import is the first thing that exercises it end to end. Docs updated (both untracked, need committing with the .sql): docs/reference/chasis-equivalencias.md (section "Estado actual del codigo" rewritten - shipped equivalences, the #2 gap with its reason and what closing it would cost, and the backfill) and docs/migrations/README.md (index entry under 2026-10-08).
  • db03-mba-l-cc statusChanged · 1w ago
    db03: applied PROD+DEV 2026-10-08, pending audit PASS and commit of the .sql + two doc edits.
  • audit-mba-l-cc audited · 1w ago
    audit pass: 3 paths: migration SQL + chasis-equivalencias.md + the README 575 hunk only. Live function re-measured in BOTH bases; resolver and collision state in DEV. SIN EJERCITAR: chasis_resolver unreadable to my role in PROD so PROD backfill postconditions are db03's measurement; no import run
    payload
    {"scope":"3 paths: migration SQL + chasis-equivalencias.md + the README 575 hunk only. Live function re-measured in BOTH bases; resolver and collision state in DEV. SIN EJERCITAR: chasis_resolver unreadable to my role in PROD so PROD backfill postconditions are db03's measurement; no import run","outcome":"pass","evidence":"md5(prosrc)=9f125727dba826c7ad229c7c8942fdf4 in movilba AND movilba_dev, matching the doc. Live probes: the applied body equates the motivating case and keeps a pure spacing difference distinct, in both bases, so shipped #1/#3/#4 and unshipped #2 are as documented. DEV: 0 resolver rows disagree with the new normalizer; the four no-space K280 SCANIA rows are {K280 B 4X2, K280 B4X2, K280 B4X2 GNC, K280GNC} all chasis_id 124, so six-to-four holds; tools/chasis-clave-colision.sql re-run gives 4 colliding keys, max_chasis_por_unidad_propulsora=1. The three MOVILBA-578 literals normalize to themselves. No live chassis value in either base contains GAS/GNC/CNG other than as a standalone token.","reportRef":null}
  • audit-mba-l-cc audit-finding · 1w ago
    audit 2026-10-08 PASS, with ONE latent defect that should get its own item before the next import, because the next import is the first thing that exercises the new normalizer and a wrong key is silent. THE FUEL-TOKEN REPLACEMENT IS UNANCHORED. The body is regexp_replace(..., '(GAS|GNC|CNG)', 'GNC', 'g') with no word boundary, so it rewrites those three letters ANYWHERE INSIDE A WORD. Measured against the live function in both bases: PEGASO -> PEGNCO, GASOIL -> GNCOIL, BIOGAS -> BIOGNC, 'MEGAS 12' -> 'MEGNC 12', CNGX -> GNCX, and (GASOIL) -> (GNCOIL), where the paren is then NOT stripped because the result no longer matches the paren pattern. PEGASO is a real marque, so this is plausible rather than contrived, and the function is applied to fabricante_normalizado as well as modelo_normalizado. WHY IT IS A PASS AND NOT A FAIL: I measured the whole live population in both bases and nothing is wrong today. Every value containing those letters is a standalone fuel token - public.chasis has one row, 'K 280 B4x2 GNC'; the raw history has six distinct shapes, the four SCANIA K280 ones plus AGRALE '52-MT 17.0 GNC CA 7' and 'MT 17.0 GNC'; public.opciones has no unidad_propulsora value matching at all. The resolver agrees with the normalizer on every stored key in DEV. So nothing needs reverting - the exposure is to a future book row, and the next import is when it lands. FIX, one line: anchor the alternation on word boundaries, '\\m(GAS|GNC|CNG)\\M' in Postgres, then re-measure the stored keys and the 578 literals with the same controls this migration already carries. Every existing positive and negative control would still pass. SECOND, SMALLER: the function is not idempotent for a value that STARTS with the paren form, because btrim runs at the innermost step only while the paren rule emits a LEADING space. Measured: '(GAS)' -> ' GNC' -> 'GNC', and '(GAS) B4X2' -> ' GNC B4X2' -> 'GNC B4X2'. chasis_resolver's CHECK (modelo_normalizado = rutap.normalizar_clave_chasis(modelo_normalizado)) therefore cannot be satisfied by such a key at all, so it fails closed rather than corrupting anything, but it means a book value of that shape can never be curated. Wrapping the whole expression in btrim fixes it and costs nothing. WHAT I DID NOT VERIFY: rutap.chasis_resolver is unreadable to my role in PROD ('permission denied for table chasis_resolver' as svc_nextjs), so the PROD leg of the 3-row backfill, the dominios_evidencia union and the six-to-four count are db03's measurement and not mine; what I did confirm in PROD is the function body hash and its behaviour. Same gap as MOVILBA-648. No import was run in either base, so key agreement is demonstrated and end-to-end import behaviour is not. DOC ACCURACY: both doc hunks match what I measured, including the honest 'pendiente audit PASS' on the README row and the NO EJERCITADO note about nobody having verified that the five (GAS) dominios are physically the gas variant. The README's 709 row is a separate item's hunk and I did not re-verdict it here.
  • db03-mba-l-cc note · 1w ago
    db03-mba-l-cc 2026-10-08 - verified installed, then closed. rutap.normalizar_clave_chasis(p_valor text), md5(prosrc) = 50b6ca6b638568001eab816f67c460ec, IDENTICAL in PROD and DEV. Verified by behaviour, not by reading the migration or trusting the version note: 8 probes, same 8 results in both bases - Cyrillic homoglyph translate (АВЕ -> ABE), GAS->GNC and CNG->GNC with \m\M word boundaries, the digit-letter pass ('MB 1720GAS' -> 'MB 1720GNC'), the negative control that a longer word is NOT touched ('GASOIL 500' stays), '( GNC )' -> ' GNC', NBSP (chr 160) folded to a space, and multiple spaces collapsed. The negative control matters most here: without it, a rule that rewrote GAS anywhere would look just as green. Method note on my own first pass: I probed 0/O digit-letter homoglyphs and a DIESEL token and got no change, which would have read as 'not shipped'. Both were the wrong probes - the implemented homoglyphs are Cyrillic-to-Latin and the implemented fuel token is GAS/GNC/CNG. I read prosrc rather than filing that, which is the only reason this is a close and not a false defect report. SIN EJERCITAR: no measurement of how many existing rows change key under this function, and no check of its callers. Closing on the function's behaviour in both bases, which is what the item asked for.
  • db03-mba-l-cc completed · 1w ago
    completed
task
3w ago by coder03-mba-l-cc
1w ago
2026-10-08 17:32