basquetWi + New ticket

GET /api/vehiculos/[id]/historia emite los valores crudos de validadora SUBE/OpenPass: el filtro de ocultamiento vive solo en la capa de presentacion y la ruta no la llama

Done high cmcoder04-mba-l-ca

Medido por mi contra el arbol el 2026-10-08, no tomado del reporte. src/app/api/vehiculos/[id]/historia/route.ts:41 llama toRutapHistorialItems y devuelve NextResponse.json({historial}) sin ningun filtro. src/lib/rutap-historial-api.ts:50 y :68 pasan row.valores y cambios tal cual. El set HIDDEN_PRESENTATION_FIELDS - subeValidator, subeMountingKit, openpassValidator, openpassMountingKit - vive en src/lib/rutap-history-presentation.ts:11 y solo se aplica en :52, :58 y :115, todas dentro de la derivacion de display que consumen la pantalla y el PDF. El comentario in-code de MOVILBA-589 en :8-10 lo dice explicito: 'API callers keep their existing contract'. Eso es exactamente lo que la regla dura prohibe. Entonces cualquier sesion con permiso vehiculos:read recibe el id de validadora SUBE/OpenPass y el valor de mounting kit, con etiqueta en espanol, sin gate de host - el redirect de src/proxy.ts:136 cubre /validadoras y lo que esta debajo, no esta ruta. Y esta publicada en el manifiesto OpenAPI como endpoint de contrato externo. La regla de Elazar es literal: 'hide validadoras for now, we are not going to show them, export them, etc' y el CLAUDE.md del proyecto nombra el JSON API entre las superficies. Es un defecto ROTO en prod contra una regla dura, asi que el arreglo se shipea y despues se reporta, sin GO. Es un HIDE, no una remocion: nada de DDL, no se tocan public.validadoras, public.validadoras_historial ni las cuatro columnas de vehiculos_datos_colectivos. El filtro tiene que aplicarse donde el dato sale, no en la capa de display, porque esa es la causa de que hubiera una cuarta superficie sin cubrir. Agregar un test que lo fije: hoy ningun test asserta que esta ruta no emita los cuatro campos.

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Activity

  • coder03-mba-l-cc created · 1w ago
    parent=#4105
  • coder04-mba-l-ca statusChanged · 1w ago
    API response filtering and route regression test prepared; awaiting audit.
  • coder04-mba-l-ca progress · 1w ago
    Four-path diff ready for audit. GET /api/vehiculos/[id]/historia filters subeValidator, subeMountingKit, openpassValidator and openpassMountingKit from both valores and cambios at the JSON output boundary. Display uses the same policy; stored history and validator tables are untouched. New tools/tests/vehiculo-historia-hidden-fields.test.cjs loads the real route with mocked dependencies and asserts all four fields and their values are absent from JSON while dominio survives. SHA-256: route 5bf17d56, presentation c5a271d2, policy 4e1c1f0d, test 9d24a606. git diff --check clean. Per project workflow coder has not run lint, typecheck or tests; audit to run gates and failing-before mutation.
  • coder04-mba-l-ca progress · 1w ago
    Read-only caller census after initial handoff: src/actions/vehiculos.ts:118 also returns toRutapHistorialItems(eventos) directly through a server action. The route-only filter does not cover this browser boundary. Recommend moving the shared hidden-field filter into toRutapHistorialItems, its single projection point for both non-test callers. No edit while the current SHA is under audit; awaiting verdict on scope.
  • coder04-mba-l-ca progress · 1w ago
    Revision superseding route-only 5bf17d56: move HIDDEN_VEHICLE_HISTORY_FIELDS filtering into shared toRutapHistorialItems, which is used by both GET /api/vehiculos/[id]/historia and src/actions/vehiculos.ts:118. Route returns converter output directly again. Test now loads real converter through route (previous stub would have bypassed new boundary) and seeds all four fields in valores and cambios. Pins: src/lib/rutap-historial-api.ts 238e2257; route.ts e53df545; tools/tests/vehiculo-historia-hidden-fields.test.cjs b5a0b474; shared policy 4e1c1f0d; presentation c5a271d2. No DDL/stored-data edit. Audit should see test fail with converter filter removed and pass on tree, then run gates; coder did not run gates. git diff --check clean.
  • coder04-mba-l-ca progress · 1w ago
    Producer census: toRutapHistorialItems has exactly two non-test callers, GET /api/vehiculos/[id]/historia and getVehiculoHistorial server action. Ficha page.tsx:741,1017 and PDF :1053 consume the action output; bulk export does not produce these history arrays. Detail-route historial JSONB is a separate producer covered by MOVILBA-754. Shared converter candidate remains pinned at 238e2257 with test b5a0b474; audit verdict and HTTP still owed.
  • audit-mba-l-cc audit-finding · 1w ago
    # MOVILBA-753 — audit verdict: PASS, CODE AND CONTROL. Author coder04-mba-l-ca. audit-mba-l-cc, 2026-10-08 src/lib/hidden-vehicle-history-fields.ts 4e1c1f0db960… (new, untracked) src/lib/rutap-historial-api.ts 238e2257b33b… (modified) src/lib/rutap-history-presentation.ts c5a271d2… (modified) tools/tests/vehiculo-historia-hidden-fields.test.cjs b5a0b474… (new, untracked) src/app/api/vehiculos/[id]/historia/route.ts e53df545b5b3… UNCHANGED, equal to HEAD All five re-hashed from the working tree and exact against the pins. The caller's sha equals `git show HEAD:` for the same path, so the route itself is untouched: the fix moved into the shared converter instead, which is what makes the second producer reachable. ## 1. The defect is closed at the converter, and both callers get it `toRutapHistorialItems` has exactly two non-test callers, measured by grep over `src` and `tools`: `src/app/api/vehiculos/[id]/historia/route.ts:41` and the server action `src/actions/vehiculos.ts:118`. Both now receive filtered output because the filter sits inside the converter (`rutap-historial-api.ts:51` on `valores`, `:69` on `cambios`, before the label `map`). The route-only candidate `5bf17d56` would have left the action leaking; this one does not. The presentation file's local `HIDDEN_PRESENTATION_FIELDS` is gone and its three uses (`:44`, `:50`, `:107`) now read the shared set — a move, not a behaviour change on that path: the four literals are identical to the ones the local set held. One policy, one module, four surfaces. Two further consumers of `getRutapHistorialByChain` carry no leak: `repositories/vehiculos.ts:530` and `:1757` map only `vehiculoId`, `orden`, `fechaAlta`, `tramiteNombre`, `tramite` out of each event, never `valores`, `cambios`, `raw` or `catalog`. ## 2. Gates, rc read unpiped, under the hub lock `gates-checkout-movilba-web` typecheck (next typegen + tsc --noEmit, tree-wide) rc=0 test:source rc=0, 68 pass / 0 fail test:tools rc=0, 118 pass / 0 fail eslint --no-warn-ignored, the five paths above rc=0 `test:tools` gates both ship paths (`mba-deploy-dev.sh:178`, `mba-deploy-prod.sh:61`, each `exit 1`), and the new test is in its glob, so this test is an installed gate and not a hand-run artifact. ## 3. The control was seen to fail, five ways - **Candidate test against HEAD converter bytes** (the new module left in place, `rutap-historial-api.ts` replaced by `git show HEAD:` output): **rc=1**, `AssertionError` on the `valores` deep-equal. Restored and re-hashed to `238e2257b33b…` exact. - **Four one-field mutants of the shared set**, dropping `subeValidator`, `subeMountingKit`, `openpassValidator`, `openpassMountingKit` in turn: **rc=1 on each**, so the assert covers all four and not just the first. Module restored and re-hashed to `4e1c1f0db960…` exact, candidate re-run **rc=0**. ## 4. Findings — none blocks the PASS ### 4.1 Nothing ties the four literals to `HISTORY_FIELDS`, and the test cannot catch the drift `hidden-vehicle-history-fields.ts:3` is a bare `Set` of four strings. The field names it must match are declared independently at `rutap-history-fields.ts:113` and `:164-181`, where each validator entry also carries its `column` (`sube_id_validadora`, `sube_mounting_kit`, `openpass_id_validadora`, `openpass_mounting_kit`). The new test builds its fixture from **its own copy** of the same four literals (`:51-56`), so a rename of `subeValidator` in `rutap-history-fields.ts` leaves the hidden set stale, the field exposed, and this test still green — it would be asserting about a field name nothing produces. One assert deriving the expected set from the `HISTORY_FIELDS` entries whose `column` is one of the four validadora columns closes it; `rutap-history-presentation.test.ts:206-209` and `vehiculo-pdf-history.test.ts:132-135` repeat the same four literals and inherit the same blind spot. ### 4.2 The `raw` / `catalog` leak vector is argued structurally, never exercised The repository fills `valores` from `periodHistoryValues(r)` plus a `raw` snapshot row and a `catalog` object (`rutap-historial.ts:104`, `:108-113`, `:127`). The converter projects a fixed key list and emits neither `raw` nor `catalog` — read at `rutap-historial-api.ts:47-77`. The test's whole-payload `JSON.stringify` leak assert (`:84-88`) is the right shape to catch a regression there, but its fixture `row` has no `raw` and no `catalog`, so that assert has never seen a payload carrying the raw snapshot columns. Adding `raw` with `sube_id_validadora` populated to the fixture would convert this from a reading to a measurement. ### 4.3 The server-action path is covered by construction, not by a test `src/actions/vehiculos.ts:118` is fixed because it shares the converter, and that is the whole merit of this revision over `5bf17d56`. No test drives it: the new test drives only `GET`. The ficha and PDF remain protected by the presentation filter, which is where they always were. ### 4.4 Redundant double filtering, not a defect On the action path `cambios` are filtered in the converter and again in `deriveHistoryChanges:44`. The second filter must stay: components that build candidates from repository rows rather than from the converter still depend on it, and `historyDisclosure:107` likewise. Cost is one `Set.has` per field. ## 5. NOT EXERCISED - **No HTTP, no browser, no React render, no PDF, no XLSX and no SQL.** Every figure above comes from the repo gates and from node running the one test file; nothing ran against `movilba` or `movilba_dev`. - The ficha screen and the ficha PDF were **not** re-verified for this change. Their filter moved module but not behaviour, and no test here exercises them; `rutap-history-presentation.test.ts` and `vehiculo-pdf-history.test.ts` ran inside `test:source` 68/68 but their coverage is theirs, not this verdict's. - `node --test` aborts the file on the first failing assert, so in each of the five failing runs only the first assert was observed to fire; `:81` and `:86-87` were never the failing line. - No measurement of the live API's current output on either base: whether a real vehicle's `/api/vehiculos/<id>/historia` response carries validator fields today is unmeasured, before or after. - `next build` runs on no ship path, so nothing here says anything about the production bundle. Both new files are untracked, so there is no committed revision of either to diff a later amendment against.
  • audit-mba-l-cc audited · 1w ago
    audit pass: CODE AND CONTROL, five files: hidden-vehicle-history-fields 4e1c1f0d, rutap-historial-api 238e2257, rutap-history-presentation c5a271d2, tests/vehiculo-historia-hidden-fields b5a0b474, caller historia/route e53df545 UNCHANGED = HEAD. Gates typecheck/source/tools/eslint. NO HTTP, NO PDF, NO SQL.
    payload
    {"scope":"CODE AND CONTROL, five files: hidden-vehicle-history-fields 4e1c1f0d, rutap-historial-api 238e2257, rutap-history-presentation c5a271d2, tests/vehiculo-historia-hidden-fields b5a0b474, caller historia/route e53df545 UNCHANGED = HEAD. Gates typecheck/source/tools/eslint. NO HTTP, NO PDF, NO SQL.","outcome":"pass","evidence":"audit-mba-l-cc, 2026-10-08. PASS. Author coder04-mba-l-ca. Five pins re-hashed exact; the caller's sha equals git show HEAD: for its path, so the route is untouched and the fix lives in the shared converter.\n\nCLOSED AT THE CONVERTER, BOTH PRODUCERS. toRutapHistorialItems has exactly two non-test callers by grep over src+tools: historia/route.ts:41 and the action actions/vehiculos.ts:118. The filter is inside the converter - rutap-historial-api.ts:51 on valores, :69 on cambios before the label map - so the action is covered, which the route-only candidate 5bf17d56 missed. Presentation's local HIDDEN_PRESENTATION_FIELDS is gone and its three uses (:44, :50, :107) read the shared set, same four literals: a move, not a behaviour change there.\n\nGATES, rc unpiped, under the lock: typecheck 0 tree-wide, test:source 68/68, test:tools 118/118, eslint 0 on the five paths. test:tools gates both ship paths (dev:178, prod:61) and the new test is in its glob, so it is an installed gate.\n\nCONTROL SEEN TO FAIL, 5 WAYS. Candidate test against HEAD converter bytes, new module left in place: rc=1, AssertionError on the valores deep-equal; restored, re-hashed 238e2257 exact. Four one-field mutants, each validator field dropped in turn: rc=1 on all four, so the assert covers all four and not just the first; module restored, re-hashed 4e1c1f0d exact, candidate rc=0.\n\nFINDING in the note, does not block: nothing ties the four literals to HISTORY_FIELDS. The set is bare strings; the names are declared at rutap-history-fields.ts:113 and :164-181, and the test builds its fixture from ITS OWN copy (:51-56), so a rename there leaves the set stale, the field exposed, and this test green.\n\nSIN EJERCITAR: no HTTP, browser, React render, PDF, XLSX or SQL; neither base touched. Ficha and PDF not re-verified. The whole-payload leak assert has never seen a payload with raw/catalog - the fixture row has neither, so that vector is read off the projection. node aborts on the first assert, so only","reportRef":null}
  • coder03assistant-mba-l-ca note · 1w ago
    Read-only control measurement: in an isolated in-memory source mutant, renamed HISTORY_FIELDS field subeMountingKit -> subeMountingKitRenamed; tools/tests/vehiculo-historia-hidden-fields.test.cjs still PASS (1/1, exit 0). The history-field registry, hidden-field literal set, and test fixture literals are independent; this test never loads/asserts HISTORY_FIELDS membership. Smallest fail-loud fix: assert in this test that every hidden key exists in HISTORY_FIELDS (or derive the hidden test cases from the registry plus the hide classification), so renaming a canonical history key makes the gate fail. No shared checkout writes.
  • coder03assistant-mba-l-ca note · 1w ago
    Implementation ready for scoped audit. Files: src/lib/rutap-history-fields.ts (adds hiddenFromVehicleHistory classification to the four canonical definitions), src/lib/hidden-vehicle-history-fields.ts (derives the shared hidden set from HISTORY_FIELDS), tools/tests/vehiculo-historia-hidden-fields.test.cjs (API test cases now derive from registry classification). Candidate SHA256: rutap-history-fields 89fbc16159e00c11220164594dec6923e66cc630d09df839340e0e2302e61cfe; hidden module 62347c509497c93f989c79dd7baaf81a3e0d855c15788213159caec45d5719d4; test aaafcb6bc05659093df8136d9cb18e09971e260cfa93a25756cc0eb327521c47. On unmutated candidate: targeted test 2/2 pass. In-memory regression mutant renamed subeMountingKit in HISTORY_FIELDS but retained stale old hidden set: corresponding test failed, leaking the renamed field (expected). No shared checkout files besides these targets changed by this work; no lint/typecheck run.
  • coder03assistant-mba-l-ca note · 1w ago
    Final 753 guard scope, supersedes prior combined-test note: code src/lib/rutap-history-fields.ts SHA256 89fbc16159e00c11220164594dec6923e66cc630d09df839340e0e2302e61cfe; src/lib/hidden-vehicle-history-fields.ts SHA256 62347c509497c93f989c79dd7baaf81a3e0d855c15788213159caec45d5719d4; test tools/tests/vehiculo-historia-hidden-fields.test.cjs SHA256 9d3a716afbd0e27a35edcdc63111c5284229bbdfa5b79f5955833091923592dd. Cases derive from HISTORY_FIELDS entries marked hiddenFromVehicleHistory; shared hide set derives from same metadata. Current targeted file PASS 1/1. Mutant renaming subeMountingKit in registry while retaining stale old-name hide set FAILS, exposing leaked subeMountingKitRenamed. No lint/typecheck run.
  • audit-mba-l-cc audit-finding · 1w ago
    # MOVILBA-753 — audit verdict: PASS, HUNK-SCOPED. Author coder03assistant-mba-l-ca. audit-mba-l-cc, 2026-10-08 src/lib/rutap-history-fields.ts 89fbc16159e00c11220164594dec6923e66cc630d09df839340e0e2302e61cfe src/lib/hidden-vehicle-history-fields.ts 62347c509497c93f989c79dd7baaf81a3e0d855c15788213159caec45d5719d4 tools/tests/vehiculo-historia-hidden-fields.test.cjs 9d3a716afbd0e27a35edcdc63111c5284229bbdfa5b79f5955833091923592dd Base is `dev` `353eff10` (the MOVILBA-59 ship), NOT `a7da6ffe`: the ship landed between the request and my gates. `git diff a7da6ffe..353eff10` touches five paths — the 59 migration file, `package.json`/`package-lock.json` (5.6.220 -> 5.6.221), `tools/rutap-snapshot-import.py`, `tools/verification/movilba-59-manifest-notices.py` — and is **disjoint from everything this verdict covers**, so the gates and the ship do not interact. An earlier run of mine measured the superseded test pin `aaafcb6b` and is not cited here; the 22:31 repin to `9d3a716a` moved the 754 case out to its own file, and everything below was re-measured on these bytes. All four pins re-hashed exact in the checkout immediately before and after the gate run, with `gates-checkout-movilba-web` HELD for that run (acquired 22:33, released 22:37) and `git status --porcelain tsconfig.json` empty after `next typegen`, so audit wrote nothing. Every mutant ran in a FROZEN COPY of the tree (`scratchpad/v753`), never in the shared checkout; `src/lib/transformers.ts` `be00b693` and `src/app/api/vehiculos/[id]/route.ts` `358982db` are byte-identical to the checkout after each one. ## 1. The hunk, and what it closes `hiddenFromVehicleHistory?: boolean` is added to `HistoryFieldDefinition` (`:19`) and set `true` on the four validator entries (`:168,174,180,186`); `HIDDEN_VEHICLE_HISTORY_FIELDS` is now derived by filtering `HISTORY_FIELDS` on that flag instead of repeating four string literals. Both consumers — `rutap-historial-api.ts:51,69` (published history API) and `rutap-history-presentation.ts:44,50,107` (screen + ficha PDF) — read the derived set, and no third copy of the list survives anywhere in `src/` or `tools/`. This closes the limit I registered with the 753/754 PASS of 00:52:06.914Z: a rename can no longer leave a stale filter. **Measured, not argued** — `field` is typed `RutapHistoryChange["field"]`, a closed union (`rutap-modification-subtype.ts:18`), so a one-sided rename is a type error: pinned bodies tsc rc=0 subeValidator renamed in rutap-history-fields tsc rc=2, TS2322 x2 at :177 and :183 ## 2. The classification is now self-referential, and the policy pin moved The test derives its probe fields from the same flag it tests (`:51-54`), so **dropping `hiddenFromVehicleHistory` from one field cannot fail it**. Forced on these exact bytes: flag dropped from subeValidator only historia + detail tests 3 pass / 0 fail rc=0 and that mutant **does leak**: a probe of mine with the four names written literally saw `SECRET-subeValidator` cross the JSON border of `/api/vehiculos/[id]/historia` (`rutap-historial-api.ts:51`) and the derived set come back as three names. The `assert.ok(validatorFields.length > 0)` guard only catches dropping ALL four. **The hole is closed by the suite, not by this test, and that closure is gated.** Two `src/**/*.test.ts` files pin the four names literally and assert they are withheld — `rutap-history-presentation.test.ts:205` and `vehiculo-pdf-history.test.ts:131` — and `test:source` gates both ship paths (`mba-deploy-dev.sh:175`, `mba-deploy-prod.sh:59`, each `exit 1`). Forced on the frozen copy, same mutant: pinned bodies presentation + pdf 6 pass / 0 fail rc=0 flag dropped from subeValidator only presentation + pdf 4 pass / 2 fail rc=1 So the per-field validadora policy survives this refactor, but it now rests entirely on those two files, and **no test pins the four names against the API surface itself**. If either file is deleted or relaxed, nothing replaces it there. One `assert.deepEqual` of the derived set against the four literals, in this file, would put the pin back where the refactor took it from. Not a FAIL: the gate exists today and I saw it fail. ## 3. Gates, run by me on the checkout bytes, under the lock pnpm typecheck rc=0 pnpm test:source rc=0, 68 pass / 0 fail pnpm test:tools rc=0, 119 pass / 0 fail pnpm exec eslint (the two .ts files) rc=0 `eslint` reports `tools/tests/*.cjs` as **ignored by config**, so no lint rule covers the test file on any path; `lint:strict` runs on no ship path at all. ## 4. NOT EXERCISED - No HTTP, no browser, no PDF, no XLSX, no ficha, no SQL, neither base read. The history API was reached only through the in-process `vm` loader with `auth`, `rbac`, the repository and `NextResponse` mocked. - `next build` ran on no path here. - Each mutant was forced alone; `node --test` reports one assert per file, so a combined mutant would have left later asserts a green line. - A rename applied in BOTH `rutap-modification-subtype.ts:18` and `rutap-history-fields.ts` typechecks and leaves the four literals in `HISTORY_FIELD_DISPLAY_ORDER:114` stale; that array is `readonly string[]`, so the stale entry silently drops the field's display rank to `MAX_SAFE_INTEGER`. Pre-existing, outside this hunk, no gate. - Two files failed in my frozen copy (`src/db/vehiculo-subtipo-label.test.ts`, `tools/import/subtipo-projector-source.test.ts`) and are HARNESS ARTIFACTS, not results: the same suite is 68/68 in the checkout.
  • audit-mba-l-cc audited · 1w ago
    audit pass: CLASSIFICATION HUNK on dev 353eff10: rutap-history-fields 89fbc161, hidden-vehicle-history-fields 62347c50, test 9d3a716a (supersedes aaafcb6b). Gates typecheck/test:source/test:tools/eslint under the checkout lock, plus 3 mutants in a frozen copy. NO HTTP, no PDF, no SQL, no next build.
    payload
    {"scope":"CLASSIFICATION HUNK on dev 353eff10: rutap-history-fields 89fbc161, hidden-vehicle-history-fields 62347c50, test 9d3a716a (supersedes aaafcb6b). Gates typecheck/test:source/test:tools/eslint under the checkout lock, plus 3 mutants in a frozen copy. NO HTTP, no PDF, no SQL, no next build.","outcome":"pass","evidence":"audit-mba-l-cc 2026-10-08. PASS. Author coder03assistant. 4 pins re-hashed exact before AND after the gates, lock gates-checkout-movilba-web HELD 22:33-22:37, tsconfig unchanged after next typegen, mutants only in a frozen tree copy (transformers be00b693, [id]/route 358982db byte-identical after each).\n\nBASE CORRECTION: dev 353eff10, not a7da6ffe - the MOVILBA-59 ship landed mid-review, and diff a7da6ffe..353eff10 (59 migration, 2 tool files, bump) is DISJOINT from this. My earlier run measured the superseded test pin aaafcb6b and is NOT cited.\n\nCLOSES, MEASURED: the 4 validator entries carry hiddenFromVehicleHistory, the set derives from HISTORY_FIELDS, both consumers read it (rutap-historial-api:51,69; rutap-history-presentation:44,50,107), no third copy in src/ or tools/. Rename anchor is typecheck, seen to fail: pinned rc=0, one-sided rename rc=2 TS2322 x2.\n\nLIMIT, MEASURED, NOT A FAIL: the test derives its probe from the flag it tests, so dropping the flag from ONE field is 3 pass/0 fail rc=0 while my literal-name probe saw SECRET-subeValidator cross the JSON border of /api/vehiculos/[id]/historia. Closed ELSEWHERE and GATED: presentation.test:205 and vehiculo-pdf-history.test:131 pin the 4 names literally, test:source gates both paths (dev:175, prod:59); same mutant there = pinned 6 pass/0 fail, mutant 4 pass/2 fail rc=1. The pin MOVED, it did not vanish - and nothing pins those names on the API surface itself.\n\nGATES: typecheck rc=0; test:source 68/68; test:tools 119/119; eslint rc=0 on the two .ts. tools/tests/*.cjs is IGNORED by eslint config; lint:strict runs on no ship path.\n\nNOT EXERCISED: no HTTP, browser, PDF, XLSX, ficha or SQL, neither base read; no next build; each mutant forced alone, node --test shows one assert per file; a rename in BOTH places typechecks and leaves DISPLAY_ORDER:114 stale, pre-existing and ungated. Two frozen-copy failures are HARNESS ARTIFACTS: 68/68 in the checkout.","reportRef":null}
  • coder03assistant-mba-l-ca note · 1w ago
    753 re-pin, test guard only. tools/tests/vehiculo-historia-hidden-fields.test.cjs SHA256 aa8e419df3ded9874f85ec51902912b976b17a5d5525c25731be202dbcc4883d; only change is cardinality assert (expected 4), preserving field-name derivation from HISTORY_FIELDS. Focused test current bytes: 1/1 pass. Mutant removed one hiddenFromVehicleHistory flag: test fails at cardinality (3 !== 4), exit 1. Classification source unchanged at 89fbc161; rerun request is limited to this 753 test guard.
  • coder03assistant-mba-l-ca note · 1w ago
    753 final guard re-pin: tools/tests/vehiculo-historia-hidden-fields.test.cjs SHA256 0682fa4145f0692aeb64df20a0734839612d584bf73edb4a2980d6f6f137f38f. Supersedes prior count-only pin aa8e419d. Added deepEqual from derived HISTORY_FIELDS hidden fields to the four expected names; no classification or 754 changes. Focused test passes 1/1 on candidate. One-sided mutant removing subeValidator hiddenFromVehicleHistory fails the derived-set assertion (3 names vs expected 4), exit 1.
  • coder03assistant-mba-l-ca note · 1w ago
    Exact handoff scope reverified under checkout lock: src/lib/rutap-history-fields.ts SHA256 89fbc16159e00c11220164594dec6923e66cc630d09df839340e0e2302e61cfe; src/lib/hidden-vehicle-history-fields.ts SHA256 62347c509497c93f989c79dd7baaf81a3e0d855c15788213159caec45d5719d4; tools/tests/vehiculo-historia-hidden-fields.test.cjs SHA256 0682fa4145f0692aeb64df20a0734839612d584bf73edb4a2980d6f6f137f38f. The test now deepEquals derived hidden names to the four expected names. Candidate focused test passes 1/1. Mutant removing subeValidator's flag fails at deepEqual (actual 3 fields), exit 1. No other file/hunk changed in this revision.
  • audit-mba-l-cc audit-finding · 1w ago
    # MOVILBA-753 — audit RE-VERDICT: PASS. Author coder03assistant-mba-l-ca. audit-mba-l-cc, 2026-10-08 src/lib/rutap-history-fields.ts 89fbc16159e00c11220164594dec6923e66cc630d09df839340e0e2302e61cfe src/lib/hidden-vehicle-history-fields.ts 62347c509497c93f989c79dd7baaf81a3e0d855c15788213159caec45d5719d4 tools/tests/vehiculo-historia-hidden-fields.test.cjs 0682fa4145f0692aeb64df20a0734839612d584bf73edb4a2980d6f6f137f38f **This SUPERSEDES my PASS on `9d3a716a`.** Base is still `dev` `353eff10`. The two source files are BYTE-UNCHANGED from that verdict; the delta is test-only and is the one assert I asked for. The intermediate pin `aa8e419d` was never verdicted and is not cited. coder03 withheld the ship on my limit rather than on a FAIL, and the limit is now closed and SEEN TO CLOSE. ## 1. The limit I named, and that it is gone The previous test derived its probe fields from the same flag it tested, so dropping `hiddenFromVehicleHistory` from ONE field could not fail it — measured then at 3 pass / 0 fail while `SECRET-subeValidator` crossed the JSON border of `/api/vehiculos/[id]/historia`. `:61-65` now asserts the derived hidden names against the four expected names written literally. Forced on these exact bytes, frozen copy, one mutant at a time: pinned bodies rc=0, 1 pass / 0 fail flag dropped from subeValidator ONLY rc=1, actual 3 names vs expected 4 BOTH-SIDED rename subeValidator -> subeValidadorSube (4 files) rc=1, actual carries the new name The second line is the hole from the previous verdict, now red. The third closes a SECOND limit I had recorded as open: a rename applied in both `rutap-modification-subtype.ts` and `rutap-history-fields.ts` typechecks clean and leaves the `HISTORY_FIELD_DISPLAY_ORDER:114` literal stale (rank falls to `MAX_SAFE_INTEGER`). The new assert fails on it, so the stale-rank hazard is no longer silent. That is more than was asked for. ## 2. New limit, measured, and it is the opposite failure mode `assert.deepEqual` on an ARRAY is order-sensitive, and the derived order is the DISPLAY rank, not the policy. Swapping two names inside `HISTORY_FIELD_DISPLAY_ORDER:114` — a pure presentation reorder that leaks NOTHING — fails the test: "subeMountingKit", "subeValidator", ... (flags untouched) rc=1 So the test now also fails on a correct change. A `[...].sort()` on both sides, or a Set comparison, would keep every leak it catches and drop this false positive. Not a FAIL and not a ship blocker: a test that is too eager is a maintenance cost, while the hole it replaced was a leak. Worth one follow-up line, not a hold. ## 3. Unchanged from the superseded verdict, re-confirmed on these bytes - `HIDDEN_VEHICLE_HISTORY_FIELDS` is derived by filtering `HISTORY_FIELDS`; both consumers (`rutap-historial-api.ts:51,69`, `rutap-history-presentation.ts:44,50,107`) read the derived set and no third copy of the list exists in `src/` or `tools/`. - One-sided rename is a type error: `field: RutapHistoryChange["field"]` is a closed union — pinned `tsc` rc=0, one-sided rename rc=2 with `TS2322` x2. - The two `src/**/*.test.ts` files that pin the four names literally (`rutap-history-presentation.test.ts:205`, `vehiculo-pdf-history.test.ts:131`) still hold the per-field policy on the presentation side; `test:source` gates both ship paths (`mba-deploy-dev.sh:175`, `mba-deploy-prod.sh:59`). With this re-pin the API side now has its own literal pin too, which it did not before. - `eslint` reports `tools/tests/*.cjs` as IGNORED BY CONFIG: no lint rule covers this file on any path, and `lint:strict` runs on no ship path at all. ## 3b. Gates, and one disclosure about the tree they ran on pnpm typecheck rc=0 pnpm test:source rc=0, 68 pass / 0 fail pnpm test:tools rc=0, 119 pass / 0 fail pnpm exec eslint (the two .ts files) rc=0 All four pins re-hashed EXACT immediately before and after, `gates-checkout-movilba-web` HELD for the run. **Disclosure:** the checkout's `tsconfig.json` is dirty, at `7dff8dae43b80fac666dcb47cf95ab76c8a1a77173a61e0aa7c85f5c7fd65fce` — which is coder04's MOVILBA-768 candidate pin, carrying `"exclude": [... , "tools"]`. It is NOT my `next typegen` output and it is UNVERDICTED, so my typecheck ran on a tree holding another lane's pending change. It does not reach this verdict, and that is measured rather than assumed: `tsc --noEmit --listFiles` lists BOTH `src/lib/rutap-history-fields.ts` and `src/lib/hidden-vehicle-history-fields.ts`, so the rc=0 does cover these bytes. The test file is `.cjs` and is never typechecked under either tsconfig. ## 4. NOT EXERCISED - No HTTP, no browser, no PDF, no XLSX, no ficha, no SQL, neither base read. The route was reached only through the in-process `vm` loader with `auth`, `rbac`, the repository and `NextResponse` mocked. - `next build` on no path. - `node --test` reports one assert per file, so each mutant was forced ALONE; a combined mutant would have left the later asserts a green line. - Still ungated, outside this hunk: nothing ties the four literals in `HISTORY_FIELD_DISPLAY_ORDER:114` to `HISTORY_FIELDS` by type — that array is `readonly string[]`. - The 754 bytes (`vehiculo-detail-hidden-fields.test.cjs` `00f1147a`) are unchanged and keep their own PASS.
  • audit-mba-l-cc audited · 1w ago
    audit pass: RE-VERDICT, SUPERSEDES my PASS on 9d3a716a. Test-only delta: vehiculo-historia-hidden-fields.test.cjs 0682fa41; the two src files are byte-unchanged at 89fbc161 / 62347c50. Base dev 353eff10. Gates + 3 mutants in a frozen copy. aa8e419d never verdicted. No HTTP, no SQL, no next build.
    payload
    {"scope":"RE-VERDICT, SUPERSEDES my PASS on 9d3a716a. Test-only delta: vehiculo-historia-hidden-fields.test.cjs 0682fa41; the two src files are byte-unchanged at 89fbc161 / 62347c50. Base dev 353eff10. Gates + 3 mutants in a frozen copy. aa8e419d never verdicted. No HTTP, no SQL, no next build.","outcome":"pass","evidence":"Pins re-hashed exact before and after, gates-checkout-movilba-web HELD. Gates: typecheck rc=0, test:source 68/68, test:tools 119/119, eslint on the two .ts rc=0.\nTHE LIMIT I NAMED IS CLOSED AND SEEN TO CLOSE. The old test derived its probe from the same flag it tested, so a one-field flag drop was 3 pass / 0 fail while SECRET-subeValidator crossed the JSON border. :61-65 now asserts the derived hidden names against four literals. Mutants forced one at a time on these exact bytes: pinned rc=0 1/1; flag dropped from subeValidator ONLY rc=1 (3 vs expected 4); BOTH-SIDED rename subeValidator -> subeValidadorSube across 4 files rc=1.\nThe third closes a SECOND limit I had left open: a both-sided rename typechecks clean and leaves the HISTORY_FIELD_DISPLAY_ORDER:114 literal stale, dropping that rank to MAX_SAFE_INTEGER. Now red.\nNEW LIMIT, measured, opposite failure mode: deepEqual on an ARRAY is order-sensitive and the derived order is the DISPLAY rank, not the policy. Swapping two names inside :114 - a pure reorder that leaks nothing - gives rc=1. A .sort() on both sides or a Set keeps every leak it catches and drops the false positive. Not a ship blocker: too eager is a maintenance cost, the hole it replaced was a leak.\nDISCLOSURE: the checkout's tsconfig.json is dirty at 7dff8dae, coder04's UNVERDICTED 768 pin carrying exclude:[tools]. Not my typegen output, and it does not reach this verdict - measured, not assumed: tsc --listFiles lists BOTH 753 source files, so rc=0 covers these bytes; the .cjs is never typechecked either way.\nNOT EXERCISED: no HTTP, no browser, no PDF, no XLSX, no ficha, no SQL, neither base read - the route was reached only through the vm loader with auth, rbac, repository and NextResponse mocked. next build on no path. Each mutant forced ALONE since node --test reports one assert per file. Still ungated: nothing ties those four literals to HISTORY_FIELDS by type, and eslint ignores tools/tests/*.cjs everywhere.","reportRef":null}
  • audit-mba-l-cc audit-finding · 1w ago
    WITHDRAWAL of the .sort()/Set suggestion in my PASS of 01:49, and the reason is a measurement I had not run. My mutant B used a blanket token replace, so it renamed the HISTORY_FIELD_DISPLAY_ORDER:114 literal too - :114 was never stale in it, and the test failed only because its OWN literal still held the old name. So my claim that B closed the stale-rank limit was reasoning from the wrong cause. Mutant D, the realistic case, forced on the pinned bytes in the frozen copy: rename subeValidator -> subeValidadorSube in rutap-modification-subtype.ts, in the definitions, in BOTH src tests and in the .cjs literal, and leave ONLY :114 behind. D, assert as written (order-sensitive) rc=1, actual puts the renamed field LAST D, with .sort() on both sides rc=0, stale rank NOT detected The renamed field falls to MAX_SAFE_INTEGER and sorts last; the order-sensitive deepEqual is the ONLY thing that sees it. A .sort() or a Set would silence exactly that. So what I called a false positive in the display-order reorder is the PRICE of catching a stale :114, not a defect - the suggestion is withdrawn and the assert should stay order-sensitive. The PASS and the ship are unaffected; this corrects the follow-up, not the verdict. DISCLOSURE completed, measured after the verdict: all FOUR MOVILBA-768 files are live in the shared checkout at 768's declared pins - package.json cda4b15b, mba-deploy-dev.sh 657f0527, mba-deploy-prod.sh ce83083d, tools/typecheck-tracked-tools.mjs 88d0b705 - not just tsconfig.json. The confound is bounded and that is measured too: 768's package.json diff ADDS typecheck:tools and leaves the definitions of typecheck, test:source and test:tools byte-identical to HEAD, so the three commands I ran are the same commands. tsconfig.json's exclude:[tools] does change what tsc compiles, and tsc --listFiles shows both 753 sources still in the set.
  • coder03-mba-l-cc completed · 1w ago
  • coder03-mba-l-cc verified · 1w ago
    Shipped and LIVE on both surfaces. dev ec6a1b94/patch 222, prod main merged and app.movilba.com/api/health answers serviceId 31325 = patch 222, probed 2026-10-08 23:33 ART. Root cause of the earlier 221 reading: the post-receive hook on /srv/movilba-web.git runs synchronously inside the push and my push was killed by a 2-minute timeout at 23:15:55, exactly when pnpm build finished writing BUILD_ID - so the hook never reached its restart stage (deploy.json has install and build entries and NO restart entry) and next-server kept serving the 221 build from 22:28. Fixed by completing the hook step the kill skipped: systemctl restart movilba-web.service. SIN EJERCITAR: only the health route was probed; no screen, PDF, XLSX or pod. POD leg still owed.
  • coder03-mba-l-cc note · 1w ago
    CORRECCION que supersede mi evento de 02:21:46Z: el SHA de dev esta mal escrito ahi. dev = ec4b68642158f9bba09edbeb5562c34a8ecbd790 (ec4b6864), NO ec6a1b94, que no es un objeto de este repo. prod main = 3dd4b3ec971026c2c5dbb6ebb298aa734938bc05. Todo lo demas de ese evento se sostiene sin cambios: prod responde serviceId 31325 = patch 222 y la causa del 221 fue la etapa restart del hook que el kill de los 2 minutos salteo.
  • coder03-mba-l-cc verified · 1w ago
    FLEET PARITY alcanzada: las TRES superficies sirven patch 222. prod app.movilba.com serviceId 31325 (23:33 ART), dev01 ya estaba en 222 por el deploy, y el pod permisos-movilba-dev.gcba.gob.ar devolvio 31325 a las 23:31 ART despues de que Tekton terminara - mba-deploy-pod.sh espejo el arbol de dev ec4b6864 a repositorio-asi, force-push fe6d299 -> b5feafd en develop y EventListener HTTP 202. Las dos primeras sondas al pod a las 23:27 y 23:28 devolvieron 31188 (patch 221) y eso era el pipeline todavia corriendo, no una falla: no hay sesion de oc para mirar los builds (oc whoami da Unauthorized, el token sale de la consola OCP y eso es Elazar en el navegador), asi que el pipeline no se observo, solo su resultado. SIN EJERCITAR en las tres superficies: ninguna pantalla, PDF, XLSX ni consulta - la unica ruta probada es /api/health.
bug
1w ago by coder03-mba-l-cc
1w ago
2026-10-09 02:21