El hook pre-deploy reporta un chequeo que crasheo como si el artefacto estuviera desactualizado
Medido el 2026-09-07 durante el deploy de dd0cc537. El hook pre-deploy reporto 'Postman collection desactualizada' con la coleccion INTACTA. Causa real: generate-postman-collection.ts --check CRASHEO al transpilar un drizzle/schema.ts sintacticamente roto (ver MOVILBA-324), y el hook lee CUALQUIER exit distinto de cero como desactualizacion. La clase: UN CHEQUEO QUE NO PUEDE CORRER SE REPORTA IGUAL QUE UNO QUE FALLO. El mensaje manda al lector a mirar la coleccion, que es el unico lugar donde no esta el problema. Con schema.ts arreglado el mismo comando da 'al dia (19 carpetas, 93 requests)'. Fix: el hook tiene que distinguir exit de 'desactualizada' de exit de 'no pude correr' - codigos de salida distintos en el script, y el hook reporta 'el chequeo de Postman no pudo correr' con el stderr, no una conclusion sobre el artefacto. Barrer si otros chequeos del mismo hook comparten la forma.
Activity
-
coder03-mba-l-cc / coder
-
coder03assistant-mba-l-ca
-
researcher-mba-l-cc / solo
-
Researcher started at 2026-10-08T12:08:14-03:00.
-
researcher-mba-l-cc REPRODUCES TODAY, unfixed. mba-deploy-dev.sh:114-115: node_modules/.bin/tsx scripts/generate-postman-collection.ts --check \ || { echo -e "${RED}Postman collection is stale vs the OpenAPI manifest${NC}"; exit 1; } Any nonzero exit - the script's own explicit `process.exit(1)` for "actually stale" (scripts/generate-postman-collection.ts:271) OR tsx's own crash exit when the import chain throws (e.g. transpiling a broken drizzle/schema.ts, the MOVILBA-324 case this ticket was filed against) - produces the exact same message. Genuinely indistinguishable by exit code alone today; the ticket's description still matches current code. SWEEP of the other two --check-style pre-check gates in the same hook (per the ticket's own "barrer si otros comparten la forma"): - line 108, `pnpm run --silent lockfiles:check` - does NOT share the defect. It's a standalone comparison script with no source-transpile dependency, so there's no "crashed while trying to check" failure mode distinct from "checked and found a mismatch" - a nonzero exit only ever means the real thing. - line 111, `bash tools/gen-changelog.sh` - same: shell script reading git history, not transpiling app source, no shared ambiguity. - Only the Postman check is exposed, because it alone imports/transpiles application source (the OpenAPI manifest, which pulls in drizzle/schema.ts) as part of running --check. Sweep finds exactly one site, confirming the ticket's own scope. FIX: 1. scripts/generate-postman-collection.ts: wrap the --check body's generation/comparison step in try/catch. On a caught exception (transpile/import failure), print the error and `process.exit(2)`. Keep `process.exit(1)` reserved for the genuine "generated output differs from committed file" case. Success stays exit 0. 2. mba-deploy-dev.sh:114-115: branch on the exit code instead of a single `||`: node_modules/.bin/tsx scripts/generate-postman-collection.ts --check code=$? if [[ $code -eq 1 ]]; then echo -e "${RED}Postman collection is stale vs the OpenAPI manifest${NC}"; exit 1 elif [[ $code -ne 0 ]]; then echo -e "${RED}Postman collection check could not run (see output above) - this is not a staleness verdict${NC}"; exit 1 fi Both branches still abort the deploy (an unrunnable check is not a pass), but the printed message stops pointing the reader at the collection when the real defect is upstream (a broken schema.ts, as it was in the MOVILBA-324 incident this ticket documents).
-
coder04-mba-l-ca / coder
-
Diff ready for audit: generator --check uses exit 2 only when committed collection differs; tsx crash retains exit 1. mba-deploy-dev.sh precheck branches on 2 (stale) versus any other nonzero (check could not run), both abort deploy. Controlled reproductions under checkout lock: appended newline to a clean Postman collection -> exit 2; appended invalid TypeScript to OpenAPI manifest -> exit 1. Both tracked files restored byte-for-byte immediately; no residual source diff. Scope: scripts/generate-postman-collection.ts and mba-deploy-dev.sh.
-
audit pass: scripts/generate-postman-collection.ts 1ff11443 and mba-deploy-dev.sh 3ea1d8ea. Exit-0 and crash legs EXERCISED by audit, shell branch and status capture proved; typecheck, eslint, bash -n, test:source run. NOT EXERCISED: the genuine-stale exit-2 leg, which needs a tracked-file mutation.
payload
{"scope":"scripts/generate-postman-collection.ts 1ff11443 and mba-deploy-dev.sh 3ea1d8ea. Exit-0 and crash legs EXERCISED by audit, shell branch and status capture proved; typecheck, eslint, bash -n, test:source run. NOT EXERCISED: the genuine-stale exit-2 leg, which needs a tracked-file mutation.","outcome":"pass","evidence":"PASS. scripts/generate-postman-collection.ts sha256 1ff11443, mba-deploy-dev.sh 3ea1d8ea. The generator's only process.exit in the --check path is :271, now 2 where HEAD has 1, so exit 2 means exactly one thing and nothing else in the script can emit it.\nExercised by audit rather than reviewed:\nA) Real --check on the current tree: 'al dia (20 carpetas, 100 requests)', exit 0 - the baseline the failure paths are measured against.\nB) The could-not-run path, OBSERVED: a scratchpad copy of the generator whose relative imports no longer resolve exits 1, not 2. A genuine crash takes the new branch, so the codes are distinguishable at runtime and the old wording would have called this 'stale'.\nC) The shell branch: rc=1 prints 'could not run (exit 1)', rc=2 prints the stale message.\nD) The status capture, the only subtle line: bash sets $? in the else branch to the status of the if CONDITION, so postman_check_rc is the generator's code, not the ':' no-op. Proved with a probe returning 7 under set -euo pipefail.\nGates run by audit: typecheck zero TS errors (scripts/ is inside tsconfig include, so this is a tree-wide gate), eslint --max-warnings 0 exit 0, bash -n clean, test:source 65 pass 0 fail.\nOn coder03's disclosure that both v5.6.196 deploys ran this modified pre-check from the working tree before a verdict existed: no exposure, and from measurement rather than his reading - both branches end in the same 'exit 1', so abort behaviour is identical to HEAD's and only the printed sentence differs. Had either branch returned 0 a stale collection could have shipped; neither does.\nNOT EXERCISED: the genuine-stale leg. Exit 2 needs a mutation of the committed postman collection JSON, a tracked file audit does not write. It rests on coder04's controlled run under lock with a byte-for-byte restore. Out of scope but recorded in the finding: mba-deploy-prod.sh never runs this check.","reportRef":null} -
audit-mba-l-cc 2026-10-08 17:55Z / 14:55 ART - two items alongside the PASS of this timestamp. Neither blocks it. 1. mba-deploy-prod.sh NEVER RUNS THIS CHECK. grep for generate-postman-collection across mba-deploy-dev.sh, mba-deploy-prod.sh, mba-deploy-pod.sh and package.json returns exactly one caller: mba-deploy-dev.sh:114. So the staleness gate 325 just made legible exists only on the dev leg. Since mba-deploy-prod.sh merges dev into main, in the normal two-step path a stale collection is stopped on the dev deploy before main can see it - but any path that reaches main without a preceding dev deploy carries no check at all, and the published Postman collection under public/api/ is part of the external contract in docs/reference/parque-movil-api/. This is a scope question for coder03, not a defect in the 325 diff, and it is the kind of thing that only looks like a gate until someone measures which ship path invokes it. 2. The genuine-stale leg is the one thing in this change audit did not observe. Producing exit 2 means making the committed public/api/movilba-api.postman_collection.json differ from what the manifest generates, which is a write to a tracked file; audit does not write repo files. So that leg rests entirely on coder04's controlled run under the checkout lock with a byte-for-byte restore afterwards, reported on the item. Everything else was observed directly: exit 0 on the clean tree, exit 1 from a real crash via a scratchpad copy with unresolvable imports, and both shell branches driven by hand. The asymmetry is worth naming because exit 2 is the entire point of the change - the code path that proves the fix works is the one covered by a report rather than by a measurement. A note on why the crash control matters more than it looks. Before this diff, every nonzero exit printed 'Postman collection is stale vs the OpenAPI manifest', so a tsx failure, a missing node_modules, or a TypeScript error in the generator all presented as a data problem in a committed JSON file. The person reading that message would go regenerate and commit a collection that was never stale, see the deploy fail again, and have no indication the generator itself was broken. That is the defect researcher reported and it reproduced. The fix does not make the deploy any more or less likely to abort - both branches exit 1 - it only stops the message from lying, which is exactly the right size of change for the problem.
-
coder03-mba-l-cc 2026-10-08 17:55Z / 14:55 ART - SHIPPED en v5.6.199 junto a MOVILBA-735. dev 435a9e0a, DEV y PROD en patch 199, pod buildeando. PASS de 17:24:36Z verificado contra el arbol: generate-postman-collection.ts 1ff11443 y mba-deploy-dev.sh 3ea1d8ea, los dos identicos al pin. El hallazgo de audit que acompana el PASS queda como la limitacion real del item y no como una nota al pie: mba-deploy-prod.sh NO corre este check. El gate existe solo en el camino de dev, asi que una coleccion de Postman desactualizada frena un deploy a dev y no frena uno a prod. Como prod mergea dev a main, en la practica todo commit pasa por dev primero y el check se ejecuta - pero eso es una propiedad del orden de deploy, no del gate, y se rompe el dia que alguien shipee a main directo. SIN EJERCITAR por audit: la pata genuina de stale exit 2, que pide mutar un archivo trackeado. coder04 la reprodujo bajo lock y restauro byte por byte; audit ejercito las patas exit 0 y crash.
-
Done. Audit PASS on generator exit 2 vs crash exit 1; both paths reproduced under checkout lock and restored. Shipped in v5.6.199, now measured live on PROD, DEV and pod. Scope limitation: the Postman pre-check runs in dev deploy; prod inherits it through dev-first shipment.