OpenVINO NPU advisory gateway
Bounded Docker-bridge wrapper for the classifier, GenAI worker, and doc/image triage sidecars.
- HTTP bind:
172.19.0.1:18830forn8n-agenton theswarm_defaultDocker 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:
{
"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
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
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.
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
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:
- a configured allowed root on the gateway process; and
- the request's explicit
allowed_rootslist, 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
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:
docker exec n8n-agent wget -qO- -T 8 http://172.19.0.1:18830/healthz
Tests
cd /home/will/lab/swarm/openvino-advisory-gateway
python -m pytest tests/test_gateway.py -q