Saltar a contenido

Guia de uso para el equipo

Fecha: 2026-04-27

Esta guia explica como acceder a docu.iort y como usar sus superficies principales: web documental, chat, API, MCP y operaciones de mantenimiento. No contiene secretos. Los secretos se referencian solo por nombre de Google Secret Manager (GSM).

1. Entornos y URLs

Superficie Production Staging Acceso
Web documental https://docu.iort.io https://staging.docu.iort.io Production publica; staging protegido por Cloudflare Access.
Chat https://chat.docu.iort.io https://chat-staging.docu.iort.io Lectura/preguntas publicas; escritura protegida por Cloudflare Access humano.
API https://api.docu.iort.io https://api-staging.docu.iort.io Cloudflare Access Service Auth.
MCP https://mcp.docu.iort.io/mcp https://mcp-staging.docu.iort.io/mcp Cloudflare Access Service Auth.
API externa api-ext.docu.iort.io No aplica No publicada en esta version.
MCP externo mcp-ext.docu.iort.io No aplica No publicado en esta version.

2. Secretos GSM de referencia

No imprimir estos valores en terminal, logs, issues ni PRs. Usarlos solo como entrada a scripts o variables locales.

GSM secret Uso
infra_iort_io Token Cloudflare account-scoped usado por scripts/bootstrap/export_cloudflare_env.sh, Pulumi, Wrangler y scripts bootstrap.
infra_iort_io_account_id Account ID Cloudflare que acompana al token infra_iort_io. export_cloudflare_env.sh lo carga como CLOUDFLARE_ACCOUNT_ID.
cloudflare-api-token Token Cloudflare alternativo/historico. Los scripts actuales usan infra_iort_io.
docu_iort_access_docu_iort_ci Service token de Cloudflare Access para CI, smoke tests y llamadas operativas a API/MCP.
docu_iort_access_docu_iort_chat_internal Service token usado por el Worker de chat para llamar internamente a API.
docu_iort_access_docu_iort_external_reader_bootstrap Service token reservado para futuros lectores externos read-only. api-ext y mcp-ext siguen deshabilitados.
docu_iort_github_app JSON de GitHub App usado como GITHUB_APP_CREDENTIALS en API staging/production.
docu_iort_logpush_r2_access_key_id Access Key ID R2 S3 para Logpush a docu-iort-logs y docu-iort-logs-staging.
docu_iort_logpush_r2_secret_access_key Secret Access Key R2 S3 para Logpush.

El account_id de Cloudflare se obtiene desde GSM infra_iort_io_account_id. No es necesario copiarlo manualmente en los comandos.

3. Preparar una terminal operativa

Desde la raiz del repo:

source scripts/bootstrap/export_cloudflare_env.sh

Ese script exporta:

  • CLOUDFLARE_ACCOUNT_ID
  • CLOUDFLARE_ZONE_ID
  • CLOUDFLARE_API_TOKEN

CLOUDFLARE_ACCOUNT_ID sale de infra_iort_io_account_id y CLOUDFLARE_API_TOKEN sale de infra_iort_io.

Para preparar cabeceras de Access Service Auth sin imprimir secretos:

token_json="$(gcloud secrets versions access latest --secret=docu_iort_access_docu_iort_ci)"
client_id="$(TOKEN_JSON="$token_json" node -e 'process.stdout.write(JSON.parse(process.env.TOKEN_JSON).client_id)')"
client_secret="$(TOKEN_JSON="$token_json" node -e 'process.stdout.write(JSON.parse(process.env.TOKEN_JSON).client_secret)')"
authorization_header_json="$(TOKEN_JSON="$token_json" node -e 'process.stdout.write(JSON.parse(process.env.TOKEN_JSON).authorization_header_json)')"

Al terminar:

unset token_json client_id client_secret authorization_header_json

4. Web documental

La web documental publica contiene el catalogo navegable de documentos y proyectos.

Uso normal:

  1. Abrir https://docu.iort.io.
  2. Usar la navegacion lateral para ir a proyectos, arquitectura, glosario o tags.
  3. Usar la busqueda de MkDocs para encontrar contenido textual.

Staging:

https://staging.docu.iort.io

Staging esta pensado para validar cambios antes de production. Si Cloudflare Access solicita login, usar una cuenta autorizada del dominio corporativo.

5. Chat

El chat esta pensado para preguntas sobre la documentacion y para iniciar cambios documentales controlados.

URLs:

Production: https://chat.docu.iort.io
Staging:    https://chat-staging.docu.iort.io

