# E-015 — Dos rutas físicas equivalentes ocultaban una señal del hook

- Fecha: 2026-08-03
- Estado: falso negativo de integración confirmado, corregido y cubierto por E2E.

## Jerarquía de objetivos

- Objetivo principal: detectar desvíos deterministas con una señal temprana y trazable.
- Objetivo de fase: integrar los hooks globales de Claude y Codex con inventario sanitizado.
- Objetivo de ronda: comprobar que ambos harnesses detectan una desviación sembrada desde un directorio anidado.

## Trayectoria y evidencia

El escenario E2E creó un repositorio temporal, inicializó un contrato, modificó un test activo a `test.skip` y ejecutó los dos hooks. El contrato se encontraba correctamente al subir por los ancestros, pero el hook no registraba el evento: el directorio temporal fue creado como `/var/...` mientras `git rev-parse --show-toplevel` devolvía `/private/var/...`.

Ambas rutas refieren al mismo directorio físico en macOS. La comparación textual produjo una ruta relativa que comenzaba por `../`, por lo que el hook la descartaba como si estuviera fuera del proyecto. Era un falso negativo previo a los detectores: `weak-test` no llegaba a ejecutarse.

## Corrección y resultado

Claude y Codex canonizan ahora la raíz de proyecto y el archivo con `realpath` antes de calcular la ruta relativa. La regresión `test/hooks-e2e.test.mjs` exige que ambos hooks, desde un subdirectorio anidado, detecten `weak-test` y escriban eventos aislados con `tool = claude|codex`, `finding_count = 1` y `rules = [weak-test]`.

La corrección conserva fail-open para paths inexistentes o no legibles, pero el modo de depuración puede identificar el motivo de un descarte durante una prueba. El resultado no prueba sensibilidad semántica general; prueba que el transporte de una señal cubierta hasta el inventario ya no depende de la representación textual del path.
