# OpenVINO NPU advisory gateway Bounded Docker-bridge wrapper for the classifier, GenAI worker, and doc/image triage sidecars. - HTTP bind: `172.19.0.1:18830` for `n8n-agent` on the `swarm_default` Docker bridge - Service: `openvino-advisory-gateway.service` - Mode: advisory/shadow/draft only - Metadata log: `~/.local/state/openvino-advisory-gateway/events.sqlite` ## Authority boundary Every response includes an explicit authority block: ```json { "may_route": false, "may_write_memory": false, "may_send_external": false, "may_process_private_dirs": false, "may_execute_tools": false, "may_restart_services": false } ``` This service may provide hints and drafts. It must not become the live Atlas/Hermes router, memory writer, primary chat model, external sender, tool executor, service restarter, or broad private document processor without a separate approved integration. ## Endpoints ```text GET /healthz POST /v1/advisory/classify POST /v1/advisory/generate POST /v1/advisory/triage ``` ## Cron and n8n advisory dry-run contract For cron/n8n event classification, use the dry-run contract in `docs/cron-n8n-advisory-classifier.md`. It defines the normalized event envelope, decision envelope, `suppress|log|summarize|escalate` recommendation mapping, and duplicate/stale/no-op/action-required examples. Example artifacts: - `examples/cron-advisory-dry-run.sh` — host-local cron wrapper that prints one compact decision line and performs no side effects. - `examples/n8n-advisory-dry-run-fragment.json` — sanitized inactive n8n node fragment for Set -> HTTP Request -> Code decision mapping. Both examples preserve the gateway authority boundary: advisory only, no send/restart/memory/tool/routing authority. ### Classifier shadow call ```bash curl -fsS http://172.19.0.1:18830/v1/advisory/classify \ -H 'Content-Type: application/json' \ -d '{"trace_id":"smoke","text":"Urgent: inspect service health and systemd status."}' | jq . ``` ### Bounded GenAI draft Allowed jobs: `title`, `summary`, `notification`, `memory_candidate`. ```bash curl -fsS http://172.19.0.1:18830/v1/advisory/generate \ -H 'Content-Type: application/json' \ -d '{"job":"title","input":"Summarize a local health check.","max_new_tokens":24}' | jq . ``` ### Explicit-file doc/image triage ```bash curl -fsS http://172.19.0.1:18830/v1/advisory/triage \ -H 'Content-Type: application/json' \ -d '{"path":"/home/will/lab/swarm/openvino-doc-image-triage-npu/samples/synthetic_invoice.png","allowed_roots":["/home/will/lab/swarm/openvino-doc-image-triage-npu"]}' | jq . ``` The gateway requires the path to be inside both: 1. a configured allowed root on the gateway process; and 2. the request's explicit `allowed_roots` list, if one is provided. Requests cannot broaden the process-configured roots. Do not broaden configured roots to private folders without explicit approval for that root and task. ## Install / run ```bash install -m 0644 openvino-advisory-gateway.service ~/.config/systemd/user/openvino-advisory-gateway.service systemctl --user daemon-reload systemctl --user enable --now openvino-advisory-gateway.service systemctl --user status openvino-advisory-gateway.service --no-pager ``` `--allowed-root` may be repeated in the systemd unit when additional non-private fixture/review directories are approved. Docker bridge exposure must use `--allow-docker-bridge` and the approved bridge IP `172.19.0.1`; the service still refuses wildcard binds such as `0.0.0.0`. From `n8n-agent`, verify bridge reachability with: ```bash docker exec n8n-agent wget -qO- -T 8 http://172.19.0.1:18830/healthz ``` ## Tests ```bash cd /home/will/lab/swarm/openvino-advisory-gateway python -m pytest tests/test_gateway.py -q ```