# Usar Radar oHOS desde un agente · referencias 0.4

## Alcance operativo

Entrada humana y para agentes con navegador: https://radaroperador.com/agentes
Entrada por HTTP: https://radaroperador.com/data/catalogo.json
Contrato HTTP publicado: https://radaroperador.com/openapi.json

Sin cuenta, claves ni credenciales privadas. Este documento trata las referencias y capturas del operador. **No son consultas al inventario en vivo.** Para preparar una investigación NUEVA y analizar evidencia de un agente externo, sigue [operacion.md](/agentes/operacion.md); capacidades, encargos y análisis tienen un contrato distinto del catálogo.

`GET /api/v1/referencias` lee el catálogo almacenado y declara su origen en `retrieval`; el GET no navega ni refresca fuentes upstream. La función programada de cuatro fuentes directas es independiente. Su ejecución se acredita con registros y fechas de captura, no por abrir la página. Las rutas `/data/*` siguen siendo capturas estáticas. El contrato vigente completo es `/openapi.json`; `/openapi-preparado.json` es un archivo de referencia histórica.

## Recorrido con navegador

1. Abre `/agentes`, elige alojamiento, llegada, salida y adultos.
2. Pulsa “Consultar captura”. El cálculo usa el mismo módulo que el explorador público.
3. Abre “Ver respuesta estructurada completa” o descarga el JSON.
4. Cita `source`, `generatedAt`, `provenance.checkedAt` y `provenance.sourceUpdatedAt`. El enlace de la consulta conserva sus parámetros; puede reflejar una captura más nueva tras otra publicación, por lo que conserva también el JSON si necesitas reproducibilidad exacta.

Ejemplo: https://radaroperador.com/agentes?property=plaza-chihuahua&checkin=2026-10-12&checkout=2026-10-14&guests=2

## Recorrido por HTTP sin navegador

Para la última referencia almacenada, usa `GET /api/v1/referencias`. Puedes pasar `alojamiento`, `llegada`, `salida` y `adultos`; cuando uses fechas, incluye ambas. El GET no recibe links arbitrarios ni categorías, no crea investigaciones y no obliga al recolector a realizar una nueva lectura. Revisa `retrieval.source` y `retrieval.error`: una semilla de respaldo debe seguir presentándose como captura histórica. Los parámetros del formulario de capturas (`property`, `checkin`, `checkout`, `guests`, `category`) no son los del endpoint.

Para una captura reproducible publicada como archivo:

```sh
curl --fail --silent --show-error https://radaroperador.com/data/catalogo.json
```

Descarga una vez por tarea y reutiliza localmente el catálogo para todas las fechas. La URL estática no admite filtros; añadir parámetros no cambia el contenido. Los agentes con ejecución JavaScript pueden revisar y reutilizar `/reference.mjs` (exporta `stayDates`, `referenceFor`, `publicQuery`). El módulo no solicita datos ni modifica cuentas. `/agent-query.mjs` añade validación de ID y la etiqueta de captura publicada.

### Identificadores

- `plaza-chihuahua`: habitación de hotel, propuesta publicada, 1–2 adultos cubiertos.
- `casa-coronel`: habitación de hotel, instantánea anterior a impuestos, ocupación incluida sin confirmar.
- `casa-altamar`: casa completa, base publicada; revisar mínimo de huéspedes y noches.
- `casa-marvela`: villa completa, base publicada.
- `el-ganzo`: ficha editorial sin precio conectado.

No devuelvas cero por un ID desconocido: informa “alojamiento no encontrado”.

### Fechas e importes

Fechas civiles ISO `YYYY-MM-DD`, llegada inclusiva y salida exclusiva. Entre 1 y 30 noches; 1–12 adultos, sin menores, una habitación o casa completa, MXN. La capacidad de una categoría no demuestra la ocupación incluida en su tarifa.

Para `published_proposal` o `dated_snapshot`:

1. Filtra categorías por su capacidad; cuando exista `includedGuests`, no asumas suplementos si la solicitud lo supera.
2. Selecciona **todas** las noches solicitadas en `data.calendar[fecha][categoryId]`. Si falta alguna, responde sin referencia para esa estancia; nunca rellenes ceros, repitas la noche anterior ni interpoles.
3. Cada valor ya está en pesos MXN. Para sumar con precisión, convierte cada noche a centavos una vez (`Math.round(amount*100)`), suma y divide entre 100 al devolver el total. Promedio = suma de centavos / noches, redondeado al centavo.
4. Mantén `taxesIncluded` y `breakfastIncluded`. `null` significa no informado. No agregues otra vez impuestos si ya están incluidos.
5. Para Coronel, conserva `quotedAdults:null` y `guestMatch:"unknown"`; es referencia incompleta. No certifiques precio para los adultos solicitados.
6. Conserva `binding:false` y `availability:"unknown"`.

