Documentation Index
Fetch the complete documentation index at: https://internal.september.wtf/llms.txt
Use this file to discover all available pages before exploring further.
bap-engine and the Engine talk over plain HTTP. The contract between
them is small and stable: the orchestrator launches engine containers
with a known set of environment variables and mounts; the engine
exposes a known set of HTTP endpoints. This page is the contract.
It’s stable across patch releases of either side. Major version bumps
on the engine require coordinated bumps on the orchestrator’s
ORCH_ENGINE_IMAGE.
What the orchestrator gives an engine
When the orchestrator launches an engine container, it provides:
Environment variables (always)
| Variable | Source | Purpose |
|---|
ENGINE_KEY_HASH | Generated by orchestrator | SHA-256 of the engine’s API key. The engine validates incoming X-Engine-Key against this. |
SQLITE_DB_PATH | Always /data/brain.sqlite | Where to write the per-user brain. |
CATALOG_DIR | Always /catalog | Where to read agents, skills, tools, soul template. |
Environment variables (passed through)
The orchestrator forwards any variable named in
ORCH_ENGINE_ENV_PASSTHROUGH. The standard set:
LLM_API_KEY
OPENAI_API_KEY
ANTHROPIC_API_KEY
GEMINI_API_KEY
The engine reads these directly from its own environment via
src/config.py. The orchestrator doesn’t transform them.
Mounts
| Mount | Mode | Purpose |
|---|
engine-data-{engine_id} (named volume) → /data | rw | Per-user brain SQLite + any other persistent files. |
<host catalog dir> → /catalog | ro | Shared platform catalog (agents, skills, tools, core_soul.json). |
Network
- The container joins the Docker network specified in
ORCH_ENGINE_NETWORK (default engine_net).
- The engine’s port (typically
8000 inside the container) is mapped
to a host port in [ORCH_PORT_MIN, ORCH_PORT_MAX], bound to
127.0.0.1.
Lifecycle expectations
- The container is created with
restart: unless-stopped, so a crash
inside the container restarts it. The orchestrator’s auto-restart is
for the case where the container exits and stays exited, or fails
health checks despite running.
- The orchestrator can stop, start, and destroy at any time. Engines
must support clean shutdown via SIGTERM.
What the engine gives back
The engine must implement these endpoints and behaviors. Stability
guarantees are documented per endpoint.
GET /health
Auth: none.
Stability: strict — schema and semantics never change.
Behavior: returns {"status": "ok", "uptime_seconds": float, "subsystems": {...}} when the engine is fully ready to serve
/execute. Returns non-200 or status != "ok" when not.
The orchestrator polls this during provisioning to confirm boot
completion (up to ORCH_BOOT_TIMEOUT_S, default 60s) and during the
background health loop.
POST /execute
Auth: X-Engine-Key header.
Stability: breaking changes to the request body or the SSE event
shapes require a major version bump. New optional request fields and
new event types are minor additions.
Body:
{
"message": "string",
"task_id": "string",
"max_turns": 50,
"super_thinking": false,
"media": [],
"direct": false,
"edit_message_id": null,
"retry_message_id": null
}
Response: text/event-stream. See
Streaming events.
POST /rpc
Auth: X-Engine-Key header.
Stability: the dispatcher shape is stable; individual operations
are versioned per op name.
Body:
{
"subsystem": "control" | "telemetry",
"op": "string",
...op-specific params
}
The orchestrator uses this for control operations:
set_config — atomic swap of the gateway config.
get_config — read the active config.
reload — re-read /config/gateway.yaml from disk.
quota_state — current quota usage.
cache_state — prompt-cache efficiency.
These are how the orchestrator (or your product) reads runtime state
from the engine without restarting it.
Versioning
Both sides follow semver:
| Engine version | Orchestrator behavior |
|---|
MAJOR bump (e.g. 2.x → 3.x) | Update ORCH_ENGINE_IMAGE + run regression evals before rolling. |
MINOR bump (e.g. 2.3 → 2.4) | Compatible. New optional features available; orchestrator unchanged. |
PATCH bump (e.g. 2.3.0 → 2.3.1) | Compatible. Bug fixes only. |
The orchestrator pins to a specific engine version via
ORCH_ENGINE_IMAGE. Don’t run latest — version drift is the most
common source of subtle bugs.
Auth flow
The orchestrator generates the engine API key, sends only the hash to
the engine, and returns the plaintext to the product. The engine
never sees the raw orchestrator credentials; the product never sees
the engine’s hash.
What the contract does not cover
- The engine’s internal APIs — agent loop, memory, sandbox. Those
evolve without coordination with the orchestrator.
- Per-product config beyond what’s in
gateway.yaml. If you need
per-product behavior in the engine, do it in the product layer
(BAP) or via a richer config file.
- Streaming HTTP/2. The contract is HTTP/1.1 + chunked encoding for
SSE.
See also