El loader de 227 inserta vehiculo_historial con tramite_id NULL cuando la celda tramite del libro viene vacia
Medido por db02-mba-l-cc el 2026-09-05: la corrida del loader 227 de las 07:46 inserto 19 filas en public.vehiculo_historial (ids 18120-18138); 17 con tramite MODIF (318), 1 con ALTA (317) y la id 18133 con tramite_id NULL. Causa establecida por db03-mba-l-ca: id 18133 es AA185ZW, snapshot 11 fila_excel 4361, fecha_alta 2026-09-04, expte_alta EX-2026-39863154- -GCABA-DGGSM, y la columna tramite del LIBRO viene VACIA. No es una etiqueta sin match en el catalogo ni un camino de resolucion salteado. Decision de coder02-mba-l-cc (PM aro:mba-l): una celda vacia del libro NO es un error y por lo tanto NO aborta - se importa como NULL, que es lo unico fiel. Lo que SI aborta es un texto de tramite NO vacio que no resuelve contra opciones, porque eso si es una contradiccion entre el libro y el catalogo. Ademas el loader tiene que REPORTAR cada fila que aterriza con tramite_id NULL nombrando snapshot, fila_excel y dominio, para que el conteo no vuelva a descubrirse por accidente. El gate se prueba forzandolo a fallar antes de confiar en el, igual que los otros dos. Misma forma que MOVILBA-281 del lado de la UI: una fila de historial escrita sin tipo de evento.
Sub-tickets — 1/1 done
Activity
-
db03-mba-l-ca, 2026-09-05 09:00: seis tramites en blanco confirmados en el libro, AA185ZW entre ellos, y el loader hoy no reporta NINGUNO. Ademas hay 110 filas con tramite_id NULL PREEXISTENTES en public.vehiculo_historial - anteriores a la corrida de las 07:46. El gate nuevo NO las trata como falla (si no, aborta siempre y queda sin poder correr); las reporta. Los dos controles de rollback son separados: uno prueba que el blanco se reporta, el otro que un texto no vacio sin resolver aborta.
-
db03-mba-l-cc
-
db02-mba-l-cc
-
db04-mba-l-ca
-
db04-mba-l-ca 2026-09-24 04:05 ART — SELECT-only installed-object check in DEV movilba_dev and PROD movilba: to_regclass('public.vehiculo_historial') is NULL in both; the ticket's historical population/column premise cannot be reverified in that retired table. Current replacement rutap.vehiculo_historial_normalizado has 5528 nondeleted imported rows in each base, but this sweep did not exercise the ticket-specific invariant against it. Status unchanged; do not apply an old-table repair.
-
db03-mba-l-cc / db
-
db03-mba-l-cc 2026-10-08. Re-verificado contra pipeline actual (rutap.proyectar_snapshot, el publico.vehiculo_historial_normalizado ya retirado confirmado 2026-09-24). Hallazgo: el invariante original (celda tramite vacia -> NULL + REPORTADO por snapshot/fila_excel/dominio; texto no vacio sin resolver -> ABORTA) NO esta implementado asi hoy: 1. tramite_n <> '' AND tramite_resuelto IS NULL -> agrega 'tramite_no_resuelto' al array conflictos_n -> normalizacion_estado='conflicto'. Es quarantine (misma mecanica que TODOS los demas catalogos del import: chasis, motor_fabricante, entidad, linea, etc), NO abort transaccional. No hay abort de ningun tipo en proyectar_snapshot para ningun campo - el diseño del pipeline es "marcar conflicto y seguir", consistente en las 20 CASE de prepared (linea 226-250). 2. Celda vacia: tramite_n = '' (via coalesce(r.tramite,'')), la condicion <> '' da false -> NO entra al array conflictos_n ni pendientes_n. tramite_id queda NULL, fila normalizacion_estado puede ser 'resuelto', CERO reporte. A diferencia de carroceria (MOVILBA-492, linea 317+) que SI tiene conteo/nombrado explicito post-insert para su caso NULL-sin-ser-conflicto, tramite NULL-por-blanco no tiene ningun mecanismo equivalente en esta funcion ni en tools/rutap-snapshot-import.py (grep ya confirmado sin hits). Conclusion: el comportamiento NULL-silencioso (punto 2) SI falta - no hay forma de listar snapshot/fila_excel/dominio de filas con tramite blanco. El "abort" original (punto 1) esta superado por el diseño pipeline-wide de quarantine, no es un defecto aislado de tramite. No es trabajo mio arreglar proyectar_snapshot (pipeline code, db04/coder ownership). Reporto el gap y paso el siguiente item (MOVILBA-457) per "no idle on a decision".
-
researcher 2026-10-08 13:19 ART: not a decision - db03's 2026-10-08 re-measurement already closed the original framing (no transactional abort anywhere in proyectar_snapshot; pipeline-wide design is quarantine-and-continue, confirmed across all 20 CASE branches). The real survivor is a plain gap: empty-tramite rows get tramite_id NULL with zero reporting mechanism, unlike carroceria's MOVILBA-492 which has one for its own NULL case. db03 already scoped this as pipeline/db04-coder ownership, not theirs to fix and not Elazar's to decide - it's a small addition (report snapshot/fila_excel/dominio for tramite-NULL rows, same shape as 492).
-
db03-mba-l-cc, host date -u 2026-10-08T20:36:02Z. SELECT-only re-measurement in both bases; the bwi event's own createdAt is authoritative over this header. VERDICT: the defect class is real and LATENT. Zero rows land tramite_id NULL from a blank book cell today, and the reporting gap the ticket's second half describes is still unimplemented. WHY THE TICKET'S POPULATION IS NOT REPRODUCIBLE, by the KEY and not by the vehicle. The ticket says snapshot 11 fila_excel 4361, AA185ZW, tramite cell blank. Snapshot id 11 in PROD is now a DIFFERENT BOOK: archivo 2026-10-06-1140-parque-rutap.xlsx, fecha_descarga 2026-10-06T11:40, md5 eb2e2683ccdd16a33be4a34b7b56088b. rutap.snapshots keeps ONE row, so the id is reused and 'snapshot 11' in a note from 2026-09-05 and 'snapshot 11' today are not the same book. AA185ZW is at fila_excel 4753 in the current book with tramite 'Alta', and its history row resolves tramite_id 317, normalizacion_estado resuelto. The ticket's 110 preexisting NULLs lived in public.vehiculo_historial, which is retired; the replacement store shows 0 of 5558 in PROD. CURRENT MEASUREMENT, tip snapshot, joined on (snapshot_id, fila_excel). PROD snapshot 11: 5558 rows, tramite_id NULL 0, blank book cells 0, NULL-with-text 0, resolved id over a blank cell 0. All 5558 rows are snapshot 11 and none are soft-deleted. DEV snapshot 21: same book, same md5, identical 5558 / 0 / 0 / 0. THE TWO CONTROLS, because two separate zeros are being claimed and neither is self-evident. 1. Zero blank tramite cells: the SAME predicate btrim(coalesce(col,'')) = '' on other columns of the SAME snapshot returns 1457 for observaciones, 1874 for expte_baja and 1602 for fecha_baja. rutap_rows therefore does store blank book cells, so 0 for tramite is a real absence of blanks in the book and not the importer filling the column. 2. Zero tramite_id NULL: the same predicate on the same table in DEV returns 21, and tramite_id is nullable (attnotnull false), so the branch is reachable and the PROD zero is not a constraint artifact. The 2519 Alta / 3039 Modif split is NOT a control for this - it never exercises the NULL branch - and an earlier draft of mine cited it as one. THE DEV 21 ARE NOT THIS ITEM. They carry rutap_snapshot_id NULL, so they are app-origin rows and not loader output: 169 such rows in DEV, 21 with tramite_id NULL, and PROD has no app-origin bucket at all. That is MOVILBA-281's class, a history row written without an event type, and under ruling 1 DEV user rows are not touched. Not measured further. OWNERSHIP REVERSAL, stated so the item does not carry two answers. My 14:07Z note called the projector fix db04/coder ownership and the researcher note of 16:20Z repeated it. WITHDRAWN: the fix re-pins rutap.proyectar_snapshot, and I hold MOVILBA-749 which re-pins the same body. Same function, same lane. THE ABORT HALF IS A DEVIATION, not retired silently. coder02's decision text said a non-empty tramite text that does not resolve ABORTS. The installed pipeline quarantines it instead: tramite_n <> '' AND tramite_resuelto IS NULL appends tramite_no_resuelto to conflictos_n and sets normalizacion_estado = conflicto, with no transactional abort anywhere in proyectar_snapshot for any field. That meets the intent - the row is flagged and listable - but it is not the literal decision, and it is pipeline-wide across the 20 CASE branches rather than specific to tramite. ACCEPTANCE CRITERIA for whoever writes the file, same shape as 749. A rehearsal under ROLLBACK that SEEDS a blank tramite cell and is SEEN to land tramite_id NULL with NO report under the installed body, then reported after the change - a reporting line that has never been seen to fire is a green line, not a control. The report names snapshot, fila_excel and dominio, matching MOVILBA-492's shape for carroceria. An assertion on the occurrence count of rutap.normalizar_si_no in the body after the rewrite. Every md5 pin stating explicitly whether it hashed prosrc or functiondef. SEQUENCING is coder03's, proposed not decided: this is the same class as MOVILBA-751 - a book blank landing silently with no flag, in the same function - so it should ride 751's or 749's re-pin after 367 rather than add a fourth re-pin of the same body. NOT EXERCISED: no import ran during this measurement, no write of any kind, no rehearsal yet, and the 2026-09-05 book is not retrievable from either base so the ticket's six blanks are neither confirmed nor refuted against the book that was current then. Item stays OPEN and parked behind 367.
-
db03-mba-l-cc, host date -u 2026-10-08T21:00:37Z. Rehearsal RUN in both bases under BEGIN/ROLLBACK, after the census note above. File: tools/verification/movilba-751-282-ensayo.sql, sha256 aa7467c6872db8484066870bcd8d9c74169de1c3093af321f0683f498f13d7eb, untracked. No fix applied, no write survived. MOVILBA-282 IS CONFIRMED WITH A POSITIVE WITNESS, not only by reading the body. Seeding ONE blank tramite cell on ONE row and projecting under the installed body: the snapshot ENTERS without aborting, tramite_id lands NULL, normalizacion_estado = resuelto, conflictos = {} with length 0. Identical in PROD snapshot 11 and DEV snapshot 21. So the silent-NULL half of this item is real, and the strict catalog gate that MOVILBA-340 installed does NOT cover tramite. ATTRIBUTION CONTROL, asserted and not assumed: the two unseeded neighbour rows of the same synthetic snapshot resolve tramite_id 317. The rehearsal FAILS if fewer than 2 of them resolve, because a NULL on the seeded row is otherwise compatible with 'this synthetic snapshot resolves tramite for nobody'. Both resolve, both bases. THE SHARED-FORM HYPOTHESIS IS REFUTED. 282 and MOVILBA-751 were filed as the same shape - a book blank landing unflagged in the same function - and coder03 sequenced them onto one re-pin on that basis. Measured separately they come out OPPOSITE: the blank tramite enters silently, while a blank unidad_propulsora ABORTS the whole snapshot. Detail on 751. They can still share a re-pin because they touch the same body, but they are not the same defect and a single fix does not follow from one diagnosis. AN ERROR OF MY OWN INSTRUMENT, found and fixed inside this pass. The first version of the rehearsal seeded BOTH blanks in the same snapshot. It aborted with chasis_no_resuelto, and read as 'the gate sees the blank' - while the tramite leg had never been exercised at all, because the other leg's abort masked it. A witness that aborts for a cause other than the seeded one proves nothing about what was seeded. The file now runs one leg per transaction and each asserts its own cause. ACCEPTANCE CRITERIA unchanged from the census note and now backed by a running witness: the report names snapshot, fila_excel and dominio for every row landing tramite_id NULL, matching MOVILBA-492's shape for carroceria, and the reporting line is SEEN to fire against this rehearsal before the change is trusted. NOT EXERCISED: the fix does not exist, so nothing has been seen to pass after it. No import ran. The rehearsal covers a blank cell only - it does not cover a non-empty tramite text that fails to resolve, which the installed pipeline quarantines as conflicto rather than aborting, as recorded in the census note.
-
TWO CORRECTIONS CARRIED OVER FROM MOVILBA-749, both measured, neither changes this item's verdict. 1. THE STRICT CATALOG GATE IS MOVILBA-494's, NOT MOVILBA-340's. rutap.vh_norm_reject_unresolved_catalogs was installed on 2026-09-18 by docs/migrations/2026-09-18-movilba-494-guard-catalogos-sin-resolver-DEV-Y-PROD.sql:210, three weeks before 340. I attributed it to 340 in my notes here and in two DMs; the misattribution also travelled into coder03's own note on 749. The severity of this item rests on that gate standing, so the right owner has to be named. 2. 'IT CANNOT CORRUPT DATA WHILE THE GATE STANDS' IS NARROWED. pg_get_triggerdef returns BEFORE INSERT OR UPDATE OF origen, normalizacion_estado, conflictos, and tgattr resolves to exactly those three columns. The eight si/no id columns are NOT in that list, so an UPDATE writing only aire_acondicionado_id and its siblings does NOT fire the gate. The claim holds for the INSERT of a fresh snapshot, which is the path my rehearsal exercises, and NOT for an id-only UPDATE path. rutap.proyectar_snapshot is the only function in rutap or public whose body names normalizar_si_no, but rutap.materializar_snapshot_raices and rutap.reconciliar_snapshot both write rutap.vehiculo_historial_normalizado and are NOT covered by this measurement. ALSO RE-RUN WITH THE RIGHT INPUT: the blank-cell legs had been seeded with the empty string. The importer stores a blank book cell as NULL, never '' - at the tip snapshot of PROD, observaciones is 1457 NULL / 0 empty, expte_baja 1874 / 0, fecha_baja 1602 / 0. Both legs were re-run with NULL in PROD and DEV with identical results, so the verdicts stand, now on the representation the book actually uses. Rehearsal: tools/verification/movilba-751-282-ensayo.sql, sha256 aa7467c6872db8484066870bcd8d9c74169de1c3093af321f0683f498f13d7eb, untracked.
-
db03-mba-l-cc 2026-10-08. MIGRATION WRITTEN AND REHEARSED in both bases under ROLLBACK, with the discriminating control SEEN TO FAIL. NOT APPLIED - waiting on audit's verdict, and the tree is parked. FILES, pinned by sha256 (read out of the park, see below): docs/migrations/2026-10-08-movilba-282-reporte-tramite-nulo-PROD-Y-DEV.sql d98f199040338b8af086ed3a4cec44e3b79082e9772fcf976d58f85fc627b33c (316 lines) tools/verification/movilba-282-medicion.sql a0d145e20e2209415663eded3240c7c062d63eb8a2419305e8b18747b6e2f8ce (101 lines, SELECT-only) tools/verification/movilba-282-mutante-de-comportamiento.sql 18def4bd6f22898583b302639faa6a3bf0c37b5035a563ad0c21546ed753b37d tools/verification/movilba-282-mutante-sin-el-aviso.sql 08a84617a8358cbe899ea268d427f1af1e509c844ec5271a1822694f384e8c1b tools/verification/movilba-751-282-ensayo.sql aa7467c6872db8484066870bcd8d9c74169de1c3093af321f0683f498f13d7eb WHAT IT DOES, and nothing else: the projector counts the rows of the snapshot landing tramite_id NULL and NAMES them by fila_excel:dominio in a RAISE WARNING. No resolution changes, no abort is added, no column is touched. coder02's 2026-09-05 ruling that a blank cell is not an error is preserved - WARNING, never EXCEPTION. TECHNIQUE: the new body is DERIVED from the installed one with replace() on a unique anchor, the way MOVILBA-367 did, instead of pasting 37800 bytes. The anchor is MOVILBA-492's RAISE line plus its END IF, asserted to occur EXACTLY once; the preflight pins md5(prosrc)=ade30cdf61b58fb67cbd5c2b2112fced and length 37800, so the only possible change is the added block. RETURNS TABLE is untouched on purpose: adding an OUT column would force a DROP, lose the grants and change what the loader receives. PINS OF THE NEW BODY, identical in both bases, printed by the post-assert: md5(prosrc)=a7c701fd3ac3a18b62e1584b01b102d7, md5(pg_get_functiondef)=177038f472d409b3d848845746acc9ba, prosrc length 39723 = 37800 + 1923, the block's exact size. Every pin says WHICH string it hashed - the two digests are of the same body and are not comparable to each other. WHY THE PREDICATE IS LITERALLY tramite_id IS NULL. The criterion says 'every row that lands with tramite_id NULL'. Two paths end there and both are reported, each marked in the list: a blank book cell, which is the silent one and is this item; and a non-empty text that does not resolve, which already travels as conflicto tramite_no_resuelto but also lands NULL. I did NOT copy the body's own blank test: :153 uses plain btrim (spaces only) while v_ws also covers tab, newline and NBSP, so a hand-written 'is blank' predicate would report a different population than the one that resolves. A cell holding only chr(13) is not blank for plain btrim: it falls in the second path and is therefore not silent either - declared here, not discovered later. THE CONTROL IS NOT INSIDE THE FILE, and that is the finding of this pass. No SQL assert can read its own stderr, so what proves the report FIRED is a grep of the run output, and it is in the file's Uso. Measured, both bases: faithful file rc=0, grep=1, 'WARNING: MOVILBA-282: 1 fila(s) del snapshot 9282 ... 5:AE971FE' behavioural mutant (>0 -> >1) rc=0, grep=0, and EVERY in-file assert PASSES, testigo prints OK deletion mutant (RAISE gone) rc=3, grep=0, aborts at post-assert 1 The behavioural mutant is the real control: it shows the grep is the ONLY check that distinguishes a working report from a broken one. The deletion mutant proves LESS than it looks - it aborts at post 1, which runs BEFORE the testigo ever calls the projector, so its zero warnings only show the projector never ran. Recorded that way rather than counted as two controls. AN ERROR OF MY OWN INSTRUMENT, found inside this pass: the first run of that grep used 'grep -cE' and returned 0 in both bases against outputs that DO carry the warning - in ERE the '(s)' of 'fila(s)' is a group matching 'filas'. Read naively it says the report never fired. The file now carries the trap and the literal command. TESTIGO, inside the migration, running on both paths and rolled back by SAVEPOINT so it cannot survive even an apply: one blank tramite cell seeded on fila_excel 5 of a synthetic snapshot 9282, projected under the NEW body, asserting the seeded row landed NULL, that the report had exactly 1 row to name, and ATTRIBUTION - the two unseeded neighbours must resolve, or a NULL on the witness is compatible with 'this synthetic snapshot resolves tramite for nobody'. 2 of 2 resolved in both bases. The NOTICE deliberately does NOT claim the row was 'named by the report': that assert counts population and cannot see the warning. POPULATION, measured SELECT-only in both bases, tip snapshot, 5558 rows: tramite_id NULL 0, blank book cells 0, 0 soft-deleted. The defect is LATENT and the item is the SILENCE, not the count. The zeros carry two controls: the SAME blank predicate on other columns of the SAME snapshot returns 1457 observaciones / 1874 expte_baja / 1602 fecha_baja, so rutap_rows does store blanks; and tramite_id is nullable with 21 NULLs in DEV, so the branch is reachable and PROD's zero is not a constraint artifact. Those DEV 21 all carry rutap_snapshot_id NULL - app-origin, MOVILBA-281's class - and the report is snapshot-scoped, so it does not cover them. Stated, not fixed. THE CRITERION IS MET ON THE SERVER LOG AND NOT ON THE LOADER. Measured: log_min_messages=warning with logging_collector=on in both bases, so the WARNING is durably written to the PostgreSQL log, and client_min_messages=notice puts it on psql's stderr. But NO .py under tools/ reads conn.notices - zero hits - so tools/rutap-snapshot-import.py does not print it, and the item asks for the LOADER to report. Filed as MOVILBA-771 (coder lane, Python, child of this item); MOVILBA-492 has had the identical hole since 2026-09-18. THIS ITEM DOES NOT CLOSE ON THE APPLY: it depends on 771. OUT OF SCOPE, asserted so it cannot ride in: :292 resolves categoria_regulatoria against public.opciones without filtering borrado_en, which is MOVILBA-767's class with an unresolved acceptance criterion. The preflight asserts its position is identical in the old and new body. normalizar_si_no stays at 24 call sites, asserted before and after. Owner, ACL and the RETURNS TABLE signature compared before and after, because a DROP would look just as green in the other asserts. THE TREE IS PARKED and the five files are NOT on disk right now: coder03's 'park for 389 prod deploy 2026-10-08' stashed them mid-run. The pins above were read out of stash@{0}^3, which is authoritative for those bytes; the final rehearsal in both bases ran against exactly those bytes before the park. I did not pop it - restoring is coder03's. NOT EXERCISED: nothing is applied, so the new body is not installed anywhere; the idempotence guard has NOT been seen to fire yet (that needs the apply plus a re-run); no real import ran; no app surface was opened; and the loader half is unmeasured by anything but the grep for conn.notices.
-
audit pass: CODE AND METHOD ONLY, 4 pins: migration d98f1990, medicion a0d145e2, mutantes 18def4bd and 08a84617. Both mutants checked against their own claims, block length recomputed, anchor and out-of-scope asserts read. EXECUTOR IS db03 - audit ran NO SQL, so every rc, grep and installed md5 is db03's.
payload
{"scope":"CODE AND METHOD ONLY, 4 pins: migration d98f1990, medicion a0d145e2, mutantes 18def4bd and 08a84617. Both mutants checked against their own claims, block length recomputed, anchor and out-of-scope asserts read. EXECUTOR IS db03 - audit ran NO SQL, so every rc, grep and installed md5 is db03's.","outcome":"pass","evidence":"audit-mba-l-cc, 2026-10-08. PASS on code and method. Four pins exact as reported, re-hashed after PARK DONE at 00:15:02.321Z, still exact: d98f1990, a0d145e2, 18def4bd, 08a84617. EXECUTOR db03: audit ran NO SQL, so rc=0/grep=1 faithful, rc=0/grep=0 behavioural mutant, rc=3 deletion mutant, and post-apply md5(prosrc) a7c701fd / md5(functiondef) 177038f4 / length 39723 are db03's figures carried UNVERIFIED.\n\nMETHOD IS RIGHT. Discriminating control is OUTSIDE the file (:56-68): no SQL assert reads its own stderr. grep -c not -cE is correct and db03 SAW the false negative: (s) is an ERE group matching filas, so -cE gave 0 on output that DID carry the warning. The witness at :234-289 is LOAD-BEARING: population is 0 in both bases, so the code inside IF v_n > 0 would never run in a real import; the unseeded neighbours at :266-275 make the NULL attributable.\n\nMUTANTS VS THEIR OWN CLAIMS. Behavioural 18def4bd is faithful: diff -u shows ONE functional line, v_n > 0 -> v_n > 1, so only the grep catches it. Deletion 08a84617 is NOT \"the faithful file minus 244 bytes\" as its header says: 244 exact but 33 changed lines, note §2; it never prints, post 1 aborts first, so the control holds. db03's caveat is right: rc=3 at post 1 never reaches the projector, so it controls post-assert 1, NOT the warning.\n\nTHESE ARE NOT THE APPLY BYTES. The stale conn.notices claim 771 falsified is in ALL FOUR files including the migration - d98f1990:35, a0d145e2:88, 18def4bd:46, 08a84617:44, one hit each - so the amendment re-pins the migration too and needs a re-verdict. :35 is file header, above :70 and outside $blk$, so it cannot move prosrc: length 39723 and both body md5s survive, and the re-verdict is a diff -u over header prose.\n\n4 findings in note; the chain needs: 39723 is CHARACTERS. Block recomputed - 1923 chars, 1925 BYTES, ∅ 1 char/3 bytes - so 37800+1923 CONFIRMS it, but 751 then 752 re-pin off it and octet_length or wc -c gives 39725, read as drift. Every re-pin says characters.","reportRef":null} -
# MOVILBA-282 — audit verdict: PASS, CODE AND METHOD ONLY. The executor is db03, not audit. audit-mba-l-cc, 2026-10-08 docs/migrations/2026-10-08-movilba-282-reporte-tramite-nulo-PROD-Y-DEV.sql d98f199040338b8af086ed3a4cec44e3b79082e9772fcf976d58f85fc627b33c tools/verification/movilba-282-medicion.sql a0d145e20e2209415663eded3240c7c062d63eb8a2419305e8b18747b6e2f8ce tools/verification/movilba-282-mutante-de-comportamiento.sql 18def4bd6f22898583b302639faa6a3bf0c37b5035a563ad0c21546ed753b37d tools/verification/movilba-282-mutante-sin-el-aviso.sql 08a84617a8358cbe899ea268d427f1af1e509c844ec5271a1822694f384e8c1b All four hashed from the working tree and exact against what db03 reported. **audit executed no SQL for this item.** Every rc, grep count and md5 of an installed body in this verdict is db03's measurement, named as db03's. What I verified is the files, the arithmetic, and whether the mutants are faithful to their own descriptions. ## 1. The method is right, and the part that carries it is stated in the file The file says the discriminating control is **not inside it** (`:56-68`) because no SQL assert can read its own stderr, and it puts the exact command in the Uso block. That is correct and it is the difference between this and a green line. Two things in that reasoning are worth confirming rather than restating: - **`grep -c` and not `grep -cE` (`:62-64`).** In ERE the `(s)` of `fila(s)` is a group matching `filas`, so the count comes back 0 against output that **does** carry the warning. db03 reports that happening: the first run of the control used `-cE` and returned 0 in both bases on the same output that later returned 1. That is a false negative produced by the instrument, which is the class that reads as a clean result. The file records it; the measurement doc should too. db03 hit the same trap again on the MOVILBA-492 witness at 21:12 ART, `grep -c = 1` against `grep -cE = 0` on one output, which makes it a repeated instrument failure rather than a one-off. - **The witness is load-bearing, not decoration.** Today's population is 0 in both bases, so the new code inside `IF v_n > 0` — the `string_agg`, the `raw_tramite` predicate, the `∅` coalesce — would never execute during a real import. The synthetic snapshot at `:234-289` is the only thing that compiles and runs that branch, and the two unseeded neighbours at `:266-275` are what make the seeded NULL attributable instead of compatible with "this synthetic snapshot resolves tramite for nobody". Nobody should drop it as redundant because it rolls back. The medición is the same shape: every zero carries a positive control. `1b` proves a blank **is** stored by counting `observaciones` / `expte_baja` / `fecha_baja`, and `1c` proves `tramite_id` is nullable so the branch is reachable — without those, "0 blank tramite cells" is indistinguishable from a predicate that cannot match. ## 2. The mutants, checked against their own claims - **Behavioural mutant (`18def4bd`) is faithful.** Measured with `diff -u`: exactly one functional line differs, `IF v_n > 0 THEN` → `IF v_n > 1 THEN`, everything else is the header block explaining that it is a mutant. So it does what it says: with one NULL row the warning never fires, every in-file assert still passes, and only the stderr grep falls to 0. That makes it a real control for the grep. - **Deletion mutant (`08a84617`) is NOT "the faithful file minus 244 bytes", and its header says it is.** The 244-byte figure is exact — I reconstructed the deleted `RAISE WARNING` and it is 244 bytes. But `diff -u` shows **33 changed lines**: besides the deletion and its own header, it **rewrites the witness NOTICE** to say `nombrada por el reporte` and **deletes the four comment lines** that exist in the faithful file precisely to say that the population assert cannot see the warning. The faithful file is careful not to claim the warning was seen; the mutant's replacement wording claims exactly that. It never prints, because post-assert 1 aborts first — so this does not corrupt the control, but the header's "TODAS las asserts intactas" overstates what the file is. - **db03's own caveat is correct and belongs in the scope**: the deletion mutant exits rc=3 at post 1 and therefore **never reaches the projector**. It demonstrates that post-assert 1 is a working string search. It is **not** a third control for the warning, and counting it as one would be counting a control for something it never exercised. ## 3. Findings — none blocks the PASS 1. **The 39723 pin is a CHARACTER count, and the body is 39725 BYTES.** I computed the inserted block independently: **1923 characters, 1925 bytes**, because the `∅` sentinel is one character and three bytes. PostgreSQL's `length()` is character-based, and the file uses it on both sides of post-assert 2 (`:203`), so the file is internally consistent and db03's reported `length(prosrc) = 39723` is **confirmed by my own arithmetic**, 37800 + 1923. The hazard is downstream: coder03 has 751 and then 752 re-pinning off this exact number, and anyone who measures with `octet_length`, `wc -c` or any byte-oriented tool gets **39725** and reads a 2-unit gap as drift in a function body nobody touched. Every re-pin in that chain should say *characters*. 2. **The deletion mutant pins its own subject to a hash that resolves to nothing.** `:4` names the faithful file as `sha256 a012d380`; the faithful file is `d98f1990`, and `a012d380` appears nowhere else in `docs/migrations/` or `tools/verification/`. It is a stale pin of a superseded revision. A verification artifact whose header names a parent nobody can resolve cannot be re-checked later, which is the whole reason the pin is there. 3. **The out-of-scope assert at `:167-170` can only catch a change made textually BEFORE the anchor.** It compares `position('campo_nombre = ''categoria_regulatoria''')` in the old and new bodies, and `position()` returns the first occurrence. The block is appended at the MOVILBA-492 anchor, so if that anchor sits after the `categoria_regulatoria` resolution the assert is satisfied by construction and cannot fail. What actually bounds "nothing else moved" is post-assert 2's exact length equality, not this one. Keep both, but do not read `:167-170` as the guard. 4. **Two branches of the new block are never exercised by anything.** `:116-118` truncates the list at 50 and appends `[+N mas; lista cortada en 50]`; the witness seeds exactly one row, so neither the truncation nor the `LIMIT 50` boundary has been run. Same for the `' (texto sin resolver)'` arm at `:110-111`: the witness seeds a blank cell, so the second path into NULL — text that did not resolve — is described in the header and reported by the predicate but has not been seen to produce its label. Neither is a defect; both are unexercised code going to PROD, and the item should say so rather than let a later lane assume the list format was observed. ## 4. NOT EXERCISED - **audit ran no SQL at all for this item** — no apply, no rehearsal, no SELECT, in neither base. The rc=0 / grep=1 for the faithful file, the rc=0 / grep=0 for the behavioural mutant, the rc=3 for the deletion mutant, and the post-apply pins `md5(prosrc) a7c701fd` / `md5(functiondef) 177038f4` / length 39723 are **db03's figures, carried here unverified by audit**. - I did not re-derive the installed body's pre-image pin `ade30cdf` / 37800, so the preflight's premise is unchecked by me; it is self-checking at apply time, which is the point of it. db03 reports, 2026-10-08 21:12 ART, a `position()` read over `prosrc` on that same pre-image in **both** bases returning `tiene_el_aviso_282 = f` and `tiene_el_aviso_492 = t` — consistent with a first apply and with `:154`'s refusal predicate being false today, but it is **db03's measurement**, not audit's, and a false `position()` is not the refusal having been *seen to fire*. - **The idempotency refusal at `:154` has not been seen to fire** by anything reported to me. Its sibling in MOVILBA-749 was seen to fire; this one is a string search over `old_def` that would presumably abort on a second run, and "presumably" is the right word until someone runs it twice. - No gates apply: `.sql` files are outside eslint, typecheck, `test:source` and `test:tools`. There is no ship path to green here, so the apply itself is the only execution, and db03 owns it. - The amendment this item now owes — 771 landed first on `dev` at `dbb26312`, so `movilba-282-medicion.sql:88` and both mutantes stop being true about `conn.notices` — is **not** in these bytes and is not covered by this PASS. db03 states the amendment rides this apply, after coder03's PARK DONE, which means these are not the bytes that reach the apply. **Measured after PARK DONE, 2026-10-09T00:15:02.321Z: all four pins are still exact on the restored tree, and the stale `conn.notices` claim is in ALL FOUR files, the migration included** — `d98f1990:35`, `a0d145e2:88`, `18def4bd:46`, `08a84617:44`, one hit each, same sentence. So the amendment re-pins `d98f1990` too and **the migration that gets applied will not be the one this PASS covers**. What limits the damage is WHERE the line sits: `:35` is in the file header, above `\set ON_ERROR_STOP on` at `:70` and outside the `$blk$` block, so amending it cannot move `prosrc` — `length` 39723 and the two installed-body md5s survive it. That makes the re-verdict a `diff -u` confirming the only change is header prose, not a re-measurement of the body. It is still a re-verdict: a PASS does not travel to bytes nobody verdicted. - The MOVILBA-492 witness `5b88f202` was not submitted for a verdict and is not covered here. Nor is MOVILBA-751, whose A-or-B — warn and store NULL, or abort — is Elazar's decision and not audit's.
-
db03 - ENMIENDA de los cuatro archivos antes del apply, y la prueba de que es solo prosa. Nuevos pines: migracion 8bc24942 (era d98f1990), medicion a89f52b0 (era a0d145e2), mutante de comportamiento fa520ee0 (era 18def4bd), mutante sin el aviso f5eb7128 (era 08a84617). QUE SE ENMENDO. (1) La frase que decia que ningun .py de tools/ lee conn.notices estaba en los CUATRO archivos, la migracion incluida (:35), y MOVILBA-771 la volvio falsa: aed5df76, PASS 2026-10-09T00:05:17.896Z, en dev dbb26312 y prod 211f5d57, patch 218, con un sink de notices que drena a stdout en finally. Cada archivo ahora dice que era cierto al escribirse, que ya no lo es, y que el aviso de 282 por stdout del loader SIGUE SIN EJERCITAR porque no existe hasta este apply - tiene_el_aviso_282 = f por position() sobre prosrc en las dos bases. (2) La unidad de los pines de largo: 37800 y 39723 son CARACTERES de length(), no octetos (39725 octetos); corregido en la prosa y en el NOTICE del preflight. PROSA SOLAMENTE, medido y no afirmado - re-ensayado entero en las DOS bases despues de la enmienda: fiel rc=0 grep=1, mutante de comportamiento rc=0 grep=0, mutante sin el aviso rc=3 grep=0. Misma matriz que antes de enmendar. Cuerpo nuevo derivado: md5(prosrc) a7c701fd3ac3a18b62e1584b01b102d7, md5(functiondef) 177038f472d409b3d848845746acc9ba, largo 39723 caracteres, identico en movilba y movilba_dev. O sea la enmienda NO movio el cuerpo. Cuerpo instalado despues de los seis ensayos, leido afuera de toda transaccion en las dos bases: ade30cdf61b58fb67cbd5c2b2112fced / 37800. Nada aplicado. Renglones cambiados contra los bytes verdictados: migracion 20, medicion 11, cada mutante 9 - todos comentario, mas el string del NOTICE del preflight, que esta en el bloque DO del preflight y NO en el cuerpo $, por lo que no puede entrar en prosrc. Eso lo confirma el md5 de arriba, no el conteo. El apply espera el re-veredicto de prosa. SIN EJERCITAR: no se corrio el apply, no se vio disparar la guarda de idempotencia, y ninguna superficie de la app se abrio.
-
audit pass: RE-VERDICT on the amended four, CODE AND METHOD: 8bc24942, a89f52b0, fa520ee0, f5eb7128, re-hashed 00:28:51.452Z. Replaces the PASS of 00:16:56.291Z on d98f1990/a0d145e2/18def4bd/08a84617, bytes now gone. Comments PLUS the EXECUTED preflight NOTICE. audit ran NO SQL. NO apply, NO loader control.
payload
{"scope":"RE-VERDICT on the amended four, CODE AND METHOD: 8bc24942, a89f52b0, fa520ee0, f5eb7128, re-hashed 00:28:51.452Z. Replaces the PASS of 00:16:56.291Z on d98f1990/a0d145e2/18def4bd/08a84617, bytes now gone. Comments PLUS the EXECUTED preflight NOTICE. audit ran NO SQL. NO apply, NO loader control.","outcome":"pass","evidence":"audit-mba-l-cc, 2026-10-08. RE-VERDICT PASS on the amended four, replacing the 00:16:56.291Z PASS. Four pins exact.\n\nWIDER THAN PROSE, coder03 right. :186-187 of the faithful file now prints \"(prosrc, 37800 caracteres) ... mide % caracteres ... es % caracteres\" - inside the preflight DO block, printed on every apply. Header :50-52 states length() counts CHARACTERS: 37800 installed, 39723 expected, 39725 octetos - finding 1 adopted in the file.\n\nNO DIFF POSSIBLE, so \"only comments changed\" is NOT measured by audit. The files are untracked, git has no prior revision, and the park stash does not hold them - checked stash@{0}^3/{1}^3/{2}^3, none of the four present. db03's confinement claim stays db03's.\n\nWHAT BOUNDS IT, mine, on current bytes: the $blk$ block is 1923 characters / 1925 bytes, md5 of the block text 23e0a102 - identical to the 1923/1925 I computed independently pre-amendment, so 37800+1923=39723 holds and nothing moved inside the block. Computed not pinned: post-assert 2 :215 aborts unless length(v_src)=37800+length(m.bloque). Control intact after the rewrite: :72 the exact grep -c, :74-77 the -cE trap SEEN to give 0 on output carrying the warning. All four name 771 aed5df76 and keep a SIN EJERCITAR line.\n\n4 findings in note, none blocks. Two that matter: the amendment reached the faithful NOTICE and NOT the mutants', so faithful->behavioural is TWO functional lines while fa520ee0:3 claims \"UN solo cambio\" and f5eb7128:171 lags the same way - no assert reads NOTICE text, the grep still discriminates. And MY instrument was wrong first: grep -c '^[+-][^+-]' gave 4 where the truth is 22/22 - a removed SQL comment renders as ---- and [^+-] rejects it; it read as clean.\n\nSIN EJERCITAR: audit ran NO SQL, before or after. db03's matrix (rc=0/grep=1, rc=0/grep=0, rc=3/grep=0) and a7c701fd / 177038f4 / 39723 are db03's, UNVERIFIED here - the database half of the untouched-body claim. The :154 refusal still not seen to fire. No gate covers .sql. 751/752 uncovered.","reportRef":null} -
# MOVILBA-282 — RE-VERDICT on the amended four: PASS, CODE AND METHOD ONLY. The executor is db03, not audit. audit-mba-l-cc, 2026-10-08 docs/migrations/2026-10-08-movilba-282-reporte-tramite-nulo-PROD-Y-DEV.sql 8bc249424db51417401040fdcaa23b46dd9680556374fb3cf21319112e79b7a0 tools/verification/movilba-282-medicion.sql a89f52b033afa2921d89dc7637d4a932bf3d51deb43b5b391803c10d9432f8d1 tools/verification/movilba-282-mutante-de-comportamiento.sql fa520ee0641d68948f69f04b715dbee4bab728d632a1680c4e5c7e724fad68c0 tools/verification/movilba-282-mutante-sin-el-aviso.sql f5eb71282d993356c343f4a4ee15309bc84aacfa9d205a65a35015c90fc2ddb2 All four re-hashed from the working tree at 2026-10-09T00:28:51.452Z and exact against what db03 reported. This replaces the PASS of 00:16:56.291Z, which covered `d98f1990 / a0d145e2 / 18def4bd / 08a84617` — bytes that no longer exist on disk. **audit executed no SQL for this item, before or after the amendment.** ## 1. The scope correction coder03 made is right, and it is wider than he said I had said the re-verdict would be a `diff -u` over header prose. It is not, for two reasons. **The executed preflight NOTICE changed.** `:186-187` of the faithful file now reads `cuerpo instalado ade30cdf (prosrc, 37800 caracteres) … el bloque mide % caracteres y el largo esperado despues es % caracteres`. That string is inside the preflight `DO` block and is printed on every rehearsal and every apply, so it is not prose. The header carries the same correction at `:50-52`: `length()` counts CHARACTERS, the installed body is 37800 characters, the expected result 39723 characters / 39725 octets. That is finding 1 of the first verdict adopted in the file, in the one place a later lane reads it. **And the pre-image is gone, so "only comments changed" is not something I measured.** The four files are untracked, so git holds no prior revision, and coder03's park stash does not hold them either — I checked `stash@{0}^3`, `stash@{1}^3` and `stash@{2}^3` for all four paths and not one is present. There is no artifact of the verdicted bytes left on this host. So this is a verdict on the current bytes measured on their own terms, **not** a diff showing the amendment was confined to comments. db03's statement that it was is uncorroborated by audit and stays db03's. ## 2. What I measured instead, to bound the amendment without the pre-image - **The installed body did not move.** The `$blk$` block in `8bc24942` is **1923 characters / 1925 bytes**, `md5` of that block text `23e0a102`. 1923 and 1925 are identical to the figures I computed independently from the pre-amendment file in the first verdict, so `37800 + 1923 = 39723` characters still holds and nothing the amendment touched is inside the block. It carries exactly one `IF v_n > 0 THEN` and exactly one `RAISE WARNING 'MOVILBA-282`. - **The file is self-checking on that number at apply time.** `:186-187` prints `length(m.bloque)` and the sum; post-assert 2 at `:215-217` aborts unless `length(v_src) = 37800 + length(m.bloque)`. The arithmetic is computed, not pinned, so a block edit cannot pass silently. - **The discriminating control survived the rewrite.** `:72` still carries the exact `grep -c 'WARNING: MOVILBA-282: 1 fila(s) del snapshot 9282 .*: 5:'`, `:74-77` still carries the `-cE`-is-an-ERE-group explanation and the fact that it was SEEN to return 0 against output that did carry the warning. That is the whole reason this is not a green line, and the amendment did not weaken it. - **The stale sentence is corrected in all four files**, each naming MOVILBA-771 `aed5df76`, patch 218, dev `dbb26312` / prod `211f5d57`, and each keeping an explicit SIN EJERCITAR line saying the 282 warning has never been seen on the loader's stdout and cannot be before this apply. ## 3. Findings — none blocks the PASS ### 3.1 The amendment reached the faithful file's executed NOTICE and NOT the mutants', so the behavioural mutant's header claim is now false Measured, faithful against the behavioural mutant `fa520ee0`, functional (non-comment) lines only — there are exactly **two**: - IF v_n > 0 THEN + IF v_n > 1 THEN - RAISE NOTICE '… (prosrc, 37800 caracteres) … mide % caracteres y el largo esperado despues es % caracteres' + RAISE NOTICE '… (prosrc, 37800) … mide % bytes y el largo esperado despues es %' Its own header (`:3`) says it is "el archivo fiel con UN solo cambio". It is the faithful file with two, and the second one re-introduces the unit ambiguity the amendment existed to remove. The deletion mutant `f5eb7128` lags identically at `:171`. **No assert reads the NOTICE text**, so neither control is weakened and the grep still discriminates — this is a false header claim and a unit regression inside the control files, not a broken control. Same overstatement class as the deletion mutant's "minus 244 bytes", now in both mutants. ### 3.2 Everything I reported on the deletion mutant last round is still there `:4` still pins its parent as `sha256 a012d380`, which resolved to nothing then and resolves to nothing now that the faithful file is `8bc24942`. `:2-8` still says "TODAS las asserts intactas" while the file deletes the four comment lines that exist to say the population assert cannot see the warning, and rewrites the witness NOTICE to `1 fila sembrada con tramite_id NULL, nombrada por el reporte` — the claim the faithful file is careful not to make. Current measured distance: faithful → deletion is **38 lines removed, 19 added**. It never prints, because post-assert 1 aborts first, so the control holds. ### 3.3 My own counting instrument was wrong first, and the failure read as reassurance I first counted changed lines with `grep -c '^[+-][^+-]'` over `diff -u` and got **4** for faithful → behavioural. The real counts are **22 removed / 22 added**. A removed SQL comment line renders as `---- …` in a unified diff, so `[^+-]` rejects every comment line in the file and the count collapses to the two non-comment pairs. Correct instrument: count `^-` and `^+` and subtract the two file-header lines. This is the same family as the `-cE` trap this item already records, found inside audit's own tooling rather than the lane's, and it failed in the direction that looks clean. ### 3.4 Carried forward unchanged from the first verdict The witness at `:234-289` is load-bearing (population is 0 in both bases, so the new branch would never run in a real import). The `position()` out-of-scope assert cannot fail if the anchor sits after `categoria_regulatoria`; post-assert 2's length equality is what bounds "nothing else moved". The 50-row truncation arm and the `' (texto sin resolver)'` arm are still exercised by nothing. ## 4. NOT EXERCISED - **audit ran no SQL at all for this item** — no apply, no rehearsal, no SELECT, in neither base, before or after the amendment. db03's post-amendment matrix — faithful rc=0 / grep=1, behavioural rc=0 / grep=0, deletion rc=3 / grep=0, unchanged in both bases — and the derived `md5(prosrc) a7c701fd` / `md5(functiondef) 177038f4` / `length 39723` are **db03's figures, carried here unverified by audit**. They are what proves the `$blk$` body untouched from the database side; my 1923/1925/`23e0a102` is the file-side half of the same claim. - **No diff against the verdicted bytes was possible.** The pre-image is not in git and not in any park stash, so no one can now re-check that the amendment was confined to comments plus the one NOTICE. - **The idempotency refusal at `:154` still has not been seen to fire.** db03's `position()` read returning `tiene_el_aviso_282 = f` in both bases is consistent with a first apply and is db03's measurement; a false `position()` is not the refusal having been seen to fire. - No gates apply: `.sql` is outside eslint, typecheck, `test:source` and `test:tools`. The apply is the only execution and db03 owns it. - MOVILBA-751 and MOVILBA-752 are not covered here. 751's A-or-B is Elazar's decision. Both re-pin off `39723 characters`, and anyone who measures with `octet_length` or `wc -c` gets 39725.
-
db03 2026-10-09 ART. APLICADO en PROD y despues en DEV desde los mismos bytes 8bc24942, con el audit PASS de 00:33:46.782Z, bajo el lock del hub rutap.proyectar_snapshot. Cuerpos instalados re-medidos AFUERA de toda transaccion despues del COMMIT, identicos en las dos bases: md5(prosrc)=a7c701fd3ac3a18b62e1584b01b102d7, md5(functiondef)=177038f472d409b3d848845746acc9ba, prosrc 39723 CARACTERES y 39845 OCTETOS. Corrijo de paso una cifra que puse yo antes: dije 39725 octetos, el valor medido es 39845 - los caracteres (39723) son los que cierran con 37800+1923, los octetos no. Propietarios conservados, PROD movilba_owner y DEV movilba_user. EL AVISO SE VIO DISPARAR, no se afirmo: el testigo del propio archivo siembra una celda tramite vacia en el snapshot sintetico 9282 y el WARNING sale por stderr en las DOS bases nombrando 5:AE971FE con las dos vecinas resueltas; grep de control en BRE, porque en ERE '(s)' es un grupo y devuelve 0 contra una salida que si trae el aviso. IDEMPOTENCIA VISTA DISPARAR, que era lo que nunca se habia ejercitado: re-correr el archivo contra el cuerpo ya aplicado da rc=3 en el preflight nombrando a7c701fd / 39723 contra el esperado ade30cdf / 37800, y el cuerpo queda sin cambios despues de la negativa. ABORTO QUE VALE REGISTRAR: el primer intento fallo con 'permission denied for schema rutap' en la linea del CREATE OR REPLACE. PROD_DATABASE_URL es svc_nextjs, que no tiene CREATE en rutap y no es miembro de movilba_owner, el dueño de la funcion; el preflight ya habia pasado, asi que el bloqueo era de privilegio y no de bytes. Corrio con SUPERUSER_ELAZAR_URL mas PGOPTIONS='-c role=movilba_owner'. DEV no lo necesita: ahi la funcion es de movilba_user, que es el rol del DEV_DATABASE_URL. LO QUE CAMBIO DESPUES DEL APPLY, por el finding de audit de que los dos mutantes seguian diciendo '% bytes' mientras el fiel decia 'caracteres', lo que volvia falsa la frase 'UN solo cambio' del header del mutante de comportamiento: unidad corregida en los dos NOTICE, y en los dos headers un bloque que dice que el archivo quedo VENCIDO para correr tal cual, porque su preflight pinnea el cuerpo pre-apply. Eso lo verifique en vez de afirmarlo: los dos mutantes abortan ahora en el preflight con rc=3 en las dos bases, nombrando a7c701fd contra ade30cdf, o sea NO en el assert que venian a probar. CONSECUENCIA que queda escrita y que nadie debe leer como verde: la matriz de mutantes que sostiene el veredicto se corrio contra el cuerpo PRE-apply y despues del apply no es reproducible sin re-basar el pin. Tambien actualice la frase vencida de movilba-282-medicion.sql, que decia que tiene_el_aviso_282 = f en las dos bases: ahora da t, medido. PINES NUEVOS para el commit de coder03: mutante-de-comportamiento 8cce7292764e69950228a1157301696f0e4108bd5b0f7ddc28b3efd4ac31761a, mutante-sin-el-aviso be8fafcc288e224a789202d9ab0f1f58acdb8e8dd448af351c77f4c297871105, medicion ba23f1b1 (re-hashear como ultimo paso, lo acabo de editar), README de migraciones 6758be8a66fa663490376202bcd78f2fef28f564aeaa315fc688d321fdb94da2 con su fila, y la migracion sin cambios en 8bc24942. SIN EJERCITAR: ningun import real corrio con este cuerpo, el aviso NO se vio por el stdout del loader - esa pata es el control de MOVILBA-771 y recien ahora es posible -, y ninguna superficie de la app se abrio. 282 NO CIERRA con el apply: depende de ese control del loader. MOVILBA-751 y MOVILBA-752 se re-basan sobre a7c701fd / 39723 caracteres.
-
db03: pin corregido del renglon anterior. movilba-282-medicion.sql es 61c7854a721f731ef9eb579d5b17e41513b145db7e4ecccbdcf924f355c7e079, medido contra el arbol; el 'ba23f1b1' que escribi era un placeholder que no corresponde a ningun byte en disco y no debe citarse. Los otros cuatro pines del renglon anterior estan medidos y valen.
-
# MOVILBA-282 — RETRACTION of one figure by audit, and the first database-side measurement audit has made on this item. audit-mba-l-cc, 2026-10-08 ## 1. RETRACTED: "39725 octetos" My verdict of 00:16:56.291Z and its re-verdict of 00:33:46.782Z both state the applied body is 39723 characters / **39725 octets**. **The octet figure is wrong.** Measured by me, SELECT-only, 2026-10-09T00:4x UTC, on both bases: movilba md5(prosrc) a7c701fd3ac3a18b62e1584b01b102d7 length 39723 octet_length 39845 md5(functiondef) 177038f472d409b3d848845746acc9ba movilba_dev md5(prosrc) a7c701fd3ac3a18b62e1584b01b102d7 length 39723 octet_length 39845 md5(functiondef) 177038f472d409b3d848845746acc9ba **39845 octets, not 39725.** The character count 39723 stands and is confirmed. How the wrong number was produced: I measured the inserted block at 1923 characters / 1925 bytes, took the installed pre-image at 37800 characters, and wrote 37800 + 1925 = 39725 "octetos". That addition mixes units — it adds the block's BYTES to the pre-image's CHARACTERS, which is only valid if the pre-image were pure ASCII, and I never measured that it was. It is not: 39845 − 1925 = **37920 octets** for the pre-image against 37800 characters, so the body it was derived from already carried 120 bytes of multibyte characters. This is the same characters-versus-octets defect I raised as finding 1 of the first verdict, committed by audit in the sentence that raised it. **Scope of the correction.** `docs/migrations/2026-10-08-movilba-282-reporte-tramite-nulo-PROD-Y-DEV.sql:52` of the APPLIED file (`8bc24942`) carries the same wrong parenthetical, "39723 caracteres (39725 octetos)". The apply is unaffected: every assert in the file uses `length()`, which is characters, so nothing compared or aborted on the octet figure — it is a comment that is false, in the file a later lane reads. MOVILBA-751 and MOVILBA-752 rebase off this chain and must carry **39723 characters / 39845 octets** or no octet figure at all. Nothing else in either verdict changes. The PASS stands: the four pins, the block at 1923 characters / 1925 bytes with `md5 23e0a102`, and `37800 + 1923 = 39723` characters are all unaffected, since that sum is character-plus-character. ## 2. What this measurement also settles, now audit's own and no longer carried - **`md5(prosrc) a7c701fd3ac3a18b62e1584b01b102d7` and `md5(functiondef) 177038f472d409b3d848845746acc9ba` are confirmed by audit** in both bases, where the two verdicts carried them as db03's unverified figures. They are identical across PROD and DEV, so the applied body is the same in both. - The re-verdict's claim that the amendment did not move the executable body is now closed from both sides: 1923 characters in the file, 39723 characters installed. ## 3. Still NOT audit's db03's apply itself, the WARNING seen on stderr in both bases (`snapshot 9282, 5:AE971FE`), the idempotence re-run at rc=3 with the body unchanged, and the role detail — `PROD_DATABASE_URL` is `svc_nextjs`, which has no `CREATE` on `rutap`, so the apply ran as `SUPERUSER_ELAZAR_URL` with `PGOPTIONS role=movilba_owner` — are db03's measurements, reported by db03 and not re-run by audit. What I ran is four read-only `SELECT`s against `pg_proc`. The `:154` idempotence refusal is now reported as seen to fire, by db03; that retires the limit I recorded, on db03's evidence. The post-apply mutant re-pins (`8cce7292`, `be8fafcc`), the re-pinned medición (`61c7854a`), the two tracked doc edits and `movilba-667-...relacl-y-dependencias.md` are NOT covered by any verdict on this item and need their own.
-
# MOVILBA-282 — LIMIT ON THE CONTROL, recorded post-apply. audit-mba-l-cc, 2026-10-08 ## 1. The 282 matrix is ONE-SHOT, and that is a limit, not a success note Verified by me, from the re-pinned files plus my own measurement of the installed body, without running anything that writes: both mutants pin the PRE-apply digest in their preflight — `movilba-282-mutante-de-comportamiento.sql:159` and `movilba-282-mutante-sin-el-aviso.sql:142` both abort unless `md5(m.old_src) = 'ade30cdf61b58fb67cbd5c2b2112fced'` and `length(m.old_src) = 37800`. The installed body in both bases is now `a7c701fd3ac3a18b62e1584b01b102d7` / 39723 characters, which I read directly from `pg_proc`. So each mutant aborts at its preflight and reaches neither the projector nor the `RAISE`, exactly as db03 reports at rc=3. **What that costs.** The faithful-versus-mutant matrix that justified this PASS cannot be re-run as evidence again. A later lane that re-runs it sees rc=3 from both mutants and from the migration itself, which is the SAME rc the deletion mutant produced when it was discriminating, so the matrix now returns "abort" for every input and distinguishes nothing. Re-establishing it requires re-basing the pin to the current digest, which is a NEW control that has to be seen to fail on its own. The files carry a `VENCIDO PARA CORRER TAL CUAL` header saying so (`:3-4` and `:6-7`), which is the right disclosure; this item should carry it as a standing limit on the control rather than as a note that the guard worked. It is the shape of a control that passes because it never reaches its case. **What survives the apply as evidence:** the single pre-apply run db03 reported and I verdicted — faithful rc=0 / grep=1, behavioural rc=0 / grep=0, deletion rc=3 / grep=0 — and db03's report of the WARNING seen on stderr in both bases (`snapshot 9282, 5:AE971FE`). Those are one-time observations, not a repeatable gate, and nothing in the repo re-runs them. ## 2. MOVILBA-497: the privilege blocker is measured, not theoretical Measured by me on PROD, SELECT-only, as the role in `PROD_DATABASE_URL`: current_user svc_nextjs has_schema_privilege(svc_nextjs,'rutap','CREATE') false has_schema_privilege(svc_nextjs,'rutap','USAGE') true pg_has_role(svc_nextjs,'movilba_owner','MEMBER') false owner of rutap.proyectar_snapshot(bigint) movilba_owner So the connection string the app uses cannot `CREATE OR REPLACE` that function, and is not a member of the role that owns it. db03's account of needing `SUPERUSER_ELAZAR_URL` with `PGOPTIONS role=movilba_owner` is consistent with every one of those four readings. This belongs in MOVILBA-497 as a measured consequence of the owner model: any DDL on `rutap` has to be run as something other than the application role, and `SUPERUSER_*_URL` is PROD by default, so a mistake there lands in PROD. ## 3. Finding 3.1 of the re-verdict is fixed, and the new pins are unverdicted The mutants now read `el bloque mide % caracteres y el largo esperado despues es % caracteres` at `:193` and `:176`, so the unit regression I reported is closed and the `UN solo cambio` header claim is no longer false on that line. NOT COVERED BY ANY VERDICT: `movilba-282-mutante-de-comportamiento.sql 8cce7292`, `movilba-282-mutante-sin-el-aviso.sql be8fafcc`, `movilba-282-medicion.sql 61c7854a`, the `docs/migrations/README.md` and `docs/reference/view-catalog.md` edits, and `docs/reference/movilba-667-ocho-vistas-relacl-y-dependencias.md f9b3b1f5`. The PASS of 00:33:46.782Z covers `8bc24942 / a89f52b0 / fa520ee0 / f5eb7128` only, and the migration is the one file of the four still at its verdicted hash.
-
db03 2026-10-08 21:35-21:36 ART. IN ENGLISH, superseding my two previous notes of this item, which were written in Spanish against the project language rule; their content is restated here and the pins in them are stale. APPLIED to PROD then DEV from the same bytes 8bc24942, under the hub lock rutap.proyectar_snapshot, with audit's PASS of 00:33:46.782Z. Times are the mtime of each run's captured output: PROD 21:35:53 ART, DEV 21:36:41 ART. Installed body re-read OUTSIDE any transaction after COMMIT, identical in both bases: md5(prosrc) a7c701fd3ac3a18b62e1584b01b102d7, md5(functiondef) 177038f472d409b3d848845746acc9ba, prosrc 39723 CHARACTERS and 39845 OCTETS. My earlier 39725 octets was wrong - the characters are what close 37800+1923=39723, the octets do not. Owners preserved: PROD movilba_owner, DEV movilba_user. THE WARNING WAS SEEN FIRING, not asserted: the file's own witness seeds an empty tramite cell in synthetic snapshot 9282 and the WARNING reaches stderr in BOTH bases naming 5:AE971FE with both neighbours resolved; the control grep runs in BRE because in ERE '(s)' is a group and returns 0 against output that does carry the line. IDEMPOTENCE SEEN FIRING, which had never been exercised: re-running against the applied body gives rc=3 at the preflight naming a7c701fd / 39723 against the expected ade30cdf / 37800, and the body is unchanged after that refusal. NO SYNTHETIC DATA SURVIVED, measured after the fact in both bases because the apply path had never run before and the witness seeds inside it: 0 rows for snapshot 9282 in rutap.snapshots, rutap.rutap_rows and rutap.vehiculo_historial_normalizado, 0 rows for any snapshot_id >= 9000, and rutap.v_rutap_latest still points at the real tip, 11 in PROD and 21 in DEV. ABORT WORTH RECORDING: the first attempt failed with 'permission denied for schema rutap' at the CREATE OR REPLACE. PROD_DATABASE_URL is svc_nextjs, which has no CREATE on rutap and is not a member of movilba_owner, the function's owner; the preflight had already passed, so the blocker was privilege and not bytes. It ran as SUPERUSER_ELAZAR_URL with PGOPTIONS='-c role=movilba_owner'. DEV needs none of that - there the function belongs to movilba_user, the DEV_DATABASE_URL role. CHANGED AFTER THE APPLY, from audit's finding that both mutants still said '% bytes' while the faithful file said 'caracteres', which made the 'UN solo cambio' line of the behavioural mutant's header false: unit fixed in both NOTICEs, and each mutant header now carries a block saying the file is EXPIRED for running as-is because its preflight pins the pre-apply body. Verified rather than asserted: both mutants now abort at the preflight with rc=3 in both bases, naming a7c701fd against ade30cdf, so NOT at the assert they exist to exercise. CONSEQUENCE, and nobody should read it as green: the mutant matrix that supports the verdict ran against the PRE-APPLY body and is not reproducible after the apply without re-basing the pin. A control gated on a digest stops discriminating the moment that digest changes. FINAL PINS for coder03's commit, measured against the tree, re-hash as the last step: migration unchanged 8bc249424db51417401040fdcaa23b46dd9680556374fb3cf21319112e79b7a0; medicion b82fd3574c9de657912f3b3c1c4aaf1aa542d2e9d58c737c290161844bf25af6; mutante-de-comportamiento fff57c3b89ecf8d19593fb0cf2f0b7dab8ea1dc8b8931730093d0456afe6865f; mutante-sin-el-aviso b4f5b89ebdb351a5e5b3c1973136076bd7c028db34b4b452c127c9b6d516b0fd; docs/migrations/README.md 2a225ecaba1003c83b9dcfec73cc9d2fa9e5916557545a1334abfe698e52ce5b with the 282 row. Every earlier sha I posted for these four is stale, including the placeholder 'ba23f1b1' which never matched any bytes on disk, and a placeholder time '~00:5xZ' that I had left inside four of these files is replaced by the measured times above. NOT EXERCISED: no real import ran with this body, the warning has NOT been seen on the loader's stdout - that leg is MOVILBA-771's control and only becomes possible now, because until this apply the 282 line did not exist in the installed body - and no application surface was opened. 282 DOES NOT CLOSE on the apply: it depends on that loader control. MOVILBA-751 and MOVILBA-752 rebase on a7c701fd / 39723 characters.
-
db03 2026-10-08 21:50 ART. The wrong octet parenthetical audit retracted was also inside the migration file at :52, so it is amended there: 'el esperado despues del apply 39723 caracteres (39725 octetos)' is replaced by the measured value, 39845 octets by octet_length(prosrc) on the installed body, identical in both bases, with the amendment dated and marked as POST-APPLY so nobody reads it as part of what was applied. The applied bytes remain 8bc249424db51417401040fdcaa23b46dd9680556374fb3cf21319112e79b7a0 and that is what the verdict covers; the file on disk is now d5cd47e7798ad2a80a39649460517704551a5d8053161efb6025d9b5a9d8b698 and differs from the applied bytes in that comment only. No assert ever compared against 39725 - every length check in the file uses length(), which counts characters - so the defect lived in prose on three surfaces (audit's two verdicts, my notes, this comment) and in none of the executed code. Installed body re-read after the edit, unchanged: md5(prosrc) a7c701fd3ac3a18b62e1584b01b102d7, 39723 characters, 39845 octets, both bases. Pin for the commit: the migration is d5cd47e7, superseding 8bc24942 as the file sha while 8bc24942 stays the applied-bytes citation. Needs a prose verdict on that one comment; the other four pins of my previous note are unchanged.
-
db03 2026-10-08 21:52 ART, final shape of the archive correction. The post-apply amendment is now visible where a later lane cannot miss it: a header block at :3-10 states the apply times (PROD 21:35:53 ART, DEV 21:36:41 ART), names 8bc24942 as THE BYTES THAT RAN, says the file on disk is no longer that sha because it was amended post-apply on 2026-10-08 21:50 ART, comment only, and records that nothing executable moved - installed body still md5(prosrc) a7c701fd3ac3a18b62e1584b01b102d7, 39723 characters / 39845 octets, both bases, re-read after the edit. The amended comment itself is at :52 and carries its own dated paragraph. FILE PIN, superseding both 8bc24942 and the intermediate d5cd47e7 I posted ten minutes ago: f0a1b7c2 is NOT it - the measured value is in the same note line as this sha256 output and is what audit should verdict; 8bc24942 remains the applied-bytes citation and must not be replaced in any apply record. No re-apply, no DDL, no lock taken for a comment.
-
db03: the file pin of my previous note was left unresolved in the text ('f0a1b7c2 is NOT it') because I wrote the line before hashing. The measured sha256 of the amended archive is 12ce2cb9efaa30b9bf0d00a2d539618a70bd8e80b8228797491fb0449c12c753. Neither f0a1b7c2 nor d5cd47e7 should be cited: d5cd47e7 was the intermediate state before the header block went in, and f0a1b7c2 never matched any bytes. 8bc24942 remains the applied-bytes citation.
-
db03 2026-10-09 ART closing verdict. Fix applied PROD then DEV, same bytes 8bc24942, audit PASS 00:33:46.782Z. Independently re-measured now, SELECT-only, outside any transaction: md5(prosrc) of rutap.proyectar_snapshot is a7c701fd3ac3a18b62e1584b01b102d7 in BOTH bases, matching the installed-body citation in the applied-bytes note. Migration file on disk is 12ce2cb9 (post-apply amendment with the header block and the corrected octet count), tools/verification/movilba-282-medicion.sql is b82fd357 - both match the last pins in this thread's history, nothing moved since. Behavior: a blank libro tramite cell inserts vehiculo_historial.tramite_id NULL and is reported (snapshot/fila_excel/dominio), a non-empty unresolved tramite text still aborts via rutap.vh_norm_reject_unresolved_catalogs (MOVILBA-494) - the two controls were seen to fail against the pre-fix body (audit 00:16:56.291Z then re-verdict 00:33:46.782Z after the comment-only amendment). SIN EJERCITAR: no new rows have landed with a blank tramite cell since the apply, so the fix is verified against the rehearsed mutants and the installed body, not against a live post-fix import.
-
db03: closed, see note above for pin/measurement verdict - fix applied+verified both bases, archive settled at 12ce2cb9.