Lectura publica temporal:

  • GET /
  • POST /api/search
  • POST /api/ask

Escritura protegida por Cloudflare Access humano:

  • POST /api/propose
  • POST /api/pull-request

5.1 Preguntar desde navegador

  1. Abrir https://chat.docu.iort.io.
  2. Escribir una pregunta, por ejemplo: puedo ver en NetBox la IP de un servidor?
  3. Revisar la respuesta y las fuentes citadas.

5.2 Preguntar desde terminal

curl -fsS \
  -H "Content-Type: application/json" \
  -d '{"query":"puedo ver en NetBox la IP de un servidor?","limit":5}' \
  https://chat.docu.iort.io/api/ask | node -e '
let data = "";
process.stdin.on("data", (chunk) => data += chunk);
process.stdin.on("end", () => {
  const payload = JSON.parse(data);
  console.log(payload.answer);
  console.log(JSON.stringify(payload.sources, null, 2));
});'

5.3 Buscar documentos desde terminal

curl -fsS \
  -H "Content-Type: application/json" \
  -d '{"query":"NetBox","limit":5}' \
  https://chat.docu.iort.io/api/search | node -e '
let data = "";
process.stdin.on("data", (chunk) => data += chunk);
process.stdin.on("end", () => {
  const payload = JSON.parse(data);
  console.log(JSON.stringify(payload.docs, null, 2));
});'

5.4 Proponer cambios documentales

La escritura debe hacerse desde el chat autenticado con Cloudflare Access. El flujo esperado es:

  1. Abrir https://chat.docu.iort.io.
  2. Autenticarse cuando Cloudflare Access lo pida.
  3. Pedir un cambio documental concreto.
  4. Revisar la propuesta, diff y auditoria.
  5. Crear PR si la propuesta es correcta.

El sistema debe crear ramas/PRs contra develop. No debe escribir en main.

6. API HTTP

La API esta protegida por Cloudflare Access Service Auth. Usar el service token docu_iort_access_docu_iort_ci para llamadas operativas.

Base URLs:

Production: https://api.docu.iort.io
Staging:    https://api-staging.docu.iort.io

6.1 Health

Con cabeceras separadas:

curl -fsS \
  -H "CF-Access-Client-Id: $client_id" \
  -H "CF-Access-Client-Secret: $client_secret" \
  https://api.docu.iort.io/v1/health | node -e '
let data = "";
process.stdin.on("data", (chunk) => data += chunk);
process.stdin.on("end", () => {
  const payload = JSON.parse(data);
  console.log(JSON.stringify({
    ok: payload.ok,
    ai_search: payload.ai_search,
    git_auth_mode: payload.git_auth_mode,
    write_mode: payload.write_mode,
    ai_gateway: payload.ai_gateway
  }, null, 2));
});'

Con cabecera unica Authorization:

curl -fsS \
  -H "Authorization: $authorization_header_json" \
  https://api.docu.iort.io/v1/health

Valores esperados relevantes:

  • ai_search=true
  • git_auth_mode=github_app
  • write_mode=proposal_only
  • ai_gateway.enabled=true

6.2 Preguntar al RAG

curl -fsS \
  -H "CF-Access-Client-Id: $client_id" \
  -H "CF-Access-Client-Secret: $client_secret" \
  -H "Content-Type: application/json" \
  -d '{"query":"puedo ver en NetBox la IP de un servidor?","limit":5}' \
  https://api.docu.iort.io/v1/ask | node -e '
let data = "";
process.stdin.on("data", (chunk) => data += chunk);
process.stdin.on("end", () => {
  const payload = JSON.parse(data);
  console.log(payload.answer);
  console.log("retrieval.mode =", payload.retrieval?.mode);
  console.log(JSON.stringify(payload.sources, null, 2));
});'

Valor esperado:

retrieval.mode = hybrid

6.3 Buscar documentos

curl -fsS \
  -H "CF-Access-Client-Id: $client_id" \
  -H "CF-Access-Client-Secret: $client_secret" \
  "https://api.docu.iort.io/v1/docs/search?q=NetBox&limit=5"

6.4 Endpoints de escritura

Los endpoints de escritura de API existen para el flujo del chat, pero requieren contexto humano de Access. Para uso normal del equipo, crear propuestas y PRs desde el chat, no llamando directamente a API.

7. MCP

El MCP expone herramientas para clientes compatibles con Model Context Protocol. Esta protegido por Cloudflare Access Service Auth.

Base URLs:

Production: https://mcp.docu.iort.io/mcp
Staging:    https://mcp-staging.docu.iort.io/mcp

