Eagle // Logic
Product Showcase Pricing Support

Deployment

Operations guide for running the PRIOR engine in production. PRIOR ships as a single immutable container with a native Rust serving path: no Python, no Node, and no external calls at inference time. Default port 8089.

This supersedes any older "Python gateway on port 8000" material. Production is the native engine.


1. The container model

The image bakes everything needed to enforce policy except the generation weights (which are large and shared, so you mount them):

Baked into the image Supplied at run time
The prior Rust binary + patched llama libraries The generation GGUF (mounted read-only)
The MiniLM encoder GGUF (the gate's embedder) A license.bin node-locked to your host
The default policy packs (harm_veto, codeops_minilm, …) Env configuration (below)
The model steering registry (model_params.json) A writable state volume at /app/state

Writable state (the license identity record, the SQLite governance DB, and live re-calibration output) lives under /app/state, the only directory the non-root prior user owns. Mount a volume there. It is not optional on a node-locked tier: the identity record is what binds this license to this node, and a container that starts from an empty state volume derives a fresh node identity, which seat enforcement reads as a second node. The activation is then denied and the engine degrades to unsteered passthrough. You also lose your admin keys and audit log.

Minimal run (docker compose)

MODELS_DIR=/srv/models MODEL=Llama-3.2-3B-Instruct-Q4_K_M.gguf \
  docker compose up -d

Minimal run (docker run)

docker run -d --name prior \
  -p 127.0.0.1:8089:8089 \
  -e PRIOR_NATIVE_MODEL=/models/Llama-3.2-3B-Instruct-Q4_K_M.gguf \
  -v /srv/models:/models:ro \
  -v prior-state:/app/state \
  ghcr.io/eagle-logic/prior:slim-cpu

GPU

Use the CUDA image and offload layers to the GPU:

docker run -d --name prior --gpus all \
  -p 127.0.0.1:8089:8089 \
  -e PRIOR_NATIVE_MODEL=/models/Llama-3.2-3B-Instruct-Q4_K_M.gguf \
  -e PRIOR_NATIVE_NGL=99 \
  -v /srv/models:/models:ro -v prior-state:/app/state \
  ghcr.io/eagle-logic/prior:slim

The reference 7–8B model at 4-bit needs ~6 GB VRAM; run one model per GPU.


2. Network exposure & auth

The published port is loopback-only by default. docker-compose.yml publishes to 127.0.0.1:8089, which is reachable for local testing but not on the network. This is intentional: the /v1 endpoint is unauthenticated by default.

To expose the engine on a LAN or the internet, do both:

  1. Publish on a routable interface: PRIOR_PUBLISH_ADDR=0.0.0.0.
  2. Require a key on /v1: PRIOR_REQUIRE_AUTH=1 (then create keys via /admin/keys).

Put TLS termination (a reverse proxy / load balancer) in front for anything internet-facing.


3. Licensing (node-locked)

The engine verifies an ED25519-signed license bound to the host's hardware fingerprint before enabling steering. Eagle Logic's public key is baked into the published image, so it verifies locally and never calls home in the inference path, and you do not supply a key. (Connected tiers make a periodic background license check-in; the air-gapped tier makes none and runs fully offline (see Licensing).) You only mount your license.bin:

docker run -d --name prior --gpus all \
  -p 127.0.0.1:8089:8089 \
  -e PRIOR_NATIVE_MODEL=/models/model.gguf \
  -v /srv/models:/models:ro \
  -v /path/to/license.bin:/app/license.bin:ro \
  -v prior-state:/app/state \
  ghcr.io/eagle-logic/prior:slim
  • Without a valid license, PRIOR degrades to plain inference with no gate actuation (x-prior-steering: disabled) rather than failing to boot.
  • There is no bypass. A license verifies or it does not load, local development included.
  • A license binds customer id, hardware id, tier, expiry, and capabilities. Expired, tampered, or wrong-host licenses are rejected. Full details in Licensing.

4. Environment variable reference

Everything is optional except where noted. Defaults shown are the container defaults.

Server & network

Variable Default Purpose
PRIOR_PORT 8089 HTTP port.
PRIOR_BIND_HOST 127.0.0.1 Interface the server binds inside the container. The default is the container's own loopback, which no -p mapping can reach — set 0.0.0.0 under docker run or the engine starts fine and refuses every connection. Compose sets it for you.
PRIOR_PUBLISH_ADDR 127.0.0.1 Host interface the port is published on (compose). Set 0.0.0.0 to expose.
PRIOR_ALLOWED_ORIGINS * CORS allowed origins (comma-separated). Restrict in production.

Model & engine

Variable Default Purpose
PRIOR_POLICY on Master policy switch. on = the shipped detect+steer policy (harmful requests and destructive ops refused); off = byte-for-byte passthrough. Detection and steering always move together.
PRIOR_NATIVE_MODEL (none) Path to the generation GGUF (required).
PRIOR_NATIVE_ENCODER baked MiniLM Path to the gate's encoder GGUF.
PRIOR_NATIVE_ARBITERS harm_veto, codeops_minilm, injection.byteppm Comma-separated arbiter pack paths to load at boot. The image sets all three; override to load your own.
PRIOR_NATIVE_NGL 0 GPU layers to offload for generation (99 = all; 0 = CPU).
PRIOR_NATIVE_ENCODER_NGL 0 GPU layers for the encoder.
PRIOR_MAX_CONTEXT 8192 Max context window.
PRIOR_MODEL_REGISTRY /app/state/model_params.json Per-model steering registry (golden layer + alpha).
PRIOR_SPAN_SCORING 1 Span-score padding defense on/off.
PRIOR_SPAN_K 12 Span-scoring neighbor count.
PRIOR_GRAD_MAX_ANCHOR 256 Max anchor length for the steering gradient.

Auth & license

Variable Default Purpose
PRIOR_REQUIRE_AUTH 0 Require a Bearer key on /v1 (live-toggleable via /admin/runtime).
PRIOR_API_KEY (none) Seed an Admin key at startup (env-only, not persisted).
PRIOR_LICENSE_PUBLIC_KEY removed No longer read. The verification key is compiled into the engine; it was an env var until it became clear a published image could be pointed at any key. Setting it has no effect.
PRIOR_LICENSE_FILE auto-search Path to license.bin.
PRIOR_LICENSE_REFRESH_URL (none) Optional connected-tier license auto-refresh endpoint.
PRIOR_LICENSE_REFRESH_TICK_SECS 3600 Refresh poll interval.
PRIOR_LICENSE_REFRESH_THRESHOLD_DAYS 7 Days before expiry to trigger a refresh.

Storage & state

Variable Default Purpose
PRIOR_STATE_DIR /app/state Writable state directory (owned by the non-root user).
PRIOR_DB_PATH /app/state/ssa_oracle.db Governance SQLite DB (keys, audit). :memory: for ephemeral.

Observability & safety

Variable Default Purpose
PRIOR_LOG_LEVEL / RUST_LOG info Log verbosity.
PRIOR_JSON_LOGS (none) Emit structured JSON logs (set to enable).
PRIOR_YELLOW_MODE inline YELLOW confirm delivery: inline (append to content) or header only.
PRIOR_SAFETY_AUDIT_RETAIN 1000 Rows retained in the durable safety audit.
PRIOR_DIAG_TOKEN (none) Optional token for privileged diagnostics.

Policy ingest (extractor)

Only needed to use POST /admin/packs/ingest. Unconfigured ⇒ a clear 400, never a silent dial.

Variable Purpose
PRIOR_EXTRACTOR_URL Extraction LLM endpoint (llama.cpp /completion or OpenAI-compatible).
PRIOR_EXTRACTOR_ENDPOINT / _CHAT API path / chat-style toggle.
PRIOR_EXTRACTOR_TEMPERATURE / _MAX_TOKENS / _TIMEOUT Sampling + limits.

5. Health, readiness & Kubernetes

Probe Endpoint Behavior
Liveness GET /health Answers as soon as the HTTP server is up (the model loads lazily).
Readiness GET /health Use the same endpoint; back it with a startupProbe budget generous enough for a cold model load/download.
livenessProbe:
  httpGet: { path: /health, port: 8089 }
  periodSeconds: 10
startupProbe:
  httpGet: { path: /health, port: 8089 }
  failureThreshold: 120     # tolerate a cold-node model load
  periodSeconds: 5

Because the engine is stateless per request, scale horizontally by running more replicas behind a load balancer; each replica needs its own node-locked license (or a cluster license; see Licensing).


6. Observability

  • Metrics. GET /metrics is Prometheus exposition: zone distribution (GREEN/YELLOW/RED), refusal counts, and latency / token / injection histograms. Scrape it directly.
  • Structured logs. Set PRIOR_JSON_LOGS for one JSON object per line on stdout, ready for Datadog / Splunk / ELK. Routing decisions and steering-apply events are structured fields.
  • Safety audit. GET /admin/audit/safety is the durable, queryable trail of every gate decision (prompt hashes only, never text or completions). Pair x-prior-decision-id from a response with the matching audit row for end-to-end traceability.

7. Upgrades

The container is the atomic unit. To upgrade, pull the new image and replace the container; mount the same /app/state volume and the same license.bin. Policy packs authored through ingest live under your state/packs volume, so persist that volume and your custom policies survive replacement.


See also: Getting Started · API Reference · Licensing.