movilba
MOVILBA-59
· child of MOVILBA-13 Política: PROD replica el snapshot RUTAP vigente en PostgreSQL Deferred
Import RUTAP no reproducible de punta a punta: fuente/DSN/apply manuales y conciliacion solo en salida del operador
In progress normal
dmdb04-mba-l-ca
Hallazgo de audit via coder02-mba-l-cc 2026-08-20, fuera de alcance de MOVILBA-23 a proposito. Hoy un snapshot RUTAP llega a Postgres cruzando tres conversores con semanticas incompatibles (tools/rutap-snapshot-import.py, tools/rutap-snapshot-to-postgres.py, tools/import/convert_parque_rutap.py) mas handoffs manuales entre xlsx, sqlite y Postgres. Eso es exactamente como el snapshot del 08-13 llego a prod por un camino que no quedo en el repo. Objetivo: un solo camino declarado, con manifiesto que se arrastre por todas las etapas, para poder re-derivar Postgres desde el xlsx sin conocimiento tribal. NO incluye cambiar la semantica de ningun conversor sin ticket propio.
Activity
-
parent=#2590
-
Merged from canceled MOVILBA-60 (coder02): third converter is tools/import/convert_to_psv.js, not just convert_parque_rutap.py - so the fleet is rutap-snapshot-import.py + rutap-snapshot-to-postgres.py + convert_parque_rutap.py + convert_to_psv.js. Audit's two asks: (1) one canonical contract-driven importer, (2) source-hash identity carried through all stages so any agent can prove which xlsx a Postgres row came from. 60 canceled, 59 is the survivor.
-
db03-mba-l-ca / db
-
STILL OPEN, verificado en el repo por db03-mba-l-ca 2026-08-21 08:11. Siguen conviviendo 4 caminos independientes de conversion/import de RUTAP: snapshot-import, snapshot-to-postgres, convert_parque_rutap y convert_to_psv. No hay un camino canonico unico que lleve manifiesto. Nota: el ticket dice 3 conversores y son 4. Se cruza con MOVILBA-110 - si rutap.snapshots quedo atras es justamente porque la carga al schema rutap es uno de esos caminos y nadie es duenio de correrlo.
-
PARTIAL AUDIT (db03-mba-l-ca, read-only, no DB/repo write): FIXED/VERIFIED: exactly one active XLSX importer (tools/rutap-snapshot-import.py); the 3 incompatible converters are archival, no live caller. Fresh isolated import of snapshot5 XLSX reproduced the stored snapshot exactly: 5258 rows, 25 CUITs, identical MD5 e26935d0ec45bc7b283f5c2c51fd8acd. rutap-sync-prod.sql now gates every open domain at exactly one open row - the former silent max() ambiguity is closed. REMAINING BLOCKERS (pipeline still not reproducible end-to-end): 1. v_rutap_latest selects by fecha_descarga (derived from filename or manual --fecha), not an approved immutable snapshot ID/hash. 2. SQLite->Postgres needs manual --snapshot; the sync step separately reads whatever v_rutap_latest is at that moment, with no run manifest tying XLSX MD5, SQLite id, PG id, and reconciliation result together. 3. Importer has no required-column/schema-contract or duplicate-natural-key gate - accepts evolving columns, can load a malformed shape. 4. sync's faltantes_esperados override still permits a knowingly incomplete production reconciliation. RECOMMENDED TARGET: one orchestrator/run manifest that takes XLSX + approved source identity, validates required fields/keys, stages SQLite->PG by the same hash, runs reconciliation against an explicit snapshot ID in one recorded run, emits post-commit parity.
-
coder-mba-l-ca / coder
-
Elazar 2026-08-27: remove SQLite from the operational path; direct XLSX -> immutable PostgreSQL rutap snapshot -> MovilBA transformation/reconciliation. Existing date-based latest selection stays; no quarantine policy and no speculative header redesign for unchanged headers.
-
Verified snapshot 5->6: same 53-column Base shape, no additions/removals; snapshot 6 has 0 domains with multiple open rows. Items 1-4 are closed as non-issues for this import. Work starts on direct PostgreSQL ingestion.
-
Snapshot 7 operational DEV apply committed and independently verified: 4 vehicles, 4 VDC, 8 VDC corrections, 20 history rows; AF875JB excluded. Remaining work: audit/commit/deploy reproducible importer, planner, sync safety and documentation artifacts.
-
Snapshot-7 pipeline completed: direct PG import, reproducible source-bound planner/apply, strict nonzero failure guards and documentation shipped to DEV as e4bd406c (v5.4.68). DEV operational apply and independent post-apply audit passed; AF875JB remains intentionally excluded pending authoritative correction.
-
ALCANCE DEL CIERRE (db02-mba-l-cc 2026-08-28, con respuesta explicita de db-mba-l-ca que corrio la validacion). El item quedo en done, pero la validacion de snapshot 7 NO cierra la auditoria de db03-mba-l-ca del 08-26. Palabras de db-mba-l-ca: snapshot 7 solo cerro el pin de snapshot en runtime y los invariantes del planner PARA ESA CORRIDA en DEV (5257 filas fuente, 39 acciones planificadas, rollback read-only); NO cierra (1) el manifiesto que ate MD5 del XLSX con el snapshot_id de Postgres, (2) el contrato de columnas requeridas, (3) el gate de clave natural duplicada, ni (4) la politica de faltantes_esperados que todavia permite una reconciliacion a produccion sabidamente incompleta. Y no tomo ninguna decision que cerrara alguno de esos cuatro: siguen abiertos por falta de codigo, no por acuerdo. Ademas: el SHA 423342f2...9768 citado en el cierre es el hash del archivo tools/rutap-reconcile-plan.sql antes de ejecutarlo - acredita QUE SCRIPT corrio, no sobre que datos corrio ni que plan emitio, asi que no sustituye al manifiesto del punto (1). Consecuencia practica: el objetivo declarado del ticket ('re-derivar Postgres desde el xlsx sin conocimiento tribal') NO esta alcanzado. Decision de PM/coder si esto reabre 59 o abre un sucesor; db02 no reabre item ajeno.
-
Reopened: snapshot-7 DEV apply and planner invariants passed, but the ticket objective remains incomplete. Pending canonical XLSX→Postgres run manifest binding source MD5, snapshot ID and reconciliation output; required-column and duplicate-natural-key gates; and removal/replacement of the faltantes_esperados path that permits knowingly incomplete reconciliation. AF875JB is not an exclusion; MOVILBA-78 owns that tie case.
-
coder-mba-l-ca confirma que no esta activo; owner del codigo del importer sigue siendo coder, db03 owna diseno/apply/evidencia de DB
-
PROPIEDAD NO ESCRITA DEL IMPORTER, medida el 2026-09-04 (db02, DEV snapshot 9). Anotarla ANTES de que alguien reescriba el pipeline. `tools/rutap-snapshot-import.py` **normaliza el NBSP (U+00A0) al stagear**. Cero NBSP llegan a `rutap.rutap_rows`: expte_baja 0, observaciones 0, linea 0. El libro SI los trae - el delta 09-03 -> 09-04 muestra AF023VE pasando de U+00A0 a vacio en `Expte. Baja` - o sea el caracter existe en el xlsx y muere en el staging. **POR QUE IMPORTA QUE ESTE ESCRITO:** en Postgres, `btrim` a secas NO saca U+00A0 (medido: `btrim(nbsp||'A'||nbsp)` da largo 3, y `btrim(chr(160))` NO es cadena vacia). Una celda con solo NBSP **pasa cualquier chequeo de vacio o de largo** y compara distinto contra todo. Hace falta la forma con charset: `btrim(x, ' '||chr(9)||chr(10)||chr(13)||chr(160))`. Si alguien reescribe esa normalizacion, la clase vuelve y el unico testigo es una celda que se ve no-vacia y no coincide con nada. **No es un pendiente: es una propiedad del importer que hay que preservar en cualquier reescritura, y un caso de test obvio.** CONTROL POSITIVO hecho: un NBSP sembrado se encuentra 1 de 1, y las columnas SI traen no-ASCII real (195 filas en expte_baja, 866 en observaciones: en-dash U+2013, acentos, grado), asi que el barrido llega al texto. El cero es un cero medido, no un cero por falta de entrada.
-
unassigned
-
2026-09-08 00:06 - APLICADO EN DEV (db03-mba-l-ca). Artefacto DEV-only docs/migrations/2026-09-08-movilba59-rutap-expedientes-DEV.sql, commit 72de6c5a, sha256 56e0a514b3bc3e5b9567115d58592d9d32988bd7007bae4f8ff5408f080ac63b, PASS de audit-mba-l-cc sobre esos bytes (DEV only: el guard fija movilba_dev/movilba_user). Rehearsal ROLLBACK PASS, apply COMMIT PASS en 10.9.10.54/movilba_dev como movilba_user, PG 15.17. rutap.rutap_expedientes creada con 8 columnas, owner movilba_user; importer INSERT=true; FK y unicidad snapshot/hoja/fila presentes; 3 indices. snapshots sin cambios (ids 9-11, next 12). Cobertura: las ramas ADD CONSTRAINT / SET NOT NULL NO se ejercitaron porque DEV ya tenia todo (medido por db02); el grant a svc_nextjs se salteo por rol ausente en DEV. Origen: el importer (tools/rutap-snapshot-import.py:334) rechazaba el snapshot 2026-09-07-2350 sin esta tabla; el artefacto 08-27 DEV-PROD (fb98924a...) quedo BLOCKED por audit (sin guard de entorno; 3 guards comparaban pg_get_constraintdef como texto). PROD sigue sin aplicar y necesita su propio corte + GO.
-
2026-09-08 00:07 - COBERTURA PARA EL CORTE PROD (db03): en DEV los ADD CONSTRAINT condicionales y el grant/check a svc_nextjs no se ejercitaron; los SET NOT NULL corrieron pero sobre columnas ya NOT NULL, asi que la transicion nullable->NOT NULL no se probo. El exito en DEV no valida esos caminos en PROD (PG 17.6). Antes de cualquier apply en PROD: corte PROD propio con guard movilba/svc_nextjs, validar rol y grants reales, GO de Elazar. Pendiente anotar en docs/migrations/pending-prod-changes.md (se agrupa con el proximo push de docs para no reiniciar dev01 por una linea).
-
db03-mba-l-cc
-
db04-mba-l-ca
-
2026-10-08 static census started; current converter inventory pinned at /data-lezama/movilba/evidencia/MOVILBA-59/2026-10-08-current-converter-census.md (sha256 e461aa50). No import or DB write; replacement design not begun.
-
2026-10-08 read-only static census, report /data-lezama/movilba/evidencia/MOVILBA-59/2026-10-08-current-converter-census.md sha256 e461aa50c06ff708124236c295f0049be661a1360e53847646d7a8564bcafecd. Current tree has ONE operational XLSX/CSV->Postgres importer (tools/rutap-snapshot-import.py aed5df76); xlsx-to-psv.ts 2cd9e73f and import/convert_parque_rutap.py e63fb1be are explicitly archival, with incompatible whitespace/pipe/type handling and no DB write. Historical rutap-snapshot-to-postgres.py is absent; SQLite bridge retired. MOVILBA-771 added a fourth output surface, PostgreSQL NOTICEs streamed to stdout on new-snapshot projection, not a persisted run manifest. File selection, date/DSN/apply and captured stdout remain manual. BWI title/description describe the historical three-converter route, not the current active route. No import run, DB query, semantics change or replacement design. Next measurement: pin one recent source file, snapshot row and operator-captured reconciliation/NOTICE output to determine what can actually be replayed after COMMIT.
-
Import RUTAP no reproducible de punta a punta: fuente/DSN/apply manuales y conciliacion solo en salida del operador
-
Retitled after 2026-10-08 census e461aa50: the old 'three incompatible converters' title was historical, not the live path. One direct importer is operational; two converters are explicitly archival; SQLite->PG bridge absent. Remaining measured gap is manual source/DSN/apply selection and reconciliation/NOTICE output not bound to a durable run manifest. No claim that the current import data path is broken. MOVILBA-773 takes priority before this item's next source/snapshot/output measurement.
-
2026-10-08 21:42 ART SELECT-only recent-run check: PROD snapshot 11 and DEV snapshot 21 both identify 2026-10-06-1140-parque-rutap.xlsx, 5558 Base rows, MD5 eb2e2683ccdd16a33be4a34b7b56088b; on-disk source MD5 matches. Scoped search of evidencia/import-reports found later analyses but no captured 06/10 importer stdout/stderr. Thus source and snapshot are re-identifiable, but original flags/version, reconciliation/NOTICE output and post-commit gate results cannot be reconstructed from retained evidence; absence claim is limited to searched paths. Report /data-lezama/movilba/evidencia/MOVILBA-59/2026-10-08-current-run-replayability.md sha256 ba8a5f015ddfedbdb5a20081522e0f0e3a9b989f45ab3a2b5291642b2e96e1e9. No import/write. Next: ask operator for any external transcript; if none, design durable per-run manifest before next import.
-
2026-10-08 per-run manifest contract, SELECT-only/no code or DDL: /data-lezama/movilba/evidencia/MOVILBA-59/2026-10-08-per-run-manifest-spec.md sha256 9fe31747d247bcd304824083f2af3d2fd0d0b9c29676c588f2610885e73d8833. Record immutable run id, target DB identity, mode, source path/MD5/SHA256/size, snapshot id, exact non-secret flags/defaults, importer and DB function digests, complete branch-specific reconciliation/materialization/projection/parity counters, and complete ordered NOTICE stream (including explicit zero, count/length/digest). Insert manifest in same PG transaction after gates and before commit; failure/dry-run rolls it back. Cover new, idempotent, and Hoja2 repair commit sites; duplicate run gets separate manifest, not second snapshot. Controls: forced rollback, commit/readback, idempotent second record, dry-run absence, >50 notices. Operator confirms no external transcript of 06/10 run; no historical manifest backfill. No implementation/apply authorized by this spec.
-
Coder implementation pre-read after db04 spec SHA 9fe31747: current importer has three terminal COMMIT sites (new snapshot :1391, duplicate reconciliation :1143, Hoja2 repair :1005), plus an already-repaired Hoja2 no-write early return. No rutap run table exists; a prospective guarded table migration and importer change must be audited together, with no DB apply during code review. Current functions print but do not return several required structured counters (replacement, DEV-protected reconciliation, preflight diagnostics); projection NOTICE deque drains to stdout and must also be retained in order for a committed manifest. Checkout lock requested; no code/DB write yet.
-
Implementation map pinned at /data-lezama/movilba/evidencia/MOVILBA-59/2026-10-08-importer-implementation-map.md SHA256 e882aef38cf25ed8225b22e213997efbb708fd4a47ea8203b315ffd406418078. Three existing commit boundaries and missing structured-return seams identified. A new guarded rutap run table is needed; no such table exists, no code/DDL/import write was made. Checkout lock held by audit, FIFO waiters ahead; code+migration wait for handoff, then audit before any DB apply.
-
Implementation candidate in isolated persistent worktree /home/rob/Documents/work/gcaba/movilba-web-worktrees/movilba-59-run-manifest (branch movilba-59-run-manifest, based on dev dbb26312). Importer tools/rutap-snapshot-import.py SHA256 14dfec43aab15c7049e24ddafb1c341435156867dd1f22094e9f335c700fc492; new default-ROLLBACK migration docs/migrations/2026-10-08-movilba-59-import-run-manifest-PROD-Y-DEV.sql SHA256 c9028f5f8bd075246dc0f925ebf9a841f77b8f3287fe89dcaa62382b8c2ecdc1. Inserts manifest on same cursor before all three commit paths, records source/code/function digests and structured counters, captures complete notices/output, and reads back after commit. No lint/typecheck/tests or DB rehearsal run by coder lane; no DB apply. Audit code+DDL, db operator default-ROLLBACK rehearsal and discriminating controls owed before ship.
-
Candidate repin before verdict: importer SHA256 feaea3bed867572a543a596533ced1b370bb91c5a1442ab954ddcfffb8a003f1 supersedes 14dfec43; server function digest query now pins four exact regprocedure signatures rather than function names. Migration SHA256 c9028f5f unchanged. Audit/db04/PM notified; bytes frozen pending review.
-
2026-10-08 21:55 ART owner-credential default-ROLLBACK rehearsal of exact migration SHA256 c9028f5f8bd075246dc0f925ebf9a841f77b8f3287fe89dcaa62382b8c2ecdc1, isolated worktree docs/migrations/2026-10-08-movilba-59-import-run-manifest-PROD-Y-DEV.sql. PROD first as postgres connection SET ROLE movilba_owner (matching rutap.snapshots owner), rc0: SET / BEGIN / SET / SET / DO / CREATE TABLE / CREATE INDEX / REVOKE / DO / ROLLBACK. DEV second as movilba_user owner, rc0: BEGIN / SET / SET / DO / CREATE TABLE / CREATE INDEX / REVOKE / DO / ROLLBACK. No RAISE NOTICE from either leg. Independent post-transaction SELECT: to_regclass('rutap.import_run_manifests') NULL and rutap.snapshots count 1 on BOTH bases. Same SQL SHA unchanged after. No apply/COMMIT, no importer run, no >50-NOTICE or manifest-insert/runtime control exercised. Audit should verdict migration bytes plus this rehearsal; importer code review remains separate.
-
Added hand-run, no-DB NOTICE serialization control in isolated worktree: tools/verification/movilba-59-manifest-notices.py SHA256 248a3f1f2a8f3bf8db72d383e3504583ff43fc2785c1c6793d892d230c3fb4c6. It asserts explicit empty stream and 60 ordered notices retained through manifest JSON with count/UTF-8 length/SHA256; it does not exercise PostgreSQL delivery or transaction durability. Importer feaea3be and migration c9028f5f bytes unchanged. Per repo workflow coder lane has not run the verifier or gates; audit execution and DB rehearsal owed.
-
PM constraint check on candidate feaea3be: insert_run_manifest receives the existing branch cursor and executes INSERT before that branch's existing pg.commit(); dry-run uses its existing pg.rollback(), so no committed manifest. readback_run_manifest uses the SAME pg connection only AFTER commit to SELECT the persisted row, then rolls back that read-only transaction; no second connection or autonomous commit was added. New-snapshot, duplicate reconciliation and Hoja2 repair commit branches covered; no DB execution claimed yet.
-
2026-10-08 21:57 ART migration guard positive controls after PROD/DEV default-ROLLBACK rehearsal. Correction: pinned SQL c9028f5f contains NO RAISE NOTICE; both DO blocks fail with RAISE EXCEPTION. Preflight tested on PROD as svc_nextjs using exact bytes: rc3 at line26, 'MOVILBA-59 wrong database, owner, or table pre-image', before CREATE. Postcondition tested on DEV using throwaway copy /data-lezama/movilba/evidencia/MOVILBA-59/2026-10-08-manifest-postcondition-mutant.sql SHA256 2fab9151 (only predicate inversion count=0 plus header): rc3 at line60 AFTER CREATE TABLE/INDEX/REVOKE, 'MOVILBA-59 manifest ownership, access, or empty-state mismatch'. Independent post-error SELECT: manifest relation absent in both bases. Role check: PROD movilba_owner rutap USAGE/CREATE true/true; svc_nextjs true/false. DEV movilba_user true/true. Therefore PROD apply must SET ROLE movilba_owner (as rehearsal did); DEV apply runs as movilba_user. Controls see both fail-closed branches; they do NOT exercise an importer insert, COMMIT, or >50 notices. Original SQL SHA unchanged.
-
PM three-commit-path correction incorporated in isolated worktree. New importer SHA256 9b7d92824556d658695985436f3f1e291660fc5ed731fff22280bd07e798bcec (supersedes feaea3be): shared insert helper now uses INSERT ... RETURNING run_id and aborts in-transaction unless the expected row is returned, before any branch can COMMIT. Manual NOTICE control repinned SHA256 d73bd4fda002c53b2bbe4ef3c8ae56f992dd6fc97b275d9fb0035bba8efd925d for its fake cursor; migration c9028f5f unchanged. No gates or DB run by coder lane; audit must verdict these pins.
-
Delivery correction from PM: one shared checkout and hub lock are the active rule; the isolated worktree is review-only and must never deploy. No further worktrees will be created. Current candidate pins there remain importer 9b7d9282, migration c9028f5f, manual control d73bd4fd. Audit to transfer checkout lock BY NAME to coder03, not @next, because stale FIFO waiters remain. Reviewed bytes will be copied byte-identically into the shared checkout under a named lock before the ordinary ship path; no candidate apply/ship yet.
-
2026-10-08 21:58 ART SELECT-only owner-parity check before manifest-table apply: PROD movilba has role movilba_owner (NOLOGIN) and NO movilba_user; all 25 rutap table/view-like relations are owned by movilba_owner. DEV movilba_dev has role movilba_user (LOGIN) and NO movilba_owner; all 27 rutap table/view-like relations are owned by movilba_user. Thus the two existing owner role names are disjoint. The c9028f5f migration, correctly run as each base's rutap.snapshots owner, would create import_run_manifests owned by movilba_owner in PROD and movilba_user in DEV. Matching the same role name across bases is impossible without separate role DDL; no role creation/ALTER is authorized by 59. This is an existing environment-wide 585/497 divergence, not accidental drift of this one table. No apply or role write. PM decision required before apply: retain environment-local owner parity (recommended relative to each base's rutap owner) and document the explicit exception, or separately authorize role convergence under 497.
-
Three-path line census prompted a correction: prior importer 9b7d9282 accidentally turned the already-repaired Hoja2 no-write early return into a fourth manifest-only COMMIT. That was outside the three original commit paths and is withdrawn. New importer SHA256 f401b06bfaa5801e2f0377ff56f8f6838d8c8f67375a3498f60749086b155f76: Hoja2 repair INSERT line 1155 before COMMIT 1158; idempotent-duplicate INSERT 1313 before COMMIT 1317; full import INSERT 1600 before COMMIT 1603. Already-repaired Hoja2 returns after ROLLBACK without writing, exactly as before. Manual control d73bd4fd, migration c9028f5f unchanged. No code gates/DB apply. Audit must review f401b06b; previous importer pins superseded.
-
Owner rule resolved by coder03-mba-l-cc at 2026-10-08 21:59 ART: import_run_manifests follows each base's rutap.snapshots owner (PROD movilba_owner, DEV movilba_user). Role names do not exist cross-base; creating a common role is out of 59 and belongs to 497. The existing environment-specific owner divergence is recorded on MOVILBA-585. No apply before audit verdict on pinned migration/importer/control bytes.
-
# MOVILBA-59 — audit verdict: FAIL, CODE, MIGRATION BODY AND CONTROL. Author coder04-mba-l-ca. audit-mba-l-cc, 2026-10-08 tools/rutap-snapshot-import.py f401b06bfaa5… (modified, 282+/20-) docs/migrations/2026-10-08-movilba-59-…-PROD-Y-DEV.sql c9028f5f8bd0… (new, untracked) tools/verification/movilba-59-manifest-notices.py d73bd4fda002… (new, untracked) All three re-hashed from `/home/rob/Documents/work/gcaba/movilba-web-worktrees/movilba-59-run-manifest` at HEAD `dbb26312`, exact against the 21:59 pins, and re-hashed again after my mutant runs; the worktree holds nothing else. Measured against db04's spec `9fe31747d247bcd3…` at `/data-lezama/movilba/evidencia/MOVILBA-59/2026-10-08-per-run-manifest-spec.md`. ## 1. FAIL, one cause: two reformatted calls break three asserts in two gated tests `test:source` gates both ship paths (`mba-deploy-dev.sh:175`, `mba-deploy-prod.sh:59`, each `exit 1`). The candidate splits two `ejecutar_reconciliacion` calls over two lines to capture their return value: :1300 rows = ejecutar_reconciliacion(cur, duplicate[0], apply,\n 'idempotente') :1489 rows = ejecutar_reconciliacion(cur, snap, apply,\n '-> vehiculos/VDC') Three asserts match that call text literally, on one line: tools/import/movilba-517-app-history-source.test.ts:55 /ejecutar_reconciliacion\(cur, duplicate\[0\], apply, 'idempotente'\)/ tools/import/movilba-517-app-history-source.test.ts:56 /ejecutar_reconciliacion\(cur, snap, apply, '-> vehiculos\/VDC'\)/ tools/import/root-materializer-importer-source.test.ts:54 the :55 regex again Instrument seen to discriminate — dev HEAD `24eb417e` test files, `docs/` present, only the importer swapped underneath, run in my scratchpad and never in coder04's worktree: importer aed5df76 (dev HEAD) 517 rc=0 root-mat rc=0 518 rc=0 subtipo rc=0 importer f401b06b (candidate) 517 rc=1 root-mat rc=1 518 rc=0 subtipo rc=0 candidate, :1300 rejoined only 517 rc=1 root-mat rc=0 518 rc=0 subtipo rc=0 candidate, :1300 and :1489 rejoined 517 rc=0 root-mat rc=0 518 rc=0 subtipo rc=0 `node --test` stops a file at its first failing assert, so the second 517 assert was invisible until I rejoined the first call — rejoining only `:1300` is not enough, and the whole remedy is those two lines. In the worktree itself `pnpm test:source` is 66 pass / 2 fail, the same two files. Execution order is unchanged; these are text-position assertions of the MOVILBA-771 family, which measure wrongly in both directions, and they are nonetheless installed gates that are red. Either keep both calls on one line or re-anchor the three asserts — I do not edit code. Separate: the worktree HEAD `dbb26312` is three commits behind `dev` `24eb417e`, so it needs a rebase before it can ship regardless. ## 2. The spec's >50-NOTICE requirement is MET, and I verified it against the live transport rather than the control Spec `9fe31747` line 15: "Never silently keep only psycopg2's last 50", and control (5) at line 23: "a NOTICE stream over 50 messages is retained in full". The candidate's sink is `deque()` at `:1181`, with the reason in-code at `:1176-1178`. Measured live against `movilba_dev` as `movilba_user`, psycopg2 2.9.10, one `DO` block that only `RAISE NOTICE`s, `ROLLBACK`, nothing read or written: plain list sink raised 10 -> retained 10; raised 60 -> retained 50, first retained 'control 11'; raised 120 -> retained 50, first 'control 71' deque sink raised 120 -> retained 120, in order, 'control 1' … 'control 120' So the cap is real, it drops the EARLIEST messages silently, and the deque the candidate installs is what avoids it. Requirement satisfied, positive control seen both ways. **That property rests on my probe, not on `d73bd4fd`.** The control's `ProjectionCursor.execute` appends to `pg.notices` from Python, bypassing psycopg2's C-level cap entirely, so its `60/60 retained in order` is a property of the container object and would print identically if the sink were a truncating list. Its docstring says so; the printed line does not. Spec control (5) is therefore not yet discharged by anything in the repo — closing it needs a case with a real server emitting >50 messages, which no artifact here has. Reachability, measured across **every non-system schema in BOTH bases**: exactly one function raises anything at all, `rutap.proyectar_snapshot(bigint)`, with 2 `RAISE WARNING` (MOVILBA-492 carroceria, MOVILBA-282 tramite), both one-line aggregates. No trigger function and no non-`rutap` function raises. So today's population per run is 2 against a cap of 50. ## 3. Privileges: no new precondition, one narrowing worth knowing `c9028f5f` only `REVOKE ALL … FROM PUBLIC` and grants nothing, and the importer takes `--dsn` from the operator (`:1621`) with no `SET ROLE`. That adds no requirement the import did not already have: the importer already inserts into `rutap.snapshots`, so the connecting role was already the owner or a superuser. Measured, SELECT-only: PROD rutap.snapshots owner movilba_owner, acl {movilba_owner=arwdDxtm, svc_nextjs=r}; svc_nextjs INSERT false, CREATE on rutap false DEV rutap.snapshots owner movilba_user, acl NULL, movilba_user INSERT true both pg_default_acl for schema rutap: none The new table gets the same owner and no grants, so the set of roles that can write it equals the set that can already write `rutap.snapshots`. The one difference is that `svc_nextjs` will not even have SELECT on the manifest, unlike `rutap.snapshots`; no app path reads it today, so this is a note, not a change. I did not measure which DSN PROD imports actually use, and nobody attempted an `INSERT`. ## 4. Reviewed and not objected to Three insert/commit pairs, each on the transaction's own cursor with the `INSERT` before its `COMMIT`: `:1155`/`:1158` (hoja2_repair), `:1313`/`:1317` (idempotent_reconcile), `:1600`/`:1603` (new_snapshot). The already-repaired Hoja2 branch returns at `:1129` after `pg.rollback()` with no manifest row, which is the defect coder04 withdrew and is correct in these bytes. `insert_run_manifest` fails closed four ways before writing (table absent, snapshot absent in this transaction, unexpected database, fewer than four `regprocedure` digests) and asserts the returned `run_id` equals the generated one. `readback_run_manifest` reads after `COMMIT` on the same connection and demands exactly `[(snapshot_id, source_sha256)]`. Migration body: the preflight pins the table's owner to the LOCAL owner of `rutap.snapshots`, preserving PROD `movilba_owner` and DEV `movilba_user`, which matches db04's role census and 585's environment-specific exception. No FK to `rutap.snapshots` is right here, since each import deletes the previous snapshot row while the run record must survive. No change asked for in `c9028f5f`. **Control seen to fail twice**, restored between runs: mutant A, `proyectar_con_avisos` returning an empty notice list, rc=1 at `:75`; mutant B, `notices.sha256` falsified, rc=1 at `:99`. Importer restored and re-hashed `f401b06b…` exact, control rc=0. ## 5. NOT EXERCISED - **No import ran.** No manifest row was ever inserted, no `COMMIT`, no `readback_run_manifest`, no `importer_revision()` against a clean tree, no `TeeOutput` over a real run. Spec controls (1) through (4) — forced failure after insert, committed single row, idempotent rerun, dry-run leaving zero rows — are all undischarged, and (5) is undischarged by any repo artifact. - **No DDL applied.** `rutap.import_run_manifests` exists in neither base. db04's rehearsal is db04's, scoped to the migration's preflight/create/postcondition/rollback, and by its own statement excludes importer insert, `COMMIT` and >50 NOTICEs. - **No server message ever reached a manifest.** Section 2's figures come from a synthetic `DO` block; the projector was never run, so no real `WARNING` was seen captured, serialized or stored. - **No lint, typecheck, `test:tools` or `next build`.** The candidate changes no TypeScript and the worktree has no install; what I ran is the four `tools/import` importer source tests, in both directions, plus the four rejoin variants. - Privilege figures are `has_table_privilege` and `relacl` reads, not an attempted write.
-
audit fail: CODE, MIGRATION BODY and CONTROL vs db04's spec 9fe31747, plus a live SELECT-only measurement of both bases: importer f401b06b, migration c9028f5f, control d73bd4fd, worktree dbb26312. Gates: the four tools/import source tests, four ways. NO import, no DDL, no COMMIT, no lint/typecheck/test:tools.
payload
{"scope":"CODE, MIGRATION BODY and CONTROL vs db04's spec 9fe31747, plus a live SELECT-only measurement of both bases: importer f401b06b, migration c9028f5f, control d73bd4fd, worktree dbb26312. Gates: the four tools/import source tests, four ways. NO import, no DDL, no COMMIT, no lint/typecheck/test:tools.","outcome":"fail","evidence":"audit-mba-l-cc 2026-10-08. FAIL, one cause. Author coder04. 3 pins re-hashed exact before and after my mutants.\n\nFAIL: two split calls break three asserts in two gated tests. :1300 and :1489 split ejecutar_reconciliacion over two lines; 517-app-history:55, 517:56 and root-materializer:54 match that call text on ONE line, and test:source gates both paths (dev:175, prod:59, exit 1). Instrument discriminates - dev 24eb417e test files, only the importer swapped, my scratchpad: aed5df76 4/4 rc=0; f401b06b 517 and root-mat rc=1; :1300 rejoined alone 517 STILL rc=1; both rejoined 4/4 rc=0. node --test stops at the first assert, so 517:56 was invisible until the first was fixed - the remedy is two lines, not one. Worktree dbb26312 is 3 commits behind dev.\n\nSPEC >50-NOTICE REQUIREMENT IS MET (spec line 15, control 5): the sink is deque() at :1181. Live movilba_dev, psycopg2 2.9.10, one DO that only RAISEs, ROLLBACK: plain list 60->50 and 120->50, keeping the LAST 50; deque 120->120 in order. Seen both ways. BUT d73bd4fd cannot see it - it appends from Python, bypassing the C cap, so its 60/60 is a property of the container, and spec control 5 is discharged by my probe, not by a repo artifact. Reachability across EVERY non-system schema in BOTH bases: only rutap.proyectar_snapshot raises, 2 RAISE WARNING (492, 282).\n\nPRIVILEGES: no new precondition - c9028f5f grants nothing and there is no SET ROLE, but the importer already inserts into rutap.snapshots, so the writer set is unchanged: PROD owner movilba_owner (svc_nextjs=r only), DEV owner movilba_user.\n\nNOT OBJECTED TO: INSERT before COMMIT at 1155/1158, 1313/1317, 1600/1603; insert_run_manifest fails closed 4 ways; migration pins each base's LOCAL owner. CONTROL SEEN TO FAIL: empty notices rc=1 at :75, falsified sha256 rc=1 at :99; restored f401b06b exact.\n\nNOT EXERCISED: no import, no manifest row, no COMMIT, no readback; spec controls 1-4 undischarged; no DDL, table in neither base; no lint/typecheck/test:tools.","reportRef":null} -
Audit FAIL 2026-10-08 22:16 ART on importer f401b06b: source-text gate requires both ejecutar_reconciliacion calls on one line. Corrected only those two call-site wraps in the review worktree; new importer SHA256 aa334967b8a75e959f7bbecf451848c912ef581943e608e778bff172082b64af, lines 1300 and 1488. Migration c9028f5f and hand-run NOTICE control d73bd4fd unchanged. Previous f401 pin superseded. Per code-lane workflow, no local test/gate run; audit re-verdict owed on exact new pin. No DB apply or ship.
-
Rebased the existing review-only movilba-59-run-manifest worktree onto DEV a7da6ffe after audit FAIL; local review commit c5d1f740, clean worktree. No shared-checkout write or deploy. Exact post-rebase SHA256 pins remain importer aa334967b8a75e959f7bbecf451848c912ef581943e608e778bff172082b64af, migration c9028f5f8bd075246dc0f925ebf9a841f77b8f3287fe89dcaa62382b8c2ecdc1, NOTICE control d73bd4fda002c53b2bbe4ef3c8ae56f992dd6fc97b275d9fb0035bba8efd925d. Both reconciler calls are on one line at importer :1300/:1488. Audit re-verdict owed; no code gates or DB apply by coder lane.
-
# MOVILBA-59 — audit re-verdict: PASS, CODE, MIGRATION BODY AND CONTROL. Author coder04-mba-l-ca. audit-mba-l-cc, 2026-10-08 tools/rutap-snapshot-import.py aa334967b8a7… (300+/20-) docs/migrations/2026-10-08-movilba-59-…-PROD-Y-DEV.sql c9028f5f8bd0… tools/verification/movilba-59-manifest-notices.py d73bd4fda002… Worktree `/home/rob/Documents/work/gcaba/movilba-web-worktrees/movilba-59-run-manifest` at `c5d1f740`, clean, rebased onto `dev` `a7da6ffe` (verified: `a7da6ffe` is an ancestor of `c5d1f740`). The commit touches those three paths and nothing else, 452+/20-. All three re-hashed exact against coder04's 22:18 pins and again after my mutant runs. This re-verdict supersedes my FAIL on `f401b06b` of 01:16:51.767Z; the earlier note's sections 2 through 5 still describe these bytes, since the delta is confined to two lines. ## 1. The FAIL cause is closed, and the delta is exactly the remedy I named `diff` against `f401b06b` is the two rejoins and nothing else: :1300 rows = ejecutar_reconciliacion(cur, duplicate[0], apply, 'idempotente') :1488 rows = ejecutar_reconciliacion(cur, snap, apply, '-> vehiculos/VDC') No other hunk moved, so none of my earlier measurements of the manifest path is invalidated. ## 2. Gates, run by me on the rebased worktree bytes pnpm test:source rc=0, 68 pass / 0 fail (the 4 tools/import importer tests among them) pnpm test:tools rc=0, 2 skipped, 0 fail control d73bd4fd rc=0, '0/0 and 60/60 retained in order' `node_modules` was symlinked from the shared checkout for the run and removed afterwards; the worktree is clean and the pins are unchanged. **Both asserts seen to fail independently, which is what answers the runner's first-failure stop.** `node --test` still reports only one assert per file, so one combined mutant would have left the second one a green line. I forced each separately, in my scratchpad, never in the worktree: body as pinned 517 rc=0 only :1300 re-split 517 rc=1, first failing assert at :55 only :1488 re-split 517 rc=1, first failing assert at :56 Plus `root-materializer-importer-source:54` already seen rc=1 against `f401b06b`. So all three asserts have been observed failing, and the limit is named rather than assumed: it is a property of the runner, not of this candidate, and a future edit that breaks two of these lines at once will still only show the first. ## 3. Carried unchanged from the FAIL note, still true of these bytes - **Spec `9fe31747` control (5), >50 NOTICEs retained in full: MET**, by the `deque()` sink at `:1181`. Measured live on `movilba_dev`, psycopg2 2.9.10, one `DO` that only `RAISE NOTICE`s, `ROLLBACK`: a plain list keeps the LAST 50 of 60 and of 120, dropping the earliest; the deque keeps 120 of 120 in order. **That property rests on my probe, not on `d73bd4fd`**, whose `ProjectionCursor` appends from Python and bypasses psycopg2's C-level cap, so its `60/60` would print identically with a truncating sink. Reachability, every non-system schema in both bases: only `rutap.proyectar_snapshot(bigint)` raises anything, 2 `RAISE WARNING` (MOVILBA-492, MOVILBA-282). - **Privileges: no new precondition.** `c9028f5f` grants nothing and the importer has no `SET ROLE`, but it already inserts into `rutap.snapshots`, so the set of roles that can write is unchanged — PROD owner `movilba_owner` with `svc_nextjs=r` only, DEV owner `movilba_user`. `svc_nextjs` will not have SELECT on the manifest, unlike `rutap.snapshots`; no app path reads it. - Three insert/commit pairs on the transaction's own cursor, `INSERT` before `COMMIT`; the already-repaired Hoja2 branch returns with no manifest row; `insert_run_manifest` fails closed four ways and asserts its own `run_id` back; `readback_run_manifest` demands exactly one row; the migration pins the table's owner to each base's local owner of `rutap.snapshots`, and the absent FK is correct because each import deletes the previous snapshot row. - Control seen to fail twice on the notice path (empty notice list rc=1 at `:75`, falsified `notices.sha256` rc=1 at `:99`), measured against `f401b06b`, whose notice path these bytes do not touch. ## 4. NOT EXERCISED — unchanged, and this PASS is on bytes and gates only - **No import ran.** No manifest row was ever inserted, no `COMMIT`, no `readback_run_manifest`, no `importer_revision()` against a clean tree, no `TeeOutput` over a real run. Spec controls (1) through (4) — forced failure after insert, committed single row, idempotent rerun creating a second run without a second snapshot, dry-run leaving zero rows — are all undischarged, and (5) is discharged by my probe rather than by a repo artifact. - **No DDL applied.** `rutap.import_run_manifests` exists in neither base; nothing here authorizes the apply, and the PROD-first apply plus the independent post-commit readback remain db04's operational gates. - **No server message ever reached a manifest.** The projector was never run; no real `WARNING` was seen captured, serialized or stored. - **No typecheck, no lint, no `next build`.** The candidate changes no TypeScript. `test:tools` passing says nothing about the importer; it is reported because it gates both ship paths. - Privilege figures are `has_table_privilege` and `relacl` reads; nobody attempted a write, and I did not measure which DSN PROD imports actually use. - Three earlier runs of the control from my `devtests` copy returned rc=2 and are an instrument error, not a result: that copy came from the shared checkout, where the control file does not exist. The valid control runs are the ones in the worktree.
-
audit pass: CODE, MIGRATION BODY and CONTROL on the rebased worktree c5d1f740 (dev a7da6ffe is an ancestor): importer aa334967, migration c9028f5f, control d73bd4fd. Gates test:source, test:tools and the NOTICE control, plus a live SELECT-only probe. NO import, no COMMIT, no DDL, no typecheck/lint.
payload
{"scope":"CODE, MIGRATION BODY and CONTROL on the rebased worktree c5d1f740 (dev a7da6ffe is an ancestor): importer aa334967, migration c9028f5f, control d73bd4fd. Gates test:source, test:tools and the NOTICE control, plus a live SELECT-only probe. NO import, no COMMIT, no DDL, no typecheck/lint.","outcome":"pass","evidence":"audit-mba-l-cc 2026-10-08. PASS, re-verdict superseding my FAIL on f401b06b at 01:16:51.767Z. Author coder04. 3 pins re-hashed exact before and after my mutants; worktree c5d1f740 clean, dev a7da6ffe an ancestor, commit touches only those paths.\n\nDELTA IS EXACTLY THE REMEDY NAMED: diff vs f401b06b is the two rejoins, :1300 and :1488, nothing else, so no earlier measurement of the manifest path is invalidated.\n\nGATES on the rebased bytes: test:source 68 pass 0 fail; test:tools 0 fail 2 skipped; control d73bd4fd rc=0.\n\nBOTH ASSERTS SEEN TO FAIL INDEPENDENTLY, in my scratchpad, never in the worktree: body as pinned 517 rc=0; only :1300 re-split 517 rc=1 at :55; only :1488 re-split 517 rc=1 at :56. root-materializer:54 was already seen rc=1 on f401b06b. node --test reports one assert per file, so a combined mutant would have left the second a green line - the runner's limit, not this candidate's, named rather than assumed.\n\nCARRIED, STILL TRUE: spec 9fe31747 control 5 is MET by the deque at :1181 - live probe, plain list keeps the LAST 50 of 60 and of 120, deque keeps 120/120 in order - but d73bd4fd cannot see that difference, so control 5 rests on my probe, not a repo artifact. Only rutap.proyectar_snapshot raises in either base, 2 RAISE WARNING (492, 282). Privileges add no precondition: the importer already inserts into rutap.snapshots, PROD owner movilba_owner with svc_nextjs=r only, DEV owner movilba_user. INSERT before COMMIT at 1155/1158, 1313/1317, 1600/1603; insert_run_manifest fails closed 4 ways; readback demands exactly one row; migration pins each base's LOCAL owner.\n\nNOT EXERCISED: no import ran, no manifest row, no COMMIT, no readback, no real NOTICE stored; spec controls 1-4 undischarged and 5 discharged only by my probe; no DDL, the table exists in neither base and nothing here authorizes the apply; no typecheck, lint or next build, no TypeScript changed; no write attempted.","reportRef":null} -
Audited file scope shipped by coder03-mba-l-cc on DEV 353eff10 / PROD 8afa58ab, patch 221; shared checkout files independently re-hashed at importer aa334967, migration c9028f5f, control d73bd4fd. The clean review worktree was removed with git worktree remove after verifying byte identity; no deployment from it. Migration is a FILE only: rutap.import_run_manifests is absent in both bases. Item remains open for separately authorized PROD-first DDL apply and real import/manifest/COMMIT/readback/NOTICE controls; audit PASS covers code and rollback rehearsal, not runtime. POD leg still awaiting observed patch 221.
-
2026-10-08 23:06 ART — Reviewed SQL docs/migrations/2026-10-08-movilba-59-import-run-manifest-PROD-Y-DEV.sql SHA256 c9028f5f8bd075246dc0f925ebf9a841f77b8f3287fe89dcaa62382b8c2ecdc1 applied PROD then DEV, unchanged. Authority: Commons §6 pre-live requested PROD DDL; no carve-out applies. PRE: table absent / rutap.snapshots 1 in each base. PROD as SET ROLE movilba_owner: default-ROLLBACK rehearsal rc0, after-read table absent/snapshots 1; apply rc0 COMMIT, POST table present 0 rows, owner movilba_owner, two valid indexes, PUBLIC SELECT false, svc_nextjs SELECT/INSERT false, snapshots 1, app health ok serviceId 31188. DEV as movilba_user: default-ROLLBACK rehearsal rc0, after-read table absent/snapshots 1; apply rc0 COMMIT, POST table present 0 rows, owner movilba_user, two valid indexes, PUBLIC SELECT false, snapshots 1, app health ok serviceId 31188. No CASCADE. Importer insert/COMMIT/readback and real NOTICE capture remain NOT EXERCISED; item stays open. My first extra PROD privilege probe erred by passing 'PUBLIC' to has_table_privilege (not a role); corrected with aclexplode and measured false. Schema mirror regeneration belongs to coder lane per Commons §6.
-
Post-DDL DEV Drizzle mirror regenerated with ./mba-introspect.sh under gates-checkout-movilba-web lock. Script verified movilba_dev and 117/117 view mirror with 4 baselined lossy literals, exit 0. Tracked diff is exactly one +23-line declaration for rutap.import_run_manifests in drizzle/schema.ts, SHA256 2d0e74a9ac5b11dafff23e571aca32a314dc7c1451e31bade8788d1e2da399cc. drizzle/relations.ts unchanged SHA256 19650192eda36466b6344d956043f2f486c4f2543151b1082bb45f94ee513eb3, consistent with DDL having no FK. Audit concern to check: generator prints int8_ops for completedAt in composite index although installed DDL indexes timestamptz; assess as mirror limitation before ship. No app gates run by coder; no importer/manifest runtime execution.
-
Mirror follow-up: coder03 measured installed import_run_manifests_snapshot_idx positionally in PROD and DEV using generate_subscripts(indkey,1): snapshot_id uses default int8_ops, completed_at uses default timestamptz_ops in both. Generated on completedAt in drizzle/schema.ts is a Drizzle mirror artifact, not installed state and not a DDL defect. Prior +23-line-only diff/pin 2d0e74a9 unchanged, relations.ts unchanged. The first non-positional opclass query was a cross product and is withdrawn. Mirror clear for one-hunk audit/ship scope.
-
Correction to immediately prior note: the omitted generated expression is .op("int8_ops") on completedAt. This is a Drizzle mirror artifact, while the installed PostgreSQL index has timestamptz_ops on that column in PROD and DEV. The mirror SHA remains 2d0e74a9.
-
# MOVILBA-59 Drizzle mirror hunk - audit INVESTIGATION, verdict WITHHELD pending gates. Author coder04-mba-l-ca. audit-mba-l-cc, 2026-10-08 drizzle/schema.ts 2d0e74a9ac5b11dafff23e571aca32a314dc7c1451e31bade8788d1e2da399cc drizzle/relations.ts 19650192eda36466b6344d956043f2f486c4f2543151b1082bb45f94ee513eb3 (UNCHANGED vs HEAD) migration applied c9028f5f8bd075246dc0f925ebf9a841f77b8f3287fe89dcaa62382b8c2ecdc1 Both pins exact in the shared checkout. `git diff --stat` on the two mirror files reports `drizzle/schema.ts | 23 +++` and nothing else, so the mirror's ONLY deviation from HEAD is `importRunManifestsInRutap`. coder03's withheld-on-764 premise is empirically moot on these bytes: no accumulated DEV hunk rides along. That is measured on the diff, not inferred from 764's status. **Why no verdict yet.** A PASS on a `.ts` hunk needs `pnpm typecheck` to have run, and the hunk's correctness depends on `rutap`, `check`, `index`, `jsonb`, `uuid` and `timestamp` all resolving in `schema.ts`. That needs the checkout, and `gates-checkout-movilba-web` is HELD by coder03-mba-l-cc until 1791515438 with the note "ship 628+733+753+754+768 to dev then prod; mirror and 775/776 NOT included". Running a typecheck inside another lane's prod leg would also be measured against a parked tree. The structural measurement below is complete and does not need the lock; the verdict follows the gates, on re-pinned bytes. ## 1. The `.op("int8_ops")` on completedAt is a mirror artifact, measured myself I did not take the prior readings on trust. Positional join through `generate_subscripts(indkey,1)`, mapping `indkey[ord]` to `attnum` and `indclass[ord]` to `pg_opclass`, so each column meets its OWN opclass and no cross product can manufacture agreement. Identical in both bases: import_run_manifests_pkey ord 0 run_id uuid_ops opcdefault btree primary unique valid import_run_manifests_snapshot_idx ord 0 snapshot_id int8_ops opcdefault btree import_run_manifests_snapshot_idx ord 1 completed_at timestamptz_ops opcdefault btree Installed state is `timestamptz_ops` on `completed_at`, default, in PROD 17.6 and DEV 15.17 alike. The generated `.op("int8_ops")` on `completedAt` is **wrong text in a generated file** and corresponds to no installed object. It is the known lossy-mirror class, not a DDL change: `drizzle/schema.ts` is never a DDL source here, and `db:generate`/`db:migrate` are named by neither `mba-deploy-dev.sh` nor `mba-deploy-prod.sh`, so nothing turns that text into an index. ## 2. The mirror matches the applied migration, column by column, both bases All 10 columns in migration order, every one `attnotnull = t`, one default: run_id uuid PK | snapshot_id bigint | mode text | target_database text | source_path text source_md5 text | source_sha256 text | source_size_bytes bigint completed_at timestamptz DEFAULT clock_timestamp() | manifest jsonb Six CHECKs plus the PK. **What I measured is that the mirror's `check` text equals `pg_get_constraintdef` in both bases**, not that it equals the migration's source: the migration writes `mode IN (...)` and the catalog stores `= ANY (ARRAY[...])`, so a byte claim against the `.sql` would be false. The predicates are semantically the migration's six. `relations.ts` unchanged is CORRECT and not an omission: the migration declares no FK on purpose (`:5-6`, each import deletes the previous snapshot row while the run record must stay immutable), so there is no relation to mirror. `bigint ... { mode: "number" }` on `snapshot_id` and `source_size_bytes` matches how the same file already treats `rutap.snapshots.id` at `drizzle/schema.ts:673`, including the identical `{ mode: "bigint" }` advisory comment. ## 3. The owner asymmetry is INHERITED and already censused under MOVILBA-497 Raised against this item as a 773-class divergence and as NEW debt. It is neither new nor confined to this table. Measured, both bases, every `rutap` relation and not just the one: PROD rutap 11 tables + 15 views + 3 sequences ALL owned by movilba_owner DEV rutap 13 tables + 15 views + 3 sequences ALL owned by movilba_user Zero exceptions on either side. The new table's owner is each base's uniform `rutap` owner, so a matching pair was unreachable without first re-owning DEV's whole schema. The migration also forces it rather than choosing: the preflight at `:20-23` aborts unless `current_user` IS the owner of `rutap.snapshots`. The citable source coder03 asked for already exists and is stronger than that inference: `docs/reference/movilba-585-dev-prod-structural-census.md:57-65` (MOVILBA-773 amendment) records all 104 `public`+`rutap` views differing in owner, PROD `movilba_owner` 71 / `postgres` 33 against DEV `movilba_user` 104, and declares them **UNRESOLVED environment-role differences under MOVILBA-497, "not authorization to change an owner, GRANT, or REVOKE"**, with the note "DEV's application role is the owner; PROD's is not." My census above extends that same finding from views to `rutap`'s tables and sequences, with the same pattern and no exception. So: not 59's debt, not day-one drift, and the open item is 497. Two sub-readings that look like drift and are not: the `m` (MAINTAIN) privilege in PROD's aclitem is PostgreSQL 17 only and has no PG15 spelling, so `arwdDxtm` vs `arwdDxt` is a version artifact; and `relacl` NULL on DEV's `snapshots` means default privileges, not an absence of the owner's. `PUBLIC SELECT` is false on the new table in both bases, measured through `aclexplode(coalesce(relacl, acldefault(...)))`. That is the same formula the migration's own postcondition uses, so it is a re-run of the author's control, not an independent one. DEV holds 0 manifest rows and 1 snapshot row. ## 4. One observation outside this hunk, and the correction to my first reading of it PROD has **no `svc_nextjs` grant** on the new table, where `rutap.snapshots`, `rutap_rows`, `rutap_expedientes` and `unidad_propulsora_resolver` all carry `svc_nextjs=r`. Correct as it stands: no TypeScript path reads the table. The only readers are `tools/rutap-snapshot-import.py` and `tools/verification/movilba-59-manifest-notices.py`, and `grep` over `src/` finds nothing. My own PROD census connected as `svc_nextjs` and got `permission denied` on the row count, which is that grant state behaving as designed and is why the PROD row count is absent above. **I first wrote that an import run with an app-role DSN would materialize and project, then fail late at `:347`, because `insert_run_manifest` probes existence (`:307`), snapshot presence (`:310`), database name (`:315`) and four function digests (`:317-329`) but never INSERT privilege. That reading is wrong and the probe refutes it.** `has_table_privilege` for every non-`pg_` role in both bases, on `rutap.snapshots` INSERT/UPDATE/DELETE against `import_run_manifests` SELECT/INSERT, returns all-true or all-false per role with **no role split between the two tables** - PROD: `20313154204`, `20366097083`, `db_admins`, `elazar`, `movilba_owner`, `nossesmacchia`, `postgres` all-true, the other 24 including `svc_nextjs`, `svc_api`, `movilba_app_user` and `next_app` all-false; DEV: `datco`, `movilba_user`, `postgres` all-true, the other 68 all-false. So the role that reaches `:347` can always insert, and a role that cannot insert the manifest cannot write `snapshots` either, so it fails at the first snapshot write long before the manifest. The missing privilege probe costs nothing today. It is unexercised rather than safe-by-construction: a future GRANT could split the pair. ## 5. NOT EXERCISED - **No gates.** `pnpm typecheck`, `test:source` and `test:tools` have NOT been run on this hunk, which is why there is no verdict here. The mirror has not been seen to compile. - **No importer run.** No manifest row written, no COMMIT, no `readback_run_manifest`, no real NOTICE captured. Everything above is installed structure plus generated text. - `drizzle-kit` was not run and the mirror was not regenerated by me. I audited coder04's output, so an error in `./mba-introspect.sh` that both of us would reproduce is not covered. - The mirror projects neither `relowner` nor `relacl`, so the §3 divergence is invisible in `schema.ts` exactly as 773 found it invisible in the 585 census. Nothing here changes that. - No HTTP, no screen, no export, no PDF. No DDL and no data written by me; both bases read SELECT-only.
-
2026-10-08 23:23 ART: After the audited c9028f5f migration was applied PROD then DEV, coder03's deploy park completed and checkout lock freed. DEV introspection regenerated drizzle/schema.ts to include rutap.import_run_manifests; exact current SHA256 2d0e74a9ac5b11dafff23e571aca32a314dc7c1451e31bade8788d1e2da399cc. Also corrected MOVILBA-585 structural census addendum to installed-state owner/ACL evidence, SHA256 49fbb907507a3a3c03c3902c23b45c2fca9e89bbfb2953fec8584633f50eb5a7. Both are pending audit review; no repository gates run. No import executed: real manifest insert/commit/readback and NOTICE capture remain unexercised.
-
# MOVILBA-59 Drizzle mirror + 585 addendum - audit verdict: PASS. Author coder04-mba-l-ca. audit-mba-l-cc, 2026-10-08 drizzle/schema.ts 2d0e74a9ac5b11dafff23e571aca32a314dc7c1451e31bade8788d1e2da399cc docs/reference/movilba-585-dev-prod-structural-census.md 49fbb907507a3a3c03c3902c23b45c2fca9e89bbfb2953fec8584633f50eb5a7 relations.ts 19650192eda36466b6344d956043f2f486c4f2543151b1082bb45f94ee513eb3 (UNCHANGED) migration applied c9028f5f8bd075246dc0f925ebf9a841f77b8f3287fe89dcaa62382b8c2ecdc1 **SUPERSEDES my earlier INVESTIGATION note on this item** (verdict withheld pending gates). All structural measurement there stands unchanged; this adds the gates and the second file. ## Gates, under gates-checkout-movilba-web, granted directly to me by db04 (no race) pnpm typecheck rc=0 pnpm test:source 68 pass / 0 fail pnpm test:tools 119 pass / 0 fail Both pins re-verified EXACT before and after the run; no other lane's work was in the tree (coder03's prod ship had already released and reported PROD live on patch 222). ## schema.ts hunk: unchanged from my prior measurement `.op("int8_ops")` on `completedAt` is a Drizzle mirror artifact; installed index uses `timestamptz_ops` opcdefault in both bases, measured positionally. `relations.ts` correctly untouched (migration declares no FK by design, `:5-6`). Owner asymmetry is NOT new debt: all `rutap` relations in PROD owned by `movilba_owner`, all in DEV by `movilba_user`, zero exceptions, matching the already-open MOVILBA-497. ## 585 addendum: corroborated independently The doc's "25 existing" (PROD) / "27" (DEV) `rutap` table+view denominators, pre-manifest, match my own census exactly: I counted 11 tables + 15 views = 26 PROD / 13 + 15 = 28 DEV INCLUDING the new table, so 25/27 before it. `svc_nextjs` USAGE-without-CREATE on `rutap` and the owner-is-local-snapshots-owner framing both match what I measured directly. The doc correctly separates "mirror is generated from DEV" from "PROD presence/owner/ACL measured directly" - that distinction is real: my own PROD read used `svc_nextjs` and got `permission denied` on the row count specifically because PROD grants nothing there, which the doc's "PROD svc_nextjs has neither SELECT nor INSERT" states as fact, not inference. ## NOT EXERCISED No importer run, no manifest row, no COMMIT, no readback, no real NOTICE. No HTTP, no screen, no DDL or data written by me.
-
audit pass: drizzle/schema.ts (+23 manifest table) and movilba-585-dev-prod-structural-census.md addendum, both re-pinned. Gates: typecheck, test:source, test:tools, all under the checkout lock. No importer/DDL/data write by audit.
payload
{"scope":"drizzle/schema.ts (+23 manifest table) and movilba-585-dev-prod-structural-census.md addendum, both re-pinned. Gates: typecheck, test:source, test:tools, all under the checkout lock. No importer/DDL/data write by audit.","outcome":"pass","evidence":"Gates rc=0/68-0/119-0 on re-pinned bytes 2d0e74a9/49fbb907, both pins unchanged before and after. int8_ops on completedAt confirmed mirror-only artifact (installed is timestamptz_ops, positional join). Owner asymmetry matches the open MOVILBA-497, not new debt - all rutap relations movilba_owner in PROD, movilba_user in DEV, zero exceptions. 585 doc's 25/27 pre-manifest denominators match my own independent count (26/28 including the new table). svc_nextjs permission-denied on my PROD row count matches the doc's \"neither SELECT nor INSERT\" claim exactly, not inferred by either of us separately - same underlying grant state. No importer run, no manifest row, no COMMIT/readback/NOTICE. No DDL or data write by audit.","reportRef":null} -
2026-10-08 23:25 ART audit PASS on post-apply mirror/doc: drizzle/schema.ts SHA256 2d0e74a9ac5b11dafff23e571aca32a314dc7c1451e31bade8788d1e2da399cc and docs/reference/movilba-585-dev-prod-structural-census.md SHA256 49fbb907507a3a3c03c3902c23b45c2fca9e89bbfb2953fec8584633f50eb5a7; exact before/after gates. Audit ran typecheck, test:source 68/68 and test:tools 119/119. Audit confirmed int8_ops, 585's pre-manifest 25/27 denominators, and owner asymmetry belongs to existing MOVILBA-497 rather than new drift debt. Checkout released and transferred to coder04. Item remains open: a real import's manifest write/commit/readback and real NOTICE capture are unexercised.
-
Shipeado. dev 92d85947 patch 223 (health OK intento 1/10), prod main e16f0ce9 patch 223, app.movilba.com/api/health serviceId 31462 verde al primer intento con el cuerpo nuevo del gate de 628. Los tres pines re-hasheados contra el arbol compartido como ultimo paso antes del commit y exactos contra los PASS de audit: schema.ts 2d0e74a9, addendum 585 49fbb907, opciones.ts bc223c5d. El arbol de los otros carriles se parkeo a un stash para el deploy de prod y volvio verificado POR ARCHIVO, no por conteo: diff de trackeados contra el stash vacio y los 26 blobs untracked identicos. POD: delegado a proxy-mba-w-cc, que es la regla de Elazar - la pata del pod corre desde whey, no desde lezama - asi que la paridad de flota NO esta cerrada todavia, el pod sigue en 222 y quiere 31462. SIN EJERCITAR: ningun import corrio, la tabla de manifiesto sigue en 0 filas, ningun dropdown se abrio y 775 sigue sin caller en src/ ni tools/, o sea el arreglo es correcto y hoy inalcanzable.
-
CORRECCION de mi propio cierre, que supersede el status done que puse a las 02:40Z: lo reabro a inProgress. Lo que esta shipeado es el CODIGO y el DDL - la tabla de manifiesto aplicada en las dos bases, el espejo de drizzle que la declara, el importador que escribe una fila por corrida y los dos call sites del reconciliador en una linea. Lo que el titulo de este item pide es otra cosa: que el import RUTAP sea reproducible DE PUNTA A PUNTA, y eso no se demuestra con texto de codigo. Ninguna corrida real existe: cero filas en la tabla de manifiesto, ningun COMMIT ni readback observado, ningun NOTICE de la proyeccion visto salir por stdout, y los controles 1 a 4 de la spec 9fe31747 siguen sin descargar. Cerrarlo por el ship del instrumento es exactamente la forma que este proyecto llama linea verde: un control que todavia no se vio correr. Queda abierto hasta que una corrida de import escriba su fila de manifiesto y alguien la lea de vuelta. Dueno: db04-mba-l-ca.
-
2026-10-08 23:42 ART — Real PROD runtime on clean detached worktree at production commit e16f0ce93c3d7b3c308875d305a9350bb9d066cf; importer SHA256 aa334967b8a75e959f7bbecf451848c912ef581943e608e778bff172082b64af; worktree_dirty=false. Source /data-lezama/movilba/libro/2026-10-06-1140-parque-rutap.xlsx, MD5 eb2e2683ccdd16a33be4a34b7b56088b, SHA256 a72ade6a52621051e5a1dc7a01281de7b11e69c2332c8bf5163fea943b2c5f1a, 1,760,186 bytes; PROD current snapshot 11 already matched it (5,558 Base / 47 Hoja2), so both committed runs exercised . Default-ROLLBACK PROD rehearsal rc0 showed replacement counts and every reconciliation write count 0. Apply run IDs 645eb32d-b454-4ac4-9751-57e0ee8b5b19 and fc2ed12f-c11c-4c1f-9c3a-6ebebffed102; each printed COMMIT and importer readback succeeded. Independent post-commit SELECT: both run rows link snapshot 11/source MD5; ; notices count=0/items=[] as projector is explicitly skipped in idempotent mode; verified counts 5558/47 each. Post-state: 1 snapshot, 5558 raw rows, 47 Hoja2, 0 other-snapshot raw/history, 2 manifest rows; app health OK serviceId 31462. No new snapshot was created. Remaining boundary: no approved newer workbook exists locally; this run did not exercise new-snapshot materialize/projector or real projector NOTICE output, forced post-insert failure, or apply-path rollback. Item stays inProgress pending a new approved source for those paths.
-
Correction to the 02:42Z note: the two committed PROD executions both exercised the idempotent_reconcile branch. NOTICE count 0/items=[] is expected because that branch skips the projector; it is not evidence that projector NOTICE capture was exercised. Both run IDs were read back independently after COMMIT. The current-source import produced two durable manifest rows with no business-data changes. New-snapshot/projector NOTICE capture and the forced post-insert failure path remain unexercised; no newer approved workbook is available locally, so keep this item open until a new approved source can exercise that path.
task
2026-08-20 by wi-cli-venus
1w ago