7.1 Ver health y herramientas

curl -fsS \
  -H "CF-Access-Client-Id: $client_id" \
  -H "CF-Access-Client-Secret: $client_secret" \
  https://mcp.docu.iort.io/mcp

7.2 Listar herramientas por JSON-RPC

curl -fsS \
  -H "CF-Access-Client-Id: $client_id" \
  -H "CF-Access-Client-Secret: $client_secret" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' \
  https://mcp.docu.iort.io/mcp

7.3 Usar ask_docs

curl -fsS \
  -H "CF-Access-Client-Id: $client_id" \
  -H "CF-Access-Client-Secret: $client_secret" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"ask_docs","arguments":{"query":"puedo ver en NetBox la IP de un servidor?","limit":5}}}' \
  https://mcp.docu.iort.io/mcp | node -e '
let data = "";
process.stdin.on("data", (chunk) => data += chunk);
process.stdin.on("end", () => {
  const payload = JSON.parse(data);
  const text = payload.result?.content?.[0]?.text || "{}";
  const parsed = JSON.parse(text);
  console.log(parsed.answer);
  console.log(JSON.stringify(parsed.sources, null, 2));
});'

Respuesta esperada:

  • answer: texto de respuesta.
  • sources: lista de fuentes documentales.

8. Operaciones de mantenimiento

8.1 Reindexar RAG

Tras cambios documentales o tras un pulumi up que toque API/MCP:

DEPLOY_WORKERS=1 scripts/bootstrap/reindex_ai_search.sh staging
DEPLOY_WORKERS=1 scripts/bootstrap/reindex_ai_search.sh production

Esto:

  • construye catalogo, chunks y grafo;
  • aplica migraciones y seeds D1;
  • sube documentos a R2 para AI Search;
  • reindexa Vectorize y AI Search;
  • redeploya API/MCP con binding AI_SEARCH.

8.2 Smoke tests

Staging:

BASE_DOCS=https://staging.docu.iort.io \
BASE_CHAT=https://chat-staging.docu.iort.io \
BASE_API=https://api-staging.docu.iort.io \
BASE_MCP=https://mcp-staging.docu.iort.io/mcp \
scripts/bootstrap/09_smoke_tests.sh

Production:

BASE_DOCS=https://docu.iort.io \
BASE_CHAT=https://chat.docu.iort.io \
BASE_API=https://api.docu.iort.io \
BASE_MCP=https://mcp.docu.iort.io/mcp \
scripts/bootstrap/09_smoke_tests.sh

8.3 Logpush

Logpush envia workers_trace_events a R2:

  • docu-iort-logs-staging
  • docu-iort-logs

Configurar o reparar:

scripts/bootstrap/configure_logpush.sh staging
scripts/bootstrap/configure_logpush.sh production

El script usa destino S3-compatible porque los buckets son EU:

${CLOUDFLARE_ACCOUNT_ID}.eu.r2.cloudflarestorage.com

8.4 Rate limiting

La cuenta Cloudflare solo permite una regla en http_ratelimit. Por eso el script configura una regla combinada para staging y production:

scripts/bootstrap/configure_rate_limits.sh production

Regla esperada:

docu-iort-surface-all

Limite actual:

10 requests / 10 seconds

9. Queues, Workflows y Workers internos

Workers internos:

  • docu-iort-ingest
  • docu-iort-ingest-staging
  • docu-iort-monitor
  • docu-iort-monitor-staging

Queues:

  • docu-iort-index
  • docu-iort-write
  • docu-iort-classify
  • equivalentes -staging
  • DLQs correspondientes *-dlq

Workflows canary:

  • docu-iort-ingest
  • docu-iort-doc-write
  • docu-iort-maintenance
  • equivalentes -staging

El monitor tiene cron triggers configurados desde Pulumi.

10. Reglas de seguridad

  • No escribir secretos en Git.
  • No imprimir secretos en terminal compartida, tickets, PRs ni logs.
  • No publicar api-ext ni mcp-ext sin rate limiting y scopes read-only.
  • API/MCP deben permanecer protegidos por Cloudflare Access Service Auth.
  • El chat puede estar publico para lectura/preguntas en esta fase, pero la escritura debe requerir Access humano.
  • No escribir en main; los cambios documentales deben ir por PR contra develop.
  • No cambiar el modelo de embeddings sin recrear/reindexar AI Search. Modelo oficial: @cf/qwen/qwen3-embedding-0.6b.
  • Modelo conversacional oficial: @cf/moonshotai/kimi-k2.6.