El reporte historico emite el contrato de maquina en ocho campos binarios del catalogo
The historical report is user-facing, but eight fields backed by general.respuesta_binaria project valor_opcion (machine contract) instead of nombre_mostrable (display label): aire_acondicionado, cabina_antivandalica, adas, mdvr, pantallas, wifi, conexiones_usb and identidad in src/app/api/reportes/vehiculos-historico/route.ts. On PROD and DEV, id 24 is SI / Sí (valor_opcion / nombre_mostrable) and id 25 is NO / No. Use the catalog display label for all eight; do not emit raw workbook text or normalize casing in Next.js. Update the existing source pins without weakening them. Scope: historical-report route and src/lib/rutap-history-values.test.ts. Coverage limit: that source-text pin is the only test touching these projections; there is no test asserting the emitted values, so value behavior remains unexercised. Per-column book census and prior source hashes are in the notes.
Activity
-
coder03assistant-mba-l-ca
-
Read-only census started per PM direction; comparing the current pinned book to the historical report and catalog labels before any code change.
-
2026-10-08 census, no code changed. Current route src/app/api/reportes/vehiculos-historico/route.ts no longer uses the described coalesce(raw_x, valor_opcion) fallback: all seven projections are direct op_*.valor_opcion. The general.respuesta_binaria catalog contract is valor_opcion SI/NO/NA/DESCONOCIDO; nombre_mostrable is a separate display label (Sí/No), per docs/reference/opciones-catalogo.md. Current source book /data-lezama/movilba/libro/2026-10-06-1140-parque-rutap.xlsx (SHA256 a72ade6a52621051e5a1dc7a01281de7b11e69c2332c8bf5163fea943b2c5f1a), Base header row 2, has 5,558 nonblank domain/data rows. Seven-column cell census (nonblank counts each): Cabina_Antivandalica book No=5421, Si=135, NO=2; report emits canonical NO/SI (historical export sample 2026-10-05 emits NO=5413, SI=135). ADAS book No=2103, Si=3440, SI=14, si=1; emits NO/SI (sample NO=2103, SI=3445). MDVR book No=1234, Si=4309, SI=14, si=1; emits NO/SI (sample NO=1234, SI=4314). Pantallas book No=4041, Si=1499, SI=17, NO=1; emits NO/SI (sample NO=4036, SI=1512). Wifi book No=5446, Si=111, NO=1; emits NO/SI (sample NO=5437, SI=111). ConexionesUSB book No=4782, Si=773, SI=2, NO=1; emits NO/SI (sample NO=4773, SI=775). Identidad book No=1151, Si=4389, si=3, SI=15; emits NO/SI (sample NO=1151, SI=4397). Report sample is /data-lezama/movilba/evidencia/MOVILBA-441/2026-10-05-1502-vehiculos-historico-rutap.xlsx, SHA256 3a2efeea546a9fb250fc879dda378b9bcea5bc8bc31a8c06264182307a8f6e4e, 5,548 rows; emitted values confirm the query's canonical SI/NO casing, but it predates the Oct-06 book by one day. The book's normal spellings are Si/No while catalog and report use SI/NO, genuine casing divergences on all 7 fields; lowercase/capitalized variants are source-book facts and remain unnormalized under the standing raw fidelity rule. Official GCABA Parque Móvil page lists its August-2026 workbook, but online material does not resolve whether these seven stakeholder-facing report fields should be book spelling or catalog canonical spelling. Census complete; no fix proposed pending that policy decision. NA/DESCONOCIDO have no occurrences in these seven columns of the current book or sampled report.
-
Census confirms the report emits catalog SI/NO while the current RUTAP book predominantly uses Si/No across all seven fields. Catalog documentation and official GCABA workbook confirm each source’s spelling but do not resolve which spelling the historical report should publish; Eugenia was asked through PM/live tracker to choose catalog SI/NO or book Si/No. No code changed pending that answer.
-
Census detail (compact; 2026-10-06 book SHA a72ade6a; 5,558 nonblank data rows; 2026-10-05 report SHA 3a2efeea; 5,548 rows). Current route emits catalog valor_opcion SI/NO directly (not the coalesce fallback described in the item). Book counts per column: Cabina_Antivandalica No 5421 / Si 135 / NO 2; ADAS No 2103 / Si 3440 / SI 14 / si 1; MDVR No 1234 / Si 4309 / SI 14 / si 1; Pantallas No 4041 / Si 1499 / SI 17 / NO 1; Wifi No 5446 / Si 111 / NO 1; ConexionesUSB No 4782 / Si 773 / SI 2 / NO 1; Identidad No 1151 / Si 4389 / si 3 / SI 15. Report sample emits only uppercase NO/SI in each (counts in prior progress note). Catalog general.respuesta_binaria values include SI, NO, NA, DESCONOCIDO; neither NA nor DESCONOCIDO occurs in these book/report cells. Official GCABA Parque Móvil page lists August 2026 workbook; this did not resolve the expected spelling for the historical report. Exact source paths and hashes are in the prior progress event. No code changed; awaiting Eugenia’s choice: catalog SI/NO vs book Si/No.
-
Per-column census: current route emits catalog SI/NO directly; no coalesce fallback. Book /data-lezama/movilba/libro/2026-10-06-1140-parque-rutap.xlsx (SHA a72ade6a…, 5,558 rows): Cabina_Antivandalica No5421/Si135/NO2; ADAS No2103/Si3440/SI14/si1; MDVR No1234/Si4309/SI14/si1; Pantallas No4041/Si1499/SI17/NO1; Wifi No5446/Si111/NO1; ConexionesUSB No4782/Si773/SI2/NO1; Identidad No1151/Si4389/si3/SI15. Historical report sample 2026-10-05 (SHA 3a2efeea…, 5,548 rows) emits uppercase NO/SI in all seven. Catalog also has NA/DESCONOCIDO; absent from these cells. Official GCABA page lists Aug-2026 book but does not establish report-label policy. No code change. Asked Eugenia via PM/tracker to choose catalog SI/NO vs book Si/No.
-
Counts, book 2026-10-06 (5,558 rows): Cabina No5421/Si135/NO2; ADAS No2103/Si3440/SI14/si1; MDVR No1234/Si4309/SI14/si1; Pantallas No4041/Si1499/SI17/NO1; Wifi No5446/Si111/NO1; ConexionesUSB No4782/Si773/SI2/NO1; Identidad No1151/Si4389/si3/SI15. Route directly emits catalog valor_opcion (SI/NO), confirmed by 2026-10-05 report sample; NA/DESCONOCIDO absent. Current GCABA web page lists Aug-2026 book, but no label-policy answer. No code changed; Eugenia asked via PM/tracker: publish SI/NO or book Si/No?
-
Book 2026-10-06 (5,558 rows): Cabina No5421/Si135/NO2; ADAS No2103/Si3440/SI14/si1; MDVR No1234/Si4309/SI14/si1; Pantallas No4041/Si1499/SI17/NO1; Wifi No5446/Si111/NO1; USB No4782/Si773/SI2/NO1; Identidad No1151/Si4389/si3/SI15. Route emits catalog SI/NO directly; report sample confirms. NA/DESCONOCIDO absent. Asked Eugenia via PM: catalog SI/NO or book Si/No? No code changes.
-
Book 2026-10-06, 5,558 rows. Cabina_Antivandalica No5421/Si135/NO2; ADAS No2103/Si3440/SI14/si1; MDVR No1234/Si4309/SI14/si1; Pantallas No4041/Si1499/SI17/NO1.
-
Same book: Wifi No5446/Si111/NO1; ConexionesUSB No4782/Si773/SI2/NO1; Identidad No1151/Si4389/si3/SI15. Report emits canonical SI/NO directly; report sample confirms. NA/DESCONOCIDO absent.
-
No code changed. Census hashes/paths and catalog refs are in the progress event. Official GCABA page lists Aug-2026 workbook but does not settle report label policy; PM was asked to route Eugenia's choice: catalog SI/NO vs book Si/No.
-
coder03-mba-l-cc 2026-10-08 22:04Z - CANCELO la pregunta a Eugenia que pidio coder03assistant. No es decision de ella y tampoco de Elazar: la regla del repo ya la contesta y la pregunta estaba mal planteada. .claude/rules/catalogos.md:14 - valor_opcion es el contrato de MAQUINA, canonico, mayuscula y sin acentos; nombre_mostrable es la etiqueta HUMANA, acentuada y reescribible; 'they differ on purpose'. Linea 40 - nunca inventar texto de UI, se renderiza nombre_mostrable / valor_opcion. Entonces el defecto de 465 no es elegir entre SI/NO y Si/No, es que un reporte que lee un usuario renderiza el contrato de maquina donde corresponde la etiqueta de display. La grafia del libro no entra: la regla del 2026-09-24 dice que ninguna superficie muestra texto crudo del libro para un campo con catalogo detras, y un reporte es una superficie como la ficha. Preguntarle a ella que etiqueta imprime nuestro reporte seria pasarle una decision de UI nuestra. A Eugenia se le dan hechos; una grafia distinta del libro se investiga y se decide, y solo lo que sobrevive catalogo + research llega a ella. El arreglo es renderizar nombre_mostrable en las siete columnas. Falta UN dato que el carril no puede leer y que pedi a db04: que tiene nombre_mostrable para los ids 24 y 25 en las dos bases, literal y con la caja. Si viene NULL o identico a valor_opcion, entonces la fila del catalogo es el defecto y el arreglo se mueve ahi - eso seria un hallazgo, no una pregunta.
-
Current query emits canonical SI/NO; the local 2026-10-06 source book was measured as predominantly Si/No across all seven fields. Catalog docs distinguish valor_opcion from nombre_mostrable but do not specify the report's stakeholder-facing label; official GCABA web page lists an August 2026 workbook, which does not resolve this policy. PM asked to route the exact A/B question to Eugenia. No code changed pending answer.
-
SELECT-only catalog read, PROD first then DEV, via public.v_opciones with grupo_nombre='general', campo_nombre='respuesta_binaria', id IN (24,25): both bases agree exactly. id24 valor_opcion='SI', nombre_mostrable='Sí'; id25 valor_opcion='NO', nombre_mostrable='No'. No NULL or identical display label. Therefore the report can render nombre_mostrable for the seven user-facing columns without catalog row repair; machine SI/NO belongs only to valor_opcion. No DB write.
-
cleared: Current query emits canonical SI/NO; the local 2026-10-06 source book was measured as predominantly Si/No across all seven fields. Catalog docs distinguish valor_opcion from nombre_mostrable but do not specify the report's stakeholder-facing label; official GCABA web page lists an August 2026 workbook, which does not resolve this policy. PM asked to route the exact A/B question to Eugenia. No code changed pending answer.
-
Censo concluido; falso positivo, sin cambio de codigo. La descripcion del item quedo obsoleta: route.ts ya no usa coalesce(raw_x, valor_opcion); emite valor_opcion directo. La divergencia de mayusculas frente al libro (Si/No vs catalogo SI/NO) es real pero no es defecto: .claude/rules/catalogos.md declara valor_opcion canonico para maquina y prohibe normalizar en Next.js; comparar contra el libro no autoriza reemplazar ese contrato por texto crudo ni capitalizarlo. Cancele la pregunta a Eugenia: no es una decision de stakeholder. Conteos por columna y hashes del libro/reporte en notas previas.
-
Catalog read confirmed the report-facing labels; implementing valor_opcion -> nombre_mostrable for the seven fields only.
-
was: Sale de una observacion de audit-mba-l-cc al revisar MOVILBA-463 (v5.5.208). NO es el mismo defecto y la correccion NO es la misma. En src/app/api/reportes/vehiculos-historico/route.ts, siete columnas usan coalesce(raw_x, op_x.valor_opcion) contra el catalogo general/respuesta_binaria: adas, mdvr, pantallas, wifi, conexionesUsb, identidad, cabinaAntivandalica. (unidadPropulsora tambien usa el patron pero sus 5 valores son conceptos distintos - ELECTRICO, ELECTRICO-CABA, GN, GNC, GO - no un problema de mayusculas; no entra aca.) MEDIDO en DEV 2026-09-17, borrado_en IS NULL, sobre raw_adas como muestra: - LIBRO: 'Si' 3397, 'No' 2102, 'SI' 14, 'si' 1. - CATALOGO general/respuesta_binaria valor_opcion: 'SI', 'NO', 'NA', 'DESCONOCIDO'. O sea la dispersion de mayusculas ES DEL LIBRO, no la produce nuestro respaldo. Por [[reference_una_migracion_que_declara_bug_al_dato_del_libro_destruye_el_ssot_y_deja_el_valor_correcto_sin_testigo]] esa dispersion NO se normaliza: es el dato presentado y se emite tal cual. Lo que si es nuestro: para un periodo escrito por la app, el respaldo emite 'SI'/'NO' (mayuscula del catalogo), que es la grafia MENOS usada del libro (14 de 5514). Agregamos una grafia en vez de adoptar la que el libro usa casi siempre. Arreglo acotado: initcap(lower(valor_opcion)) SOLO en la ranura de respaldo, igual que se hizo con tramite en MOVILBA-463, dando 'Si'/'No'. No toca una sola fila de import. Cuidado antes de aplicarlo: el catalogo tiene ademas 'NA' y 'DESCONOCIDO'. initcap los volveria 'Na' y 'Desconocido'. Hay que censar si alguna fila de app los usa en estas 7 columnas y decidir su grafia explicitamente en vez de dejarla al initcap. Prioridad baja a proposito: Eugenia no reporto esto. El item 27 pide filtrar por Tramite, que ya quedo resuelto en MOVILBA-463.
-
DB fact confirmed by db04 in both PROD and DEV via public.v_opciones, group general/campo respuesta_binaria, ids 24/25: id24 valor_opcion='SI', nombre_mostrable='Sí'; id25 valor_opcion='NO', nombre_mostrable='No'. Neither display label is NULL or identical to the machine value. Current diff changes exactly the seven SELECT outputs to nombre_mostrable. route.ts SHA256 e6562e3c88f3d92e1a7c3983c2586b437390c613ba0624726837a1a465d43d8f. No gates run before audit handoff.
-
coder03-mba-l-cc 2026-10-08 21:05Z - UNBLOCKED. The Eugenia ask is CANCELLED and the question was mis-framed; it is neither Eugenia's call nor Elazar's, because the repo rule already answers it. .claude/rules/catalogos.md:14 - valor_opcion is the MACHINE contract (canonical, uppercase, unaccented); nombre_mostrable is the HUMAN label (accented, rewritable); 'they differ on purpose'. Line 40 - never invent UI text, render nombre_mostrable / valor_opcion. So the defect in 465 is not a choice between SI/NO and Si/No: it is a user-facing report rendering the machine contract where the display label belongs. The book's spelling does not enter into it - Elazar's 2026-09-24 ruling is that no surface shows raw book text for a field with a catalog behind it, and a report is a surface like the ficha. Asking Eugenia which label our report prints would hand her a UI decision of ours. She gets facts. db04 measured the one fact the lane could not read, SELECT-only in both bases, 2026-10-08 17:59 ART: public.v_opciones general.respuesta_binaria id 24 = valor_opcion 'SI' / nombre_mostrable 'Si' with acute i, id 25 = 'NO' / 'No'. PROD movilba and DEV movilba_dev agree exactly, and neither display label is NULL or identical to its machine value. So the catalog row is NOT the defect and the fix stays in the route. Fix: src/app/api/reportes/vehiculos-historico/route.ts projects op_*.valor_opcion directly for the seven fields Cabina_Antivandalica, ADAS, MDVR, Pantallas, Wifi, ConexionesUSB and Identidad - those seven move to nombre_mostrable. Scope limit to state in the diff: this is the historical-report route only; the other surfaces of the same fields are a separate census and are not claimed fixed by this.
-
coder03-mba-l-cc 2026-10-08 21:08Z - literal correction and retraction status. CORRECTION to my 21:02Z note: db04's SELECT returned id 24 nombre_mostrable = Si with an ACUTE i (U+00ED), not an unaccented Si. id 25 = No. valor_opcion stays SI / NO. Both bases agree. My earlier note rendered the accent wrong; the accented form is the measured value and it is the whole point of the fix, because the accent is exactly what valor_opcion cannot carry. The diff must NOT hardcode either string - it projects nombre_mostrable from the catalog so a future relabel reaches the report without a code change. A literal 'Si' in the route would reproduce the same defect one layer up. RETRACTION: nothing to retract. db04 did not send any 465 question to Eugenia and did not edit the tracker. coder03assistant sent the question to ME, not to her, and did not contact her directly; bwi's blockedReason only recorded that PM PLANNED to route it. So the ask never left the lane and the live tracker has no 465 row to undo. Confirmed by both lanes at 18:02 and 18:03 ART. The seven-field route diff is with audit at the SHA pinned on this item.
-
audit fail: e6562e3c, that route only: the 7 valor_opcion->nombre_mostrable projections. Gates RUN by me under lock: eslint, typecheck, test:source, test:tools, plus a catalog census in both bases. NOT exercised: next build, any live HTTP request, no emitted artifact, no other surface of these 7 fields.
payload
{"scope":"e6562e3c, that route only: the 7 valor_opcion->nombre_mostrable projections. Gates RUN by me under lock: eslint, typecheck, test:source, test:tools, plus a catalog census in both bases. NOT exercised: next build, any live HTTP request, no emitted artifact, no other surface of these 7 fields.","outcome":"fail","evidence":"FAIL, one blocking, measured. Full body in audit-finding on this item.\n\nBLOCKING: the diff breaks a ship-path gate nobody updated with it. pnpm test:source = 65 pass / 1 FAIL on src/lib/rutap-history-values.test.ts, which asserts the SQL TEXT of this very route and pins op_<f>.valor_opcion AS \"<alias>\" at :150-156 for exactly the 7 fields this diff moves. Verbatim: AssertionError [ERR_ASSERTION]: The input did not match the regular expression /op_cabina_antivandalica\\.valor_opcion\\s+AS \"cabinaAntivandalica\"/. It aborts on the first, so the other 6 pins are equally false. test:source runs on BOTH paths - mba-deploy-dev.sh:175 and mba-deploy-prod.sh:58 - so this ships on neither. Fix = those 7 regexes in the SAME commit. Do NOT weaken or skip the test: tsc cannot typecheck inside a raw sql`` template, so that pin is the only guard against a silent projection change.\n\nCOVERAGE of the 7, asked explicitly: the only test touching them is that text pin, and it pins the OLD text. No test asserts a VALUE - nothing checks that adas_presente_id 24 serialises to the display label, so the emitted label is UNEXERCISED before and after the repair.\n\nFINDING, same commit: an EIGHTH field of the identical class is left behind. op_aire_acondicionado joins general/respuesta_binaria exactly as the 7 do (:131-134) and still projects valor_opcion at :57. PROD population 24 on 5502 rows, 25 on 56 - the same two ids. After this diff one report row prints adas accented beside aireAcondicionado \"SI\": 8 columns, 1 catalog, 2 label styles, where today all 8 are uniformly the machine contract. Not a regression (8 wrong labels -> 1), but a self-contradicting report, against the 2026-09-24 one-label ruling.\n\nCENSUS complete: catalog has FOUR rows (24 SI, 25 NO, 26 DESCONOCIDO, 27 NA->N/A) so a 27 would gain a slash, but only 24/25 occur in all 8 columns in PROD - unreachable today.\n\nHELD: eslint 0; typecheck clean, tsconfig.json unchanged after typegen; test:tools 116/116; diff exactly 7+/7-.","reportRef":null} -
# MOVILBA-465 @ e6562e3c — audit verdict: FAIL (one blocking, measured) audit-mba-l-cc, 2026-10-08, signed 21:0x Z (see this event's createdAt). Gates run by me under `gates-checkout-movilba-web`. File hash matched the claimed `e6562e3c` before and after every gate. src/app/api/reportes/vehiculos-historico/route.ts e6562e3c88f3d92e1a7c3983c2586b437390c613ba0624726837a1a465d43d8f ## BLOCKING — the diff breaks a ship-path gate that was not updated with it `pnpm test:source` is **65 pass / 1 fail**: `src/lib/rutap-history-values.test.ts`. That file asserts the **SQL text of this very route**, and lines 150-156 pin `op_<field>.valor_opcion AS "<alias>"` for **exactly the seven fields this diff moves** to `nombre_mostrable`. First assertion to blow, verbatim: ``` AssertionError [ERR_ASSERTION]: The input did not match the regular expression /op_cabina_antivandalica\.valor_opcion\s+AS "cabinaAntivandalica"/ ``` It aborts on the first, so the remaining six (`adas`, `mdvr`, `pantallas`, `wifi`, `conexionesUsb`, `identidad`) are equally false. **Both** `mba-deploy-dev.sh` (`:175`) and `mba-deploy-prod.sh` (`:58`) run `test:source`, so this cannot ship on either path. coder03assistant stated gates were not run before handoff; this is precisely what they catch. The gate is behaving correctly and is **not** the defect: the seven regexes belong in the same commit as the seven projections. Do not weaken, skip or delete the test — a text-pinning test is the only thing standing between a raw `sql\`\`` template and a silent projection change, since `tsc` cannot type-check inside the template. ## FINDING — there is an EIGHTH field of the identical class, and the diff leaves it behind `op_aire_acondicionado` joins `general`/`respuesta_binaria` exactly as the seven do (join at `:131-134`) and still projects `valor_opcion` at `:57`. Measured population in PROD: `aire_acondicionado_id` is **24 on 5502 rows and 25 on 56** — the same two ids as the seven. So after this diff a single report row prints `adas: "Sí"` next to `aireAcondicionado: "SI"`: **eight columns, one catalog, two label styles**, where before the diff all eight were uniformly the machine contract. The item's own framing ("a user-facing report rendering the machine contract where the display label belongs") applies verbatim to the eighth, and Elazar's 2026-09-24 ruling — one field, one catalog label, every surface — makes a report that contradicts itself the defect. **This is not a demand to widen scope for its own sake.** coder03's scope limit on the item is explicit and I accept it for *other surfaces*. But the eighth field is the same file, the same catalog, the same join shape and one line, and shipping seven of eight leaves a visibly mixed artifact. It belongs in this commit. If the owning lane disagrees, file it before this ships so the mixed state is on the record rather than discovered by a user. Note this does **not** make the diff a regression: user-visible wrong labels go from 8 to 1, which is strictly closer to correct. That is why the finding is separate from the blocking item above. ## CENSUS COMPLETE — closing a gap the item's evidence left open The catalog has **four** rows, not two: `24 SI/Sí`, `25 NO/No`, `26 DESCONOCIDO/Desconocido`, `27 NA/N/A`. The diff relabels whatever id is present, so a row holding 27 would have gone from `NA` to `N/A` — a slash newly appearing in an export column, a sharper change than casing. **Measured: only 24 and 25 occur**, in all eight columns, in PROD; 24/25 plus NULL in DEV (31-36 NULLs per column, DEV-only test rows). So the item's 24/25 census is complete for the population and the `NA`/`DESCONOCIDO` path is unreachable today. Catalog rows are identical in both bases, and `nombre_mostrable` for id 24 is hex `53c3ad` — `S` + U+00ED, genuinely accented. The two notes on the item write it as `Sí` and as `Si` with "acute i"; those are the same string, not a discrepancy. ## PRE-EXISTING — not this diff, not blocking, worth naming Every `op_*` join reads **`public.opciones` directly**, not `v_opciones`/`v_ui_*` as the permanent catalog rule requires, and **none filters `borrado_en`** — so the route would render a soft-deleted label. There are **33 soft-deleted options in PROD and 34 in DEV**. Two consequences: the rule violation predates this diff and belongs to whoever owns the route's catalog reads, and the item's evidence was read from `v_opciones`, which is a *different relation* than the route reads. For ids 24-27 the rows are not deleted, so that evidence still holds for this change specifically. ## HELD - `eslint` on the changed file: **0** problems. - `pnpm typecheck` (`next typegen` + `tsc --noEmit`): clean, and `tsconfig.json` is unchanged afterwards (`bced5cc3`, `git status` clean on it) despite typegen owning its `include` array. - `pnpm test:tools`: **116/116**. - The diff is exactly **7 insertions, 7 deletions**, all `valor_opcion` → `nombre_mostrable`, and touches only the seven named aliases. `tipoMotor`, `unidadPropulsora`, `carroceriaCategoria` and `tramite` keep `valor_opcion` with their reasons stated in-code at `:50-53` and `:81` (MOVILBA-535 canonical book spelling; `tramite` deliberately avoiding `nombre_mostrable`), and `piso` at `:42` already used `nombre_mostrable`. So the file's mixed state is deliberate and documented for those five — which is exactly why the undocumented eighth stands out. ## NOT EXERCISED - **`next build`** — not run by me. `mba-deploy-prod.sh:62` runs it; `mba-deploy-dev.sh` does not. - **No live HTTP request** against the route, on any host. No XLSX, CSV or JSON artifact opened, so I have not seen `"Sí"` actually emitted — the label is measured from the catalog rows and the projection text, not from a response body. The route has real traffic (`docs/reference/movilba-667-route-usage-census.md`: 6, 42, 48 hits), so there are consumers; I did not identify them or check whether any parses `SI`/`NO` literally. A consumer doing so breaks on this change, and that risk is unmeasured. - **The other surfaces of these seven fields are not covered**, by the item's own scope limit and by mine. `src/lib/exports/rutap-historico.ts` maps keys to headers and consumes this route's rows, so it inherits the change; `src/repositories/rutap-libro.ts`, `src/lib/exports/vehiculos.ts`, `src/lib/exports/parque-movil-live.ts`, the ficha and the edit forms resolve these fields through their own queries and I did not measure which label each emits. That census is owed before anyone claims the fields are consistent app-wide. - **No negative control on the fix itself**: nothing asserts that the seven now emit the display label. The repaired text-pinning test will assert the new SQL text, which is a text control, not a value control — no test anywhere asserts that a row with `adas_presente_id = 24` serialises to `"Sí"`. Worth one assertion while the test file is open anyway.
-
audit-mba-l-cc correction: the audit-finding body above carries a literal placeholder 21:0xZ instead of the hour. The real signing time is this event pair's createdAt - audited 2026-10-08T21:12:55.547Z, audit-finding 21:13:05.792Z. Everything else in the body stands as posted.
-
El reporte historico emite el contrato de maquina en ocho campos binarios del catalogo
-
was: The historical report is user-facing, but its seven binary catalog columns currently emit valor_opcion (machine contract) rather than nombre_mostrable (display label). On both PROD and DEV, general.respuesta_binaria id 24 is valor_opcion='SI', nombre_mostrable='Sí'; id 25 is 'NO' / 'No'. Replace valor_opcion with nombre_mostrable for cabina_antivandalica, adas, mdvr, pantallas, wifi, conexiones_usb and identidad in src/app/api/reportes/vehiculos-historico/route.ts. Do not emit raw workbook text or normalize casing in Next.js. The per-column book census and source hashes are in the notes.
-
Revised after audit FAIL. Route now projects nombre_mostrable for all eight general.respuesta_binaria fields, including aire_acondicionado; source test updates all eight existing projection pins and asserts no valor_opcion remains under those output aliases. Exact SHA256: route 8ec8943fbd776ebbbf9f3f1256d155268e1dbffc280b6947d4da68469388fd20; test 9fccc326aa379fe3a88f2fb93fb2fcc39851e42c188d9a6a2372b794a4bbda22. git diff --check passes. Following coder role handoff rule, lint/typecheck/tests not run before audit. Test coverage limit remains: no test asserts an emitted catalog value; report it as unexercised.
-
audit-mba-l-cc correction, 2026-10-08, signed by this event's createdAt. Cite fix in my FAIL evidence on this item: I wrote mba-deploy-prod.sh:58 for test:source. The measured line is :59 (test:tools is :61). Re-measurable with grep -n 'test:source\|test:tools' mba-deploy-prod.sh. The finding is unchanged - both deploy scripts DO run test:source and test:tools, so the broken src/lib/rutap-history-values.test.ts pin blocks both ship paths; only the line number was wrong.
-
Revised route + source-pin diff is with audit for re-verdict at the exact hashes recorded in progress; hold pending that verdict. Shared checkout lock is held by audit.
-
audit pass: route.ts 8ec8943f and rutap-history-values.test.ts 9fccc326, re-hashed by me: the eight respuesta_binaria projections and the new assert. Gates re-run after drizzle/schema.ts moved mid-run. NOT exercised: no test runs the SQL, emitted values derived not observed; other 3 surfaces unmeasured.
payload
{"scope":"route.ts 8ec8943f and rutap-history-values.test.ts 9fccc326, re-hashed by me: the eight respuesta_binaria projections and the new assert. Gates re-run after drizzle/schema.ts moved mid-run. NOT exercised: no test runs the SQL, emitted values derived not observed; other 3 surfaces unmeasured.","outcome":"pass","evidence":"PASS. Both pins re-hashed by me; hashes and full body in the audit-finding posted with this.\n\nMEASURED: general/respuesta_binaria in BOTH bases is 24 SI/Si, 25 NO/No, 26 DESCONOCIDO/Desconocido, 27 NA/N-A - 4 of 4 live rows differ, so all eight fields emitted the machine contract and now emit the label.\n\nTHE CONTROL WAS SEEN TO FAIL: git show HEAD:route.ts gives 8 hits against the new assert.doesNotMatch, so it FAILS on the prior bytes; the tree gives 0 and passes. Alternation over all eight aliases, so a partial revert of any ONE field also fails it. test:source prints the file; run-source-tests.mjs walks dirs.\n\nGATES, RUN BY ME AND RE-RUN: eslint 0, typecheck 0, test:source 66/66, test:tools 118/118. The first run used drizzle/schema.ts b6029b49, db04's DEV regen, reverted to HEAD under a second lock string while I held gates-checkout-movilba-web. A gate result against a tree that no longer exists is not evidence, so all four re-ran against f34b4bea, hashed before and after, unchanged. The figures are the re-run.\n\nADJACENT, FILED AS MOVILBA-765, NOT covered by this PASS: three projections in the same SELECT still emit valor_opcion on a surface 465's own description calls user-facing. Per id in PROD over all 5558 rows: unidadPropulsora 57 of 5558 differ (id 37), tipoMotor 57 of 5558 (id 174), carroceriaCategoria 5558 of 5558 (id 72, M3 vs M3 - Colectivos). Two withdrawals from my draft: catalogos.md:51-63 decides which id ELECTRICO-CABA resolves to, not how this route renders 37; the unfiltered borrado_en at :102-107 is the RULE for a stored FK's label, catalogos.md:23. tipoMotor keys estandar_emisiones_id against campo estandar_emisiones - key and campo agree, NOT a cross-field join.\n\nNOT EXERCISED: no test runs the SQL - every assertion is a regex over source text, so the emitted value is derived from the catalog, not an observed response; no fixture, live request, XLSX or PDF; the other three surfaces unmeasured by me; lint:strict and next build not run.","reportRef":null} -
# MOVILBA-465 — audit verdict: PASS on the eight respuesta_binaria fields. The three remaining projections on the same surface are FILED as MOVILBA-765 audit-mba-l-cc, under the hub lock `gates-checkout-movilba-web` (mine, sole holder, no waiters — verified by bare `locks()`). src/app/api/reportes/vehiculos-historico/route.ts 8ec8943fbd776ebbbf9f3f1256d155268e1dbffc280b6947d4da68469388fd20 src/lib/rutap-history-values.test.ts 9fccc326aa379fe3a88f2fb93fb2fcc39851e42c188d9a6a2372b794a4bbda22 Both pins re-hashed against the tree at verdict time. The producing lane ran no gates; I ran them. ## 1. The change is substantive, measured against the catalog Eight projections move `valor_opcion` → `nombre_mostrable`: `aireAcondicionado`, `cabinaAntivandalica`, `adas`, `mdvr`, `pantallas`, `wifi`, `conexionesUsb`, `identidad`. `public.opciones` where `grupo_nombre='general' AND campo_nombre='respuesta_binaria'`, measured in BOTH bases, identical: 24 `SI`/`Sí`, 25 `NO`/`No`, 26 `DESCONOCIDO`/`Desconocido`, 27 `NA`/`N/A`. **4 of 4 live rows differ**, so all eight fields were emitting the machine value on a published export surface and now emit the human label. ## 2. The new control was SEEN TO FAIL — it is a control, not a green line git show HEAD:src/app/api/reportes/vehiculos-historico/route.ts -> 8 hits, assert.doesNotMatch FAILS the tree's route -> 0 hits, passes The regex is an alternation over all eight aliases, so a partial revert of any ONE field also fails it. The file is genuinely executed: `pnpm test:source` prints `✔ src/lib/rutap-history-values.test.ts`, and `tools/run-source-tests.mjs` walks directories with `readdirSync` rather than naming files. ## 3. Gates — run by me, and RE-RUN because the tree moved mid-run | gate | result | |---|---| | `eslint` on both files | 0 | | `pnpm typecheck` (`next typegen` + `tsc --noEmit`) | 0 | | `pnpm test:source` | 66/66 | | `pnpm test:tools` | 118/118 | My first run executed against `drizzle/schema.ts` = `b6029b4923e99e7b4da3f21dd4af391ce427407a890ed65b26621e2cdda117d3`, db04's 15-hunk DEV regen. While I held the lock, that file was reverted to HEAD. A gate result against a tree that no longer exists is not evidence, so I re-ran all four. **The figures above are the re-run**, against `drizzle/schema.ts` = `f34b4beaf82f1522f94af2e0c4c8fcba43a3c0c9c339e7402ccf72b57df7f20b`, hashed immediately before and after and unchanged across it. The two 465 files' own pins were identical in both runs. Process note, not a grade on the fix: the revert landed in the shared checkout while this lock was held, under a second resource string (`movilba-web-checkout`). The regen's timing is not established by anything I measured. Two strings over one checkout is not mutual exclusion — a bare `locks()` is the only census. ## 4. The three surviving `valor_opcion` projections — FILED as MOVILBA-765, measured per id **There is no open surface-class question, and it is 465's own item that settles it.** `bwi show MOVILBA-465` reads "The historical report is **user-facing**", and its stated scope is the eight `respuesta_binaria` projections plus the test file. So the class of this surface is decided inside the assigned task; the three remaining projections are the same defect class on the same surface, outside 465's field scope. That makes them a filed gap, not a question for Elazar. **MOVILBA-765**, with the per-id measurements below. 1. **`:35 unidadPropulsora`** → join `:132-135`, `motor/unidad_propulsora`. Measured EMISSIONS, not catalog rows: PROD over all 5558 history rows is 4875 on id 124 (`GO`/`GO`), 626 on 157 (`GNC`/`GNC`), **57 on id 37 (`ELECTRICO`/`Eléctrico`)** → divergence **57 of 5558**. Correcting my own draft: `catalogos.md:51-63` decides WHICH id the book value resolves to, not how this route renders id 37. That citation was wrong; the defect stands. 2. **`:55 tipoMotor`** → join `:124-127` keys on `h.estandar_emisiones_id` with `campo_nombre='estandar_emisiones'`. **Key and campo agree — it is NOT the cross-field join `catalogos.md:16` warns about**, which is what I had to read the ON clause to establish. PROD: 4006 on id 59 (`E5`/`E5`), 874 on 17 (`E3`/`E3`), 621 on 173 (`GNC`/`GNC`), **57 on id 174 (`ELECTRICO`/`Eléctrico`)** → divergence **57 of 5558**. Separate naming observation, **consumer impact NOT measured**: the JSON key is `tipoMotor` while the value is the emissions standard. `rutap.vehiculo_historial_normalizado` has **no `tipo_motor_id`** — only `tipo_motor` and `raw_tipo_motor`, both text — so `estandar_emisiones_id` is the only catalog-backed motor field available, which is consistent with the in-code comment at `:52`. 3. **`:47 carroceriaCategoria`** → join `:102-107`, `vehiculo/categoria_regulatoria`. **All 5558 PROD rows carry id 72** (`M3` / `M3 - Colectivos`) → divergence **5558 of 5558**, the largest of the three. **One half of my draft is withdrawn**: the unfiltered `borrado_en` is the RULE, not a defect — `catalogos.md:23`, "Resolving a value that already exists ... **reading a stored FK's label**: do **not** filter", which names `regimen_servicio_modalidad` at 0 live of 7 while 2395 of 2396 fichas point into it as the expected shape. A `borrado_en` filter must NOT be added here. The label half stands. The same ON clause carries an OR branch on the text column (`valor_opcion = h.carroceria_categoria`); **how many rows resolve through it is not measured**. ## 5. Why MOVILBA-765 must not be "fixed" in the book mirror too The book-mirror view `rutap.v_export_libro` emits `valor_opcion` for **these same fields** — measured by me in PROD from `pg_get_viewdef`: `op_X.valor_opcion` into `rutap.export_libro_catalogo(...)` at `:22`, `:24-26`, `:32-35`, and `unidad_propulsora` at `:10`. 574:26-30 records the reason: "ETIQUETA = valor_opcion (el literal canonico, el vocabulario del libro) ... nombre_mostrable difiere en 3000-5500 filas por columna booleana" — precisely these eight columns, chosen deliberately against `nombre_mostrable`. No contradiction with 465: 574 is scoped to the mirror, where the book's vocabulary is the product; 465 and 765 are a user-facing report. Recorded here so the next lane does not propagate 465's change into the mirror and silently revert an applied decision. Both values are catalog values, so ruling 2 of 2026-09-24 does not distinguish them — the mirror/report split does, and it is now written in both items. ## 6. NOT EXERCISED — part of the verdict - **No test executes the SQL.** Every assertion in `rutap-history-values.test.ts` is a regex over the query's SOURCE TEXT. That the export now emits `Sí`/`No` is a DERIVATION from §1's catalog measurement, not an observed response body. No fixture, no live request, no XLSX/PDF inspected. - **The other three surfaces of these eight fields are unmeasured by me** (page, edit form, JSON API). This verdict covers the historical-export route and, for §5 only, `v_export_libro`. - `pnpm lint:strict` not run and runs on no ship path (baseline-red on vendored `public/scalar`); `next build` not run. - Nothing here measured a PROD response; `drizzle/schema.ts` mirrors DEV only.
-
Audit PASS recorded on route 8ec8943f and test 9fccc326; ready for the exact-path SHIP handoff. Emitted-value behavior remains unexercised, as recorded in the audit scope.
-
coder03-mba-l-cc 2026-10-08 19:29 ART / 22:29 UTC. SHIPPED on all three surfaces in one task, fleet parity measured and not assumed. DEV ffef7e6e patch 209, PROD 89c1fabb patch 209, POD patch 209 read as serviceId 29544 = (29544-911)/137 exact, by proxy-mba-w-cc over whey because the pod leg never goes from lezama. Files carried: src/app/api/reportes/vehiculos-historico/route.ts sha256 8ec8943fbd776ebbbf9f3f1256d155268e1dbffc280b6947d4da68469388fd20 and src/lib/rutap-history-values.test.ts sha256 9fccc326aa379fe3a88f2fb93fb2fcc39851e42c188d9a6a2372b794a4bbda22, both re-hashed by audit and again by me against the tree as the last step before the commit, 2 of 2. The control was a MUTANT and not a green: audit forced the new assert to FAIL against HEAD's bytes at 8 hits and pass against the tree at 0. Gates by audit: eslint 0, typecheck 0, test:source 66/66, test:tools 118/118. The prod leg parked the WHOLE tree to a stash and restored it, 26 entries before and 26 after; that park is also why prod's test:tools never saw the two unverdicted MOVILBA-753/754 test files sitting untracked under tools/tests/. SIN EJERCITAR, and this is not a verdict of correctness: no live HTTP request was made against the report on any of the three surfaces, so the eight si/no fields are confirmed by the mutant over the query text and by nothing that rendered. STILL OPEN and NOT covered here: MOVILBA-765, the same SELECT's three remaining valor_opcion projections. Its tipoMotor hunk was STOPPED by me before verdict - it reversed MOVILBA-535's applied decision and deleted the comment recording it; unidadPropulsora and carroceriaCategoria proceed, tipoMotor is now a question for Elazar.
-
coder03 2026-10-08 19:31 ART. SHIPPED on all three surfaces, parity measured not assumed: DEV ffef7e6e patch 209, PROD 89c1fabb patch 209, POD patch 209 read as serviceId 29544 by proxy-mba-w-cc over whey. Files carried: route 8ec8943f, test 9fccc326, both re-hashed against the tree as the last step before commit. Control was a MUTANT not a green: audit forced the new assert to FAIL on HEAD at 8 hits, pass on the tree at 0. Gates by audit: eslint 0, typecheck 0, test:source 66/66, test:tools 118/118. Prod leg parked the WHOLE tree to a stash and restored it, 26 entries before and after; that park is why prod test:tools never saw the two unverdicted 753/754 test files untracked under tools/tests/. SIN EJERCITAR: no live HTTP request against the report on any surface, so the eight si/no fields are confirmed over query text and by nothing that rendered. NOT covered here: MOVILBA-765. Its tipoMotor hunk was STOPPED before verdict - it reversed MOVILBA-535 and deleted the comment recording it.
-
Shipped with MOVILBA-765 on DEV/PROD/POD patch 209; route 8ec8943f plus source-pin test 9fccc326 passed audit. All eight respuesta_binaria projections corrected and pins updated. No live HTTP/value render was exercised; that coverage limit remains recorded.