SEIF Docs

Context Runtime deployments

IMPLEMENTED adapter: isolated-process.v1 (contract context-deployment-adapter.v1: start(spec) → { endpoint, token, exited, stop }). Control semantics live in the deployment controller, so a remote worker, container runner or hosted runtime could implement the same contract without changing promotion, binding, readiness or routing semantics. Only the local process adapter ships; there is no placeholder Kubernetes code. Proven on macOS arm64 and Linux x64/arm64.

Deploy

POST /v1/deployments {project, environment, promotion, bindingRevision?} (capability environment.deploy):

  1. The promotion must be current, under the current policy, approved where required (or an executed break-glass promotion).
  2. The environment's binding revision is checked against the Build's provider requirements and secret resolvability; a mismatch blocks before any process starts (DEPLOYMENT_BINDING_BLOCKED, audited).
  3. The runner writes the verified Build and a runtime binding file (secret variable names only), resolves exactly the bound secrets, and starts the runtime with a minimal environment.
  4. Readiness: the Registry polls health until readiness leaves STARTING (bounded by startupTimeoutMs), and requires the exact Build digest, contract, deployment id and binding revision. Required providers not ready → FAILED (PROVIDER_NOT_READY) unless the binding allows degrade → DEGRADED.
  5. Atomic active-deployment transition: one transaction points the environment at the new deployment. The replaced deployment becomes DRAINING: it serves late consumption/outcome reports addressed to it (never new resolutions) for drainMs, is collected one last time, then RETIRED. Its Build copy is removed (reconstructible from CAS); its trace outbox is kept.

Proven: requests issued while a new production deployment was STARTING were all served by the previous Build; after readiness the route served the new Build; rollback returned the route to the previous immutable Build. This is a single-host transition, not HA: if the active process dies, the environment answers RUNTIME_UNAVAILABLE until redeployed.

Application routing

Applications use the stable endpoint /v1/projects/:project/environments/:environment/context/{resolve,expand,consumption,outcome} (SDK base …/runtime) with an application credential. New resolutions go only to the active deployment; reports may name deploymentId (returned by resolve; the SDKs pass it) to reach a draining deployment, otherwise DEPLOYMENT_RETIRED. Deployment-specific routes remain for operators.

Timeout classes and retries

ClassDefaultNotes
health2 sreadiness and collection health
startup15 sprocess start and provider readiness
resolve15 smust exceed the slowest provider timeout by ≥1 s; proxy waits resolve + 1 s
report5 sexpand, consumption, outcome
collection10 strace delivery pages
provider2 sper provider, 50 ms–10 s

A provider timeout is a provider fact inside a 200 response (layer UNAVAILABLE, unknown, providers[].status = TIMEOUT). The proxy reports RUNTIME_TIMEOUT (504) only when the runtime itself does not answer and RUNTIME_UNAVAILABLE (503) only when it cannot be reached. Resolve is retried once only after a refused connection (the request never arrived). Consumption and outcome are idempotent by reportId (8–64 URL-safe characters): a retried report returns the original record; reusing an id for a different report is REPORT_ID_CONFLICT. SDKs generate report ids and retry reports, never resolve.

Health

Runtime health keeps subsystem facts separate: checks.process, checks.buildIntegrity, checks.providers (per provider: required, state, version, implementation, code), checks.traceDelivery (state, pending, unreadable) and overall readiness (READY, DEGRADED, NOT_READY, STARTING). Providers are re-probed every 30 s. Health never exposes secrets or endpoints.

Delivery and operations

Traces are durably queued by the runtime; the Registry commits each delivered page in one transaction and acknowledges only after commit; refused envelopes stay pending and are counted. Polling is bounded to ten pages of 100 per pass; outbox saturation refuses new trace-producing requests rather than dropping them. On Registry restart, previous-session deployments become STOPPED and environments have no active deployment until redeployed. Operational logs carry request id, principal and class, route and code — never context content or credentials.