Engineering note · 3 of 6
Every run admission path — Agent Protocol, stream/wait, cron, agent-to-agent,
MCP tools/call — goes through createRunCtx. And
runkite serve will not listen at all until the plane can prove a
production-safe posture.
Handlers stay thin. The shared funnel does the work that must never diverge across entry points:
alias → load agent → rate limit admission gates kill / agents:<id>:run / policy run.create claim thread idle → busy (409 if already owned) A2A depth/breadth · insert run · build assignment (generation=1) → return (run, assignment) · caller enqueues
parent_run_id.
An earlier default let serve boot on SQLite + in-process + no
runner tokens + no client auth — still green on /readyz, so
Kubernetes happily sent production traffic. That is gone.
Before listening, admission checks:
POSTGRES_DSN / MYSQL_DSN / MONGO_URIREDIS_URL / NATS_URL / KAFKA_URLRUNNER_TOKEN_*auth configured in langgraph.json
Any miss → clear error, exit 1, never listen. Escape hatches are explicit:
RUNKITE_ALLOW_INSECURE_SERVE=1, RUNKITE_MODE=test, or
runkite dev for the zero-dependency laptop path.
Serve admission and policy Decide deny when unsure (security). Rate limiting fails open on a Redis blip (availability). Same word, different risk preference — do not conflate them.
If you cannot prove every create path shares one gate — and that
serve will not start half-wired — you do not have a control
plane; you have N slightly different APIs and a lucky readiness probe.