Para `published_base`, no construyas un total por fechas sumando solo noches y limpieza: pueden existir descuentos, estacionalidad y suplementos no resueltos. Muestra la base y sus condiciones como referencia. Un bloqueo tampoco prueba ocupación ni demanda; la ausencia de bloqueo no acredita disponibilidad.

## Prueba reproducible

https://radaroperador.com/data/ejemplo-agente.json identifica la captura mediante SHA256, conserva `catalogGeneratedAt` y contiene entrada y salida esperada. Caso: Plaza, King, del 12 al 14 de octubre de 2026, dos adultos. Si una nueva publicación cambia el catálogo, usa el ejemplo que se publicó con ella. La fecha de generación del ejemplo nunca renueva la fecha del precio original.

Casos negativos: una estancia sin noches completas debe devolver `no_dates`; tres adultos en la propuesta de Plaza, `guest_restriction`; El Ganzo, `no_data`; un ID desconocido, error. Son límites de cobertura, no señales de demanda.

## Entrega de un informe útil

Incluye: alojamiento y categoría, noches y adultos, importes y moneda, impuestos/desayuno/cancelación cuando estén informados, tipo de referencia, fechas de lectura y origen, disponibilidad conocida o desconocida, enlaces citables y limitaciones.

No calcules promedio de mercado ni recomiendes subir/bajar precios con esta muestra. No mezcles villas completas con habitaciones, propuestas con cotizaciones finales, impuestos incluidos con excluidos o tarifas para distinta ocupación. Este catálogo no tiene conectadas tarifas de Booking, Expedia o Airbnb. Existe, por separado, una lectura puntual en navegador de Airbnb y Vrbo en /comparar; consulte /agentes/observaciones.md.

Los derechos están en `rights` de cada fuente. Acceso de consulta pública no equivale a una licencia comercial de redistribución ilimitada. La página no publica servidor MCP ni autoriza acciones sobre reservas o pagos.

## Antigüedad y transporte

`collection.status:"ok"` acredita la lectura pasada, no su vigencia presente. Considera pendiente de actualizar una captura cuyo `checkedAt` falte o tenga más de 24 horas. Conservar `sourceUpdatedAt` y advertir su desfase sigue siendo obligatorio aunque Radar haya leído la fuente hoy. Para `data.blocks`, el cálculo solo orienta sobre bloqueos si tanto `checkedAt` como `sourceUpdatedAt` tienen menos de 15 minutos; después informa disponibilidad desconocida.

Los recursos HTTP se pueden leer desde un agente en servidor o desde el navegador dentro de Radar. No hay CORS para que una web de otro dominio haga fetch directamente. No se requiere esa función para leer el catálogo con un cliente HTTP.

## Mejoras verificadas con agentes — 0.2.2

- `/data/cobertura.json` es un índice ligero de categorías, fechas cubiertas, condiciones y límites de comparación. Comparte la fecha de generación del catálogo; no hace una consulta en vivo.
- El formulario conserva alojamiento, categoría opcional (`category`), fechas y adultos en su enlace. Al editar, el resultado anterior se oculta hasta consultar de nuevo. Una categoría que no admite al grupo devuelve `guest_restriction`, no `no_dates`.
- La salida añade `context` (cobertura y condiciones), `comparison` (si hay base para recomendar) y `capacity` por categoría. Capacidad física e inclusión tarifaria siguen siendo cosas distintas.
- En villas, muestra base, limpieza, impuestos y suplemento publicado `extraGuest` por persona extra y noche. No suma una estancia final ni supone que esos conceptos bastan para resolver promociones y temporadas.
- Altamar y Marvela tienen captura de calendario. `calendar.observedBlockedDates` muestra bloqueos encontrados para esas noches, incluso si la captura es antigua; conserva sus fechas. No convierte bloqueos pasados en disponibilidad actual. La ausencia de fechas en esa lista no prueba que esté libre.
- El resumen copiable sirve para solicitar confirmación manual. Radar no envía correos ni traspasa parámetros a cotizadores cuyo formato no se haya verificado.

### Elegibilidad de casas completas
En `result.status: base_only`, la base sigue disponible como referencia aunque el grupo o la duración no sean admisibles. Revise `result.eligibility`: `restricted` conserva `reason` (`guest_restriction` o `minimum_stay`) y su explicación; `not_confirmed` nunca equivale a reserva aceptable. `calendar` describe por separado la evidencia de bloqueos y su vigencia.
