# Inspect bounded endpoint admission policy Source: https://infercrane.mintlify.app/api-reference/admission/inspect-bounded-endpoint-admission-policy /openapi.json get /api/v1/endpoints/{name}/admission # Set bounded endpoint admission policy Source: https://infercrane.mintlify.app/api-reference/admission/set-bounded-endpoint-admission-policy /openapi.json put /api/v1/endpoints/{name}/admission # Adopt an existing inference endpoint without transferring lifecycle ownership Source: https://infercrane.mintlify.app/api-reference/adoption/adopt-an-existing-inference-endpoint-without-transferring-lifecycle-ownership /openapi.json post /api/v1/adoptions/endpoints # Explicitly promote an adopted endpoint to traffic-managed ownership Source: https://infercrane.mintlify.app/api-reference/adoption/explicitly-promote-an-adopted-endpoint-to-traffic-managed-ownership /openapi.json put /api/v1/adoptions/endpoints/{name}/ownership # Create a signed webhook alert policy Source: https://infercrane.mintlify.app/api-reference/alerts/create-a-signed-webhook-alert-policy /openapi.json post /api/v1/endpoints/{name}/alerts # Evaluate deterministic findings and deliver eligible alerts Source: https://infercrane.mintlify.app/api-reference/alerts/evaluate-deterministic-findings-and-deliver-eligible-alerts /openapi.json post /api/v1/endpoints/{name}/alerts/evaluate # List signed webhook alert policies Source: https://infercrane.mintlify.app/api-reference/alerts/list-signed-webhook-alert-policies /openapi.json get /api/v1/endpoints/{name}/alerts # Cancel queued or executing async inference Source: https://infercrane.mintlify.app/api-reference/async-inference/cancel-queued-or-executing-async-inference /openapi.json delete /api/v1/async/jobs/{id} # Inspect an async job and its result when complete Source: https://infercrane.mintlify.app/api-reference/async-inference/inspect-an-async-job-and-its-result-when-complete /openapi.json get /api/v1/async/jobs/{id} # Submit one encrypted durable inference job Source: https://infercrane.mintlify.app/api-reference/async-inference/submit-one-encrypted-durable-inference-job /openapi.json post /api/v1/endpoints/{name}/async # List tenant audit events Source: https://infercrane.mintlify.app/api-reference/audit/list-tenant-audit-events /openapi.json get /api/v1/audit-events # Create an advisory plan from a persisted recommendation Source: https://infercrane.mintlify.app/api-reference/autopilot/create-an-advisory-plan-from-a-persisted-recommendation /openapi.json post /api/v1/deployments/{name}/autopilot/plans # Inspect an immutable advisory plan Source: https://infercrane.mintlify.app/api-reference/autopilot/inspect-an-immutable-advisory-plan /openapi.json get /api/v1/autopilot/plans/{id} # Record human approval without mutating serving state Source: https://infercrane.mintlify.app/api-reference/autopilot/record-human-approval-without-mutating-serving-state /openapi.json post /api/v1/autopilot/plans/{id}/approve # List benchmark history Source: https://infercrane.mintlify.app/api-reference/benchmarks/list-benchmark-history /openapi.json get /api/v1/deployments/{name}/benchmarks # Run and persist an AIPerf benchmark Source: https://infercrane.mintlify.app/api-reference/benchmarks/run-and-persist-an-aiperf-benchmark /openapi.json post /api/v1/deployments/{name}/benchmarks # Persist a fresh budget-bounded overflow decision Source: https://infercrane.mintlify.app/api-reference/burst-guard/persist-a-fresh-budget-bounded-overflow-decision /openapi.json post /api/v1/deployments/{name}/burst-guard/evaluate # Summarize tenant-scoped observed capacity evidence Source: https://infercrane.mintlify.app/api-reference/capacity-intelligence/summarize-tenant-scoped-observed-capacity-evidence /openapi.json get /api/v1/capacity/intelligence # Create bounded durable logical session identity Source: https://infercrane.mintlify.app/api-reference/context-passport/create-bounded-durable-logical-session-identity /openapi.json post /api/v1/context-passports # Inspect logical session identity and best-effort affinity Source: https://infercrane.mintlify.app/api-reference/context-passport/inspect-logical-session-identity-and-best-effort-affinity /openapi.json get /api/v1/context-passports/{id} # Apply a DeploymentSpec Source: https://infercrane.mintlify.app/api-reference/deployments/apply-a-deploymentspec /openapi.json post /api/v1/deployments/apply # Create a provider-managed deployment Source: https://infercrane.mintlify.app/api-reference/deployments/create-a-provider-managed-deployment /openapi.json post /api/v1/deployments # Delete a logical deployment Source: https://infercrane.mintlify.app/api-reference/deployments/delete-a-logical-deployment /openapi.json delete /api/v1/deployments/{name} # Inspect deployment lifecycle state Source: https://infercrane.mintlify.app/api-reference/deployments/inspect-deployment-lifecycle-state /openapi.json get /api/v1/deployments/{name} # List deployment events Source: https://infercrane.mintlify.app/api-reference/deployments/list-deployment-events /openapi.json get /api/v1/deployments/{name}/events # List logical deployments Source: https://infercrane.mintlify.app/api-reference/deployments/list-logical-deployments /openapi.json get /api/v1/deployments # Inspect persisted request metadata without content Source: https://infercrane.mintlify.app/api-reference/diagnostics/inspect-persisted-request-metadata-without-content /openapi.json get /api/v1/requests/{id} # Persist deterministic endpoint findings Source: https://infercrane.mintlify.app/api-reference/diagnostics/persist-deterministic-endpoint-findings /openapi.json post /api/v1/endpoints/{name}/doctor # Attach a backend binding to an endpoint Source: https://infercrane.mintlify.app/api-reference/endpoints/attach-a-backend-binding-to-an-endpoint /openapi.json post /api/v1/endpoints/{name}/bindings # Create a logical model identity Source: https://infercrane.mintlify.app/api-reference/endpoints/create-a-logical-model-identity /openapi.json post /api/v1/logical-models # Create a stable application endpoint Source: https://infercrane.mintlify.app/api-reference/endpoints/create-a-stable-application-endpoint /openapi.json post /api/v1/endpoints # Create an endpoint environment Source: https://infercrane.mintlify.app/api-reference/endpoints/create-an-endpoint-environment /openapi.json post /api/v1/environments # Create and stage an immutable serving plan Source: https://infercrane.mintlify.app/api-reference/endpoints/create-and-stage-an-immutable-serving-plan /openapi.json post /api/v1/endpoints/{name}/plans # Delete an endpoint without deleting its bound deployment Source: https://infercrane.mintlify.app/api-reference/endpoints/delete-an-endpoint-without-deleting-its-bound-deployment /openapi.json delete /api/v1/endpoints/{name} # Evaluate active and candidate serving plans Source: https://infercrane.mintlify.app/api-reference/endpoints/evaluate-active-and-candidate-serving-plans /openapi.json post /api/v1/endpoints/{name}/release-guard/evaluate # Inspect an endpoint and its serving plans Source: https://infercrane.mintlify.app/api-reference/endpoints/inspect-an-endpoint-and-its-serving-plans /openapi.json get /api/v1/endpoints/{name} # Inspect endpoint Release Guard policy Source: https://infercrane.mintlify.app/api-reference/endpoints/inspect-endpoint-release-guard-policy /openapi.json get /api/v1/endpoints/{name}/release-guard/policy # List endpoint environments Source: https://infercrane.mintlify.app/api-reference/endpoints/list-endpoint-environments /openapi.json get /api/v1/environments # List endpoint Release Guard decisions Source: https://infercrane.mintlify.app/api-reference/endpoints/list-endpoint-release-guard-decisions /openapi.json get /api/v1/endpoints/{name}/release-guard/evaluations # List logical model identities Source: https://infercrane.mintlify.app/api-reference/endpoints/list-logical-model-identities /openapi.json get /api/v1/logical-models # List stable application endpoints Source: https://infercrane.mintlify.app/api-reference/endpoints/list-stable-application-endpoints /openapi.json get /api/v1/endpoints # Promote a serving plan for future requests Source: https://infercrane.mintlify.app/api-reference/endpoints/promote-a-serving-plan-for-future-requests /openapi.json put /api/v1/endpoints/{name}/plans/{plan}/active # Set endpoint Release Guard policy Source: https://infercrane.mintlify.app/api-reference/endpoints/set-endpoint-release-guard-policy /openapi.json put /api/v1/endpoints/{name}/release-guard/policy # Stage a candidate serving plan Source: https://infercrane.mintlify.app/api-reference/endpoints/stage-a-candidate-serving-plan /openapi.json put /api/v1/endpoints/{name}/plans/{plan}/candidate # Stage one environment endpoint's immutable plan as another endpoint's candidate Source: https://infercrane.mintlify.app/api-reference/endpoints/stage-one-environment-endpoints-immutable-plan-as-another-endpoints-candidate /openapi.json post /api/v1/environment-promotions # Configure governed external fallback Source: https://infercrane.mintlify.app/api-reference/external-capacity/configure-governed-external-fallback /openapi.json put /api/v1/deployments/{name}/external-policy # Inspect governed external fallback Source: https://infercrane.mintlify.app/api-reference/external-capacity/inspect-governed-external-fallback /openapi.json get /api/v1/deployments/{name}/external-policy # List persisted FinOps evidence Source: https://infercrane.mintlify.app/api-reference/finops/list-persisted-finops-evidence /openapi.json get /api/v1/deployments/{name}/finops/reports # Persist a sourced cost report without invented savings Source: https://infercrane.mintlify.app/api-reference/finops/persist-a-sourced-cost-report-without-invented-savings /openapi.json post /api/v1/deployments/{name}/finops/reports # Create a scoped service account Source: https://infercrane.mintlify.app/api-reference/identity/create-a-scoped-service-account /openapi.json post /api/v1/principals # Create a tenant Source: https://infercrane.mintlify.app/api-reference/identity/create-a-tenant /openapi.json post /api/v1/tenants # Inspect the authenticated principal Source: https://infercrane.mintlify.app/api-reference/identity/inspect-the-authenticated-principal /openapi.json get /api/v1/whoami # List private-console members for the authenticated organization Source: https://infercrane.mintlify.app/api-reference/identity/list-private-console-members-for-the-authenticated-organization /openapi.json get /api/v1/console/access # List service accounts for the authenticated organization Source: https://infercrane.mintlify.app/api-reference/identity/list-service-accounts-for-the-authenticated-organization /openapi.json get /api/v1/principals # Map a hosted identity and grant or revoke private-console access Source: https://infercrane.mintlify.app/api-reference/identity/map-a-hosted-identity-and-grant-or-revoke-private-console-access /openapi.json put /api/v1/console/access # Resolve the authenticated console organization and entitlements Source: https://infercrane.mintlify.app/api-reference/identity/resolve-the-authenticated-console-organization-and-entitlements /openapi.json get /api/v1/console/session # Revoke a service account Source: https://infercrane.mintlify.app/api-reference/identity/revoke-a-service-account /openapi.json delete /api/v1/principals/{id} # Rotate a service-account credential Source: https://infercrane.mintlify.app/api-reference/identity/rotate-a-service-account-credential /openapi.json post /api/v1/principals/{id}/rotate # Set tenant safety quotas Source: https://infercrane.mintlify.app/api-reference/identity/set-tenant-safety-quotas /openapi.json put /api/v1/tenant/quota # Delete deterministic SLO policy Source: https://infercrane.mintlify.app/api-reference/inference-decisions/delete-deterministic-slo-policy /openapi.json delete /api/v1/deployments/{name}/slo-policy # Evaluate and persist a recommendation Source: https://infercrane.mintlify.app/api-reference/inference-decisions/evaluate-and-persist-a-recommendation /openapi.json post /api/v1/deployments/{name}/recommendations # Inspect deterministic SLO policy Source: https://infercrane.mintlify.app/api-reference/inference-decisions/inspect-deterministic-slo-policy /openapi.json get /api/v1/deployments/{name}/slo-policy # List persisted recommendation history Source: https://infercrane.mintlify.app/api-reference/inference-decisions/list-persisted-recommendation-history /openapi.json get /api/v1/deployments/{name}/recommendations # Set deterministic SLO policy Source: https://infercrane.mintlify.app/api-reference/inference-decisions/set-deterministic-slo-policy /openapi.json put /api/v1/deployments/{name}/slo-policy # Compare persisted serving evidence Source: https://infercrane.mintlify.app/api-reference/inference-lab/compare-persisted-serving-evidence /openapi.json post /api/v1/lab/evaluations # Create a buffered or streaming chat completion Source: https://infercrane.mintlify.app/api-reference/inference/create-a-buffered-or-streaming-chat-completion /openapi.json post /v1/chat/completions When stream=true, the response is an SSE sequence of data JSON events terminated by data: [DONE]. InferCrane never replays a partially transmitted stream. # List logical inference models Source: https://infercrane.mintlify.app/api-reference/inference/list-logical-inference-models /openapi.json get /v1/models # Proxy a capability-qualified OpenAI-compatible request Source: https://infercrane.mintlify.app/api-reference/inference/proxy-a-capability-qualified-openai-compatible-request /openapi.json post /v1/chat/completions/batch The selected endpoint must explicitly qualify this protocol. InferCrane rewrites only the logical model identity and otherwise preserves the request and response. # Proxy a capability-qualified OpenAI-compatible request Source: https://infercrane.mintlify.app/api-reference/inference/proxy-a-capability-qualified-openai-compatible-request-1 /openapi.json post /v1/completions The selected endpoint must explicitly qualify this protocol. InferCrane rewrites only the logical model identity and otherwise preserves the request and response. # Proxy a capability-qualified OpenAI-compatible request Source: https://infercrane.mintlify.app/api-reference/inference/proxy-a-capability-qualified-openai-compatible-request-2 /openapi.json post /v1/embeddings The selected endpoint must explicitly qualify this protocol. InferCrane rewrites only the logical model identity and otherwise preserves the request and response. # Proxy a capability-qualified OpenAI-compatible request Source: https://infercrane.mintlify.app/api-reference/inference/proxy-a-capability-qualified-openai-compatible-request-3 /openapi.json post /v1/responses The selected endpoint must explicitly qualify this protocol. InferCrane rewrites only the logical model identity and otherwise preserves the request and response. # List orphaned provider resources Source: https://infercrane.mintlify.app/api-reference/infrastructure/list-orphaned-provider-resources /openapi.json get /api/v1/orphans # Inspect fresh and expired cache observations separately from prefetch intent Source: https://infercrane.mintlify.app/api-reference/model-artifacts/inspect-fresh-and-expired-cache-observations-separately-from-prefetch-intent /openapi.json get /api/v1/artifacts/{id}/cache # Record bounded provider-native artifact cache evidence Source: https://infercrane.mintlify.app/api-reference/model-artifacts/record-bounded-provider-native-artifact-cache-evidence /openapi.json post /api/v1/artifacts/{id}/cache-observations # Request provider-adapter artifact prefetch Source: https://infercrane.mintlify.app/api-reference/model-artifacts/request-provider-adapter-artifact-prefetch /openapi.json post /api/v1/artifacts/{id}/prefetches # Read bounded normalized inference and lifecycle evidence Source: https://infercrane.mintlify.app/api-reference/monitoring/read-bounded-normalized-inference-and-lifecycle-evidence /openapi.json get /api/v1/endpoints/{name}/monitoring # Inspect a durable operation Source: https://infercrane.mintlify.app/api-reference/operations/inspect-a-durable-operation /openapi.json get /api/v1/operations/{id} # List durable operation events Source: https://infercrane.mintlify.app/api-reference/operations/list-durable-operation-events /openapi.json get /api/v1/operations/{id}/events # List durable operations for the authenticated organization Source: https://infercrane.mintlify.app/api-reference/operations/list-durable-operations-for-the-authenticated-organization /openapi.json get /api/v1/operations # Request cooperative operation cancellation Source: https://infercrane.mintlify.app/api-reference/operations/request-cooperative-operation-cancellation /openapi.json post /api/v1/operations/{id}/cancel # Capture an immutable evidence-backed recipe Source: https://infercrane.mintlify.app/api-reference/recipes/capture-an-immutable-evidence-backed-recipe /openapi.json post /api/v1/deployments/{name}/recipes # Get one immutable model recipe Source: https://infercrane.mintlify.app/api-reference/recipes/get-one-immutable-model-recipe /openapi.json get /api/v1/recipes/{name}/{version} # Search immutable model recipes Source: https://infercrane.mintlify.app/api-reference/recipes/search-immutable-model-recipes /openapi.json get /api/v1/recipes # Attach signed aggregate semantic quality evidence to an immutable revision Source: https://infercrane.mintlify.app/api-reference/release-evidence/attach-signed-aggregate-semantic-quality-evidence-to-an-immutable-revision /openapi.json post /api/v1/deployments/{name}/quality-evidence # Issue a signed Inference Passport Source: https://infercrane.mintlify.app/api-reference/release-evidence/issue-a-signed-inference-passport /openapi.json post /api/v1/deployments/{name}/passports # List revision-bound semantic quality evidence without prompt or output content Source: https://infercrane.mintlify.app/api-reference/release-evidence/list-revision-bound-semantic-quality-evidence-without-prompt-or-output-content /openapi.json get /api/v1/deployments/{name}/quality-evidence # List signed Inference Passports Source: https://infercrane.mintlify.app/api-reference/release-evidence/list-signed-inference-passports /openapi.json get /api/v1/deployments/{name}/passports # Evaluate active and candidate revisions Source: https://infercrane.mintlify.app/api-reference/release-guard/evaluate-active-and-candidate-revisions /openapi.json post /api/v1/deployments/{name}/rollouts/guard/evaluate # Inspect the persisted guard policy Source: https://infercrane.mintlify.app/api-reference/release-guard/inspect-the-persisted-guard-policy /openapi.json get /api/v1/deployments/{name}/release-guard/policy # Set the persisted guard policy Source: https://infercrane.mintlify.app/api-reference/release-guard/set-the-persisted-guard-policy /openapi.json put /api/v1/deployments/{name}/release-guard/policy # Capture a privacy-preserving production workload shape Source: https://infercrane.mintlify.app/api-reference/replay/capture-a-privacy-preserving-production-workload-shape /openapi.json post /api/v1/deployments/{name}/replays # Inspect a persisted workload-shape trace Source: https://infercrane.mintlify.app/api-reference/replay/inspect-a-persisted-workload-shape-trace /openapi.json get /api/v1/replays/{id} # Create a candidate revision Source: https://infercrane.mintlify.app/api-reference/revisions/create-a-candidate-revision /openapi.json post /api/v1/deployments/{name}/rollouts # List immutable deployment revisions Source: https://infercrane.mintlify.app/api-reference/revisions/list-immutable-deployment-revisions /openapi.json get /api/v1/deployments/{name}/revisions # Promote a validated candidate Source: https://infercrane.mintlify.app/api-reference/revisions/promote-a-validated-candidate /openapi.json post /api/v1/deployments/{name}/rollouts/{revision}/promote # Provision candidate capacity Source: https://infercrane.mintlify.app/api-reference/revisions/provision-candidate-capacity /openapi.json post /api/v1/deployments/{name}/rollouts/{revision}/provision # Reject a candidate revision Source: https://infercrane.mintlify.app/api-reference/revisions/reject-a-candidate-revision /openapi.json post /api/v1/deployments/{name}/rollouts/{revision}/reject # Roll back to a prior revision Source: https://infercrane.mintlify.app/api-reference/revisions/roll-back-to-a-prior-revision /openapi.json post /api/v1/deployments/{name}/rollback # Set the active route target Source: https://infercrane.mintlify.app/api-reference/routing/set-the-active-route-target /openapi.json put /api/v1/deployments/{name}/route # List external sandbox references without command, file, prompt, or output content Source: https://infercrane.mintlify.app/api-reference/sandboxes/list-external-sandbox-references-without-command-file-prompt-or-output-content /openapi.json get /api/v1/sandboxes/references # Register an externally owned sandbox and issue an expiring endpoint-scoped credential Source: https://infercrane.mintlify.app/api-reference/sandboxes/register-an-externally-owned-sandbox-and-issue-an-expiring-endpoint-scoped-credential /openapi.json post /api/v1/sandboxes/references # Revoke InferCrane access without mutating the external sandbox Source: https://infercrane.mintlify.app/api-reference/sandboxes/revoke-infercrane-access-without-mutating-the-external-sandbox /openapi.json delete /api/v1/sandboxes/references/{id} # Rotate the expiring endpoint-scoped credential for an active sandbox reference Source: https://infercrane.mintlify.app/api-reference/sandboxes/rotate-the-expiring-endpoint-scoped-credential-for-an-active-sandbox-reference /openapi.json post /api/v1/sandboxes/references/{id}/credential/rotate # List persisted scaling decisions Source: https://infercrane.mintlify.app/api-reference/scaling/list-persisted-scaling-decisions /openapi.json get /api/v1/deployments/{name}/scaling-decisions # Create a reference to an external secret Source: https://infercrane.mintlify.app/api-reference/secrets/create-a-reference-to-an-external-secret /openapi.json post /api/v1/secrets # Delete a secret reference Source: https://infercrane.mintlify.app/api-reference/secrets/delete-a-secret-reference /openapi.json delete /api/v1/secrets/{id} # List secret references Source: https://infercrane.mintlify.app/api-reference/secrets/list-secret-references /openapi.json get /api/v1/secrets # Inspect registered integration capabilities Source: https://infercrane.mintlify.app/api-reference/system/inspect-registered-integration-capabilities /openapi.json get /api/v1/integrations # List live control-plane instances and protocol compatibility Source: https://infercrane.mintlify.app/api-reference/system/list-live-control-plane-instances-and-protocol-compatibility /openapi.json get /api/v1/system/instances # Run control-plane diagnostics Source: https://infercrane.mintlify.app/api-reference/system/run-control-plane-diagnostics /openapi.json get /api/v1/doctor # List inference targets Source: https://infercrane.mintlify.app/api-reference/targets/list-inference-targets /openapi.json get /api/v1/targets # Register an inference target Source: https://infercrane.mintlify.app/api-reference/targets/register-an-inference-target /openapi.json post /api/v1/targets # List content-free external training provenance for deployment revisions Source: https://infercrane.mintlify.app/api-reference/training-lineage/list-content-free-external-training-provenance-for-deployment-revisions /openapi.json get /api/v1/deployments/{name}/training-artifacts # Verify and attach a signed immutable checkpoint handoff Source: https://infercrane.mintlify.app/api-reference/training-lineage/verify-and-attach-a-signed-immutable-checkpoint-handoff /openapi.json post /api/v1/deployments/{name}/training-artifacts # Provider contract Source: https://infercrane.mintlify.app/architecture/provider-contract The lifecycle, ownership, idempotency, inventory, and qualification contract for infrastructure adapters. # Provider Contract V1 Status: implemented contract foundation. Existing elastic and serverless adapters are bound to validated profiles without changing durable lifecycle semantics; real-provider evidence remains deferred until consolidated real-infrastructure qualification. ## Ownership The lifecycle core owns desired intent, serialized mutations, retry policy, revisions and durable evidence. A provider adapter owns translation to one external infrastructure API. Provider-native serverless owns worker scheduling; InferCrane owns the logical endpoint and operation history. ## Required lifecycle semantics * validate configuration and report capabilities without mutation * derive a stable external idempotency/adoption key from persisted replica intent * ensure or adopt exactly one external resource * observe normalized phase, endpoint, health and provider identity * cancel an in-progress request when supported without abandoning cleanup * delete idempotently and prove absence through inventory * discover owned or orphaned resources using explicit ownership metadata * bound calls, redact credentials, classify retryability and preserve provider-native details Elastic, serverless and external targets share capability vocabulary but do not pretend to have the same lifecycle. External targets are registered endpoints; InferCrane does not provision them. ## Qualification states `registered`, `simulated`, `local-qualified`, `real-qualified`, `deferred`, and `failed` are distinct. A capability or adapter registration never implies public support. Evidence is tied to contract version, adapter version, commit, test suite, environment class, timestamp and sanitized artifacts. ## Prohibited coupling Lifecycle core must not switch on provider name. Secrets must not enter persisted provider metadata. Provider pricing, capacity and timing are unknown unless returned by a trustworthy source with timestamp and provenance. # Runtime contract Source: https://infercrane.mintlify.app/architecture/runtime-contract The capability, readiness, protocol, cancellation, and evidence contract for inference runtimes. # Runtime Contract V1 Status: implemented. vLLM is locally qualified; SGLang and declarative custom OCI workloads exercise the contract through hermetic simulation. Real-GPU evidence remains deferred until consolidated real-infrastructure qualification. ## Ownership Inference engines own execution, batching, model loading, cache behavior and engine-native metrics. InferCrane owns immutable runtime identity, capability validation, lifecycle coordination, normalized evidence, routing membership and safe revision policy. ## Required contract A runtime profile declares: * stable adapter and semantic contract version * engine/version and immutable workload identity * protocol and supported operations * readiness and model-identity inspection * buffered and streaming behavior * cancellation and graceful drain/shutdown behavior * telemetry endpoints and normalized metric mappings * tool, structured-output and embedding capabilities where tested * compatibility constraints for artifact, accelerator and runtime arguments Declared, probed, simulated, locally qualified and real-qualified capabilities remain distinct. Unsupported behavior fails before paid provisioning whenever it is knowable. Production composition binds each runtime inspector to its validated `RuntimeProfile`. Provisioning and reconciliation resolve that immutable binding by runtime identity; an adapter cannot execute under a different runtime's capability claims, and an unregistered runtime remains unroutable. ## Custom OCI workloads InferCrane may accept an immutable OCI image plus explicit protocol, port, health, telemetry and shutdown declarations. It does not build or execute an image builder, sandbox arbitrary code, or infer compatibility from an `OpenAI-compatible` label alone. The portable contract persists argv rather than a shell fragment and standardizes `/health`, `/v1/models`, and `/metrics`. It supports OpenAI-compatible HTTP, HTTP-disconnect cancellation, connection-generation draining, and a bounded shutdown-grace declaration. See [Custom OCI workloads](/features/custom-oci) and inspect the exact runtime/provider matrix with `infercrane integrations`. # Architecture Source: https://infercrane.mintlify.app/architecture/system InferCrane's persistent control plane, database-free inference path, and provider boundaries. # Architecture InferCrane separates durable deployment decisions from latency-sensitive inference routing. PostgreSQL is authoritative for the control plane; an atomic in-memory snapshot is authoritative for each gateway replica's request path. Animated architecture diagram separating InferCrane's durable control plane from its database-free inference data plane. ```mermaid theme={"theme":{"light":"github-light-default","dark":"vesper"}} flowchart LR subgraph clients[Clients] CLI[InferCrane CLI] DASH[Separate web console] DELIVERY[SDK · Terraform · GitHub] SDK[Inference client] end subgraph infercrane[InferCrane] API[Authenticated control API] OPS[Leased operation worker] DB[(PostgreSQL)] REC[Reconciler] SNAP[Atomic route snapshot] GW[Gateway] ROUTER[Replica router generation] COMPOSE[Composition registry] end subgraph external[External systems] ELASTIC[Elastic backend adapter] NATIVE[Serverless backend adapter] V1[Runtime replica] V2[Runtime replica] EXTGW[User-managed gateway] SANDBOX[External sandbox] TRAIN[Training pipeline / registry] end CLI --> API --> DB DASH --> API DELIVERY --> API DB --> OPS OPS --> ELASTIC OPS --> NATIVE DB --> REC REC --> V1 REC --> V2 REC --> ROUTER REC --> SNAP API --> COMPOSE COMPOSE --> EXTGW COMPOSE --> SANDBOX COMPOSE --> TRAIN SDK --> GW --> SNAP --> ROUTER SANDBOX -. endpoint-scoped inference token .-> GW TRAIN -. signed artifact handoff .-> API ROUTER --> V1 ROUTER --> V2 GW -. buffered accounting .-> DB ``` ## Control plane The CLI, separately deployed web console, generated SDKs, Terraform provider, and GitHub delivery action use the same authenticated API. None owns provider resources or reads PostgreSQL. PostgreSQL stores desired and observed deployment state, immutable revisions, replicas, operations, events, policy evaluations, and bounded measurements. A leased worker resumes pending provider work after process failure and reconciles results back into persisted state. External ownership stays explicit and replaceable behind narrow adapters: * An elastic backend provisions and deletes replica infrastructure. * A provider-native serverless backend owns worker allocation and scale-to-zero. * An artifact resolver identifies and transfers immutable model artifacts. * A benchmark runner generates load and returns reproducible evidence. * A composition registry describes replaceable gateway, sandbox, and training handoff contracts without claiming lifecycle ownership of those external systems. InferCrane does not replace any of them with a general scheduler or workflow engine. The process composes registered elastic, serverless, external-target, runtime, artifact, and benchmark adapters. RunPod, AWS EC2, and Kubernetes are current infrastructure adapters with different qualification states; vLLM, SGLang, and custom OCI are current runtime profiles. Durable algorithms do not select implementations with provider conditionals; [qualification is separate from registration](/adr/0009-qualified-support-and-backend-registration). ## A modular system, not a bundled stack Users select a serving plan; adapters translate it into infrastructure-specific work. Core lifecycle state does not depend on a RunPod, AWS, Kubernetes, vLLM, SGLang, or gateway-specific domain model. ```mermaid theme={"theme":{"light":"github-light-default","dark":"vesper"}} flowchart TB INTENT[Endpoint · environment · serving intent] CORE[InferCrane core
desired state · operations · revisions · evidence] INTENT --> CORE CORE --> INFRA{Infrastructure contract} CORE --> RUNTIME{Runtime contract} CORE --> ROUTE{Route type} CORE --> ARTIFACT{Artifact resolver} CORE --> BENCH{Benchmark runner} CORE --> COMPOSE{Composition contract} INFRA --> AWS[AWS EC2] INFRA --> RP[RunPod] INFRA --> K8S[Kubernetes] RUNTIME --> VLLM[vLLM] RUNTIME --> SGL[SGLang] RUNTIME --> OCI[Custom OCI] ROUTE --> NATIVE[InferCrane-managed replicas] ROUTE --> SL[Provider-native serverless] ROUTE --> EXT[Adopted or governed external target] ARTIFACT --> HF[Hugging Face / Xet] BENCH --> AIP[AIPerf] COMPOSE --> LLMGW[LiteLLM or another gateway] COMPOSE --> SBX[E2B · Modal · Kubernetes sandbox] COMPOSE --> TRN[MLflow · Kubeflow · external training] ``` | Layer | InferCrane owns | Integrated system owns | | -------------------------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | | Infrastructure | intent, durable identity, retries, reconciliation, cleanup evidence | compute allocation and provider API semantics | | Runtime | capability contract, immutable configuration, readiness qualification | inference engine and model execution | | Gateway or external target | stable endpoint identity, admission, policy, request evidence | optional protocol translation and its provider credentials | | Artifact | immutable model identity and cache observations | transfer and provider-native storage primitives | | Benchmark | reproduction record, comparison, policy input | load generation and raw measurement | | Sandbox composition | endpoint-scoped, expiring inference identity and content-free reference metadata | isolation, commands, files, networking, snapshots, and execution lifecycle | | Training composition | signature verification, immutable artifact lineage, and revision attachment | datasets, training jobs, registry availability, and checkpoint storage | A user-managed LiteLLM deployment, for example, can be connected as an OpenAI-compatible external gateway. InferCrane does not bundle or fork LiteLLM: it retains endpoint identity and operational evidence while LiteLLM retains provider translation and its own configuration. See the [gateway and sandbox showcase](/showcase/gateways-and-sandboxes). ## Data plane An OpenAI-compatible request resolves the logical model alias from an atomic route snapshot. For standalone replica runtimes, it then passes to an instance-owned vLLM Router generation and a healthy worker. Provider-native Serverless and governed external targets remain explicit route types. No PostgreSQL lookup occurs in that routing decision. Each horizontally scaled gateway process owns its loopback router processes and deterministic ports. Gateway instances share PostgreSQL state, never another instance's local router. ## Request lifecycle The gateway authenticates the bearer token, validates the OpenAI request, and resolves the requested deployment alias. The route directory returns a ready generation without network or database I/O. vLLM Router applies the persisted strategy to its healthy standalone vLLM endpoints. The gateway proxies the upstream response. Streaming responses are not constrained by the ordinary server write timeout. Request accounting and normalized measurements enter bounded buffers and persist outside the routing decision. ## Safe route changes The reconciler probes worker health and served-model identity, calculates membership, starts a candidate router generation, and only then publishes a new snapshot. Scale-down fences routing and drains the worker before provider termination. Failed candidates never replace the last healthy route. Read the rules every implementation change must preserve. Follow the reasoning behind persistence, tenancy, revisions, and operation execution. # CLI reference Source: https://infercrane.mintlify.app/cli Commands for configuring, deploying, observing, updating, and deleting InferCrane deployments. # CLI reference The public CLI uses Cobra for grouped help, typo suggestions, aliases, and shell completion. It talks to the authenticated control-plane API and never opens PostgreSQL directly. Run `infercrane help` for the current command tree and `infercrane version` for the build version. ## Global conventions * Commands that return data accept `--output human|json`. * `status --watch --output json` emits one JSON document per state refresh. * Mutation commands accept `--idempotency-key`; generated keys are printed in human and JSON output and attached to uncertain-request errors. Reuse the same key after an uncertain result. * `--wait` polls persisted operation state and prints only changed progress. Closing the client does not cancel server-side work; the operation ID and exact `infercrane operation watch ID` resume command are printed before waiting begins. * `--wait-timeout 20m` bounds the local watcher without cancelling the durable operation. Resume with `infercrane operation watch ID`; cancel only with `infercrane operation cancel ID`. * JSON failures contain `code`, `category`, `message`, `retryable`, `remediation`, and provider HTTP status when available. * Command help is available before authentication: `infercrane COMMAND --help` never contacts the control plane. * `infercrane --context NAME COMMAND` selects a context for one invocation. * `infercrane --no-color COMMAND` and the standard `NO_COLOR` environment variable disable ANSI styling. Redirected output and JSON are never decorated. ## Configure and diagnose ### `init` Validate and store a control-plane URL and an already-issued credential in a named private client context. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} INFERCRANE_API_KEY='ISSUED_CREDENTIAL' \ infercrane init --context production --url https://infercrane.example ``` | Flag | Default | Meaning | | ----------- | ----------------------- | ----------------------------------------------------------------------- | | `--url` | `http://127.0.0.1:8080` | Control-plane base URL | | `--context` | `default` | Context name to create and select | | `--api-key` | environment | Existing credential; prefer `INFERCRANE_API_KEY` to avoid shell history | | `--output` | `human` | `human` or `json` | `init` verifies authentication through the read-only identity endpoint before writing configuration. Use `--skip-check` only when intentionally configuring an offline control plane. It does not create or enroll a principal. ### Contexts and authentication ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane context list infercrane context show infercrane context use production infercrane --context staging status qwen-prod infercrane auth status infercrane auth status --output json ``` JSON output uses stable lowercase fields (`id`, `tenant_id`, `name`, `role`, `kind`, and `scopes`) so authentication checks can be consumed directly by scripts without depending on Go field names. Legacy single-context configuration is migrated on the next `init`. Context listing and display never print stored credentials. ### Shell completion ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane completion bash infercrane completion zsh infercrane completion fish infercrane completion powershell ``` Homebrew installs generated completions automatically. Completion is read-only and may suggest deployment names from the configured control plane; an unavailable control plane produces no completion error or mutation. ### `doctor` Ask the control plane to check its own dependencies. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane doctor infercrane doctor --cloud infercrane doctor --serverless --output json infercrane doctor --aws infercrane doctor --gcp infercrane doctor --kubernetes infercrane doctor coder-production --window 1h ``` `--cloud` adds SkyPilot credentials and RunPod advisory accelerator availability; `--serverless` adds RunPod Serverless credentials and template validation; `--aws` performs a read-only role assumption and identity probe for the configured AWS BYOC adapter; `--gcp` checks Application Default Credentials plus read-only Compute zone access; `--kubernetes` checks the explicit context, optional KServe CRD, and required namespaced permissions. Diagnostics are read-only and do not create provider resources. The capability table distinguishes `supported`, `unsupported`, and `unknown`. InferCrane never silently changes hardware, and never claims cache or fast-resume behavior that an adapter cannot observe. ## Operations workspaces ### `inbox` ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane inbox infercrane inbox --limit 100 --output json ``` The inbox reads tenant-scoped endpoint and deployment summaries, ranks non-serving state and staged candidates deterministically, and prints the exact persisted field behind each item. It fails the whole read if either fleet API is unavailable, so a partial inventory cannot look healthy. It does not run Doctor implicitly and never reads prompt or response content. ### `observe` ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane observe coder-production infercrane observe qwen-prod --watch infercrane observe coder-production --diagnose ``` The default snapshot is read-only. Endpoint snapshots combine logical identity, serving plans, Guard, admission, and alerts; deployment snapshots combine lifecycle, traffic, active operation, Guard, and events. `--diagnose` explicitly persists a fresh deterministic Doctor evaluation. ### `artifact` ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane artifact inspect ARTIFACT_ID infercrane artifact prefetch ARTIFACT_ID --provider aws --location cache://models infercrane artifact observe ARTIFACT_ID --provider aws --location cache://models \ --state present --source aws-ebs-adapter --ttl 10m ``` Prefetch records durable intent; only a fresh provider observation is cache-hit evidence. ### `evaluation` ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane evaluation keygen --file quality-evidence.key infercrane evaluation ingest DEPLOYMENT REVISION --result evaluator-result.json \ --key quality-evidence.key --file evidence.json --attach infercrane evaluation sign DEPLOYMENT REVISION --suite SUITE --suite-version VERSION \ --evaluator NAME --evaluator-version VERSION --score 0.95 --passed=true \ --samples 100 --artifact-digest sha256:DIGEST \ --key quality-evidence.key --file evidence.json infercrane evaluation verify evidence.json infercrane evaluation attach DEPLOYMENT --file evidence.json infercrane evaluation list DEPLOYMENT ``` `ingest` accepts the strict evaluator-result v1 interchange contract, rejects unknown content fields, binds it to one immutable revision, signs it, and optionally attaches it. Evidence is signature-verified and contains aggregate values only. ### `mcp` ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane mcp ``` Starts a stdio MCP server with read-only deployment, endpoint, request, operation, and curated-recipe tools. No mutation tool is registered. See [MCP for coding agents](/integrations/mcp). ## Admission and async inference ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane admission get coder-production infercrane admission set coder-production --max-concurrency 32 --max-queue 64 \ --queue-timeout-ms 5000 --max-output-tokens 8192 --priorities normal,high infercrane async submit coder-production --file request.json \ --idempotency-key document-42 infercrane async get JOB_ID infercrane async cancel JOB_ID ``` `async submit` persists protocol-native request content only after explicit encrypted-storage consent, returns a durable job ID, and does not depend on the client remaining connected. See [Admission and async inference](/features/admission-async) for retry, retention and webhook rules. ### Terminal ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane ui ``` The terminal workspace is reconnectable, supports state-valid guarded actions, and can be forced read-only with `infercrane ui --read-only`. It requires an interactive terminal and never uses tmux for persistence. See [Terminal operations workspace](/features/terminal-ui). ## Plan and deploy ### `workload` Create a repository-local inference project, validate it without allocating a GPU, and use the same DeploymentSpec for build, plan, and deployment: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane workload init ./fraud-explainer \ --model mistralai/Mistral-7B-Instruct-v0.3 infercrane workload validate ./fraud-explainer infercrane workload plan ./fraud-explainer infercrane workload deploy ./fraud-explainer --wait ``` `workload init --recipe NAME` pins a reviewed model commit. `workload build --tag IMAGE` performs a local Docker Buildx build for custom OCI projects; add `--push` to record a registry-confirmed immutable digest. `workload dev` binds a custom OCI workload only to loopback. See [Inference projects](/features/inference-projects). ### `plan` Preview semantic changes without provider or database mutation. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane plan Qwen/Qwen3-8B \ --name qwen-prod \ --cloud runpod \ --gpu L40S \ --min 1 \ --max 4 ``` Provisioned and serverless plans include an explicit readiness-evidence boundary: ```text theme={"theme":{"light":"github-light-default","dark":"vesper"}} Readiness: unavailable — fresh provider capacity and artifact-cache observations are not available during this static plan; no startup time is fabricated Artifact cache: unknown Capacity: unknown Startup stages: capacity -> container -> artifact -> runtime -> readiness ``` This is intentionally not a time estimate. Once an operation starts, durable events replace unknown stages with provider and runtime observations where those boundaries are actually exposed. ### `deploy` and `apply` `deploy` creates a cloud or existing-target deployment. `apply` declaratively converges a deployment using the same input shape. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane deploy Qwen/Qwen3-8B \ --cloud runpod \ --gpu L40S \ --min 1 \ --max 4 \ --idempotency-key qwen-prod-initial \ --wait infercrane apply examples/infercrane.yaml \ --idempotency-key qwen-prod-spec-01 ``` | Flag | Default | Applies to | Meaning | | ------------------- | ------------------------------- | ------------------ | ----------------------------------------------------------------------------------------------- | | `--name` | derived from model | all | Logical deployment name | | `--targets` | none | existing | Comma-separated registered targets | | `--cloud` | `runpod` on primary path | elastic/serverless | Registered provider cloud; `runpod`, `aws`, and `kubernetes` have distinct qualification states | | `--gpu` | `L40S` on primary path | elastic/serverless | Requested GPU | | `--region` | provider-selected | provisioned | Provider region; required for AWS BYOC and ignored by the namespace-scoped Kubernetes adapter | | `--compute` | `elastic` | provisioned | `elastic` or `serverless` | | `--min` | `1`; serverless defaults to `0` | provisioned | Minimum replicas/workers | | `--max` | `1` | provisioned | Maximum replicas/workers | | `--wait` | false | mutations | Follow durable progress to a terminal state | | `--wait-timeout` | unlimited | waited mutations | Stop the local wait after a Go duration such as `20m`; the operation continues | | `--idempotency-key` | generated | mutations | Stable safe-retry identity | | `--output` | `human` | all | `human` or `json` | A YAML path cannot be combined with deployment flags. See [DeploymentSpec](/deployment-spec). SGLang and custom OCI use the YAML form because their runtime contract is part of the immutable revision. See [SGLang](/integrations/sglang) and [Custom OCI workloads](/features/custom-oci). After submission, human output prints the exact commands to follow durable progress. A successful wait prints the command for the first inference request. ### `integrations` ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane integrations infercrane integrations --output json ``` Displays registered provider, runtime, and external composition capabilities, evidence state, and the exact qualified runtime/provider/compute-mode combinations. Registration alone never implies production support. ### `sandbox` Compose an externally operated sandbox with one stable inference endpoint: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane sandbox connect \ --provider e2b \ --external-id sandbox-01JCGW \ --external-revision template-v3 \ --endpoint coder-production \ --ttl 30m infercrane sandbox list --output json infercrane sandbox rotate SANDBOX_REFERENCE_ID --output json infercrane sandbox revoke SANDBOX_REFERENCE_ID --yes ``` `connect` and `rotate` reveal a credential once. It expires within 24 hours, can invoke only the selected endpoint alias, and cannot use control-plane routes. `revoke` disables InferCrane access without mutating the external sandbox. See [External agent sandboxes](/integrations/sandboxes). ### `training` Verify a signed, content-free artifact handoff from an external training system: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane training keygen --file training-handoff.key infercrane training sign DEPLOYMENT REVISION_ID \ --provider mlflow --run RUN_ID \ --repository mlflow://registry/model/VERSION \ --immutable-revision VERSION --digest sha256:DIGEST \ --key training-handoff.key --file artifact.handoff.json infercrane training verify artifact.handoff.json infercrane training attach DEPLOYMENT artifact.handoff.json infercrane training list DEPLOYMENT --output json ``` The private signing key remains local. Attachment binds immutable identity to one revision but does not promote it or claim that InferCrane executed training. See [Training artifact handoffs](/integrations/training-artifacts). ## Send a request Use the logical deployment name without assembling an HTTP request by hand: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane request qwen-prod --message "Explain continuous batching in one sentence." infercrane request qwen-prod --message "Count to five." --stream infercrane request search-production --protocol embeddings --message "Document to embed" infercrane request coder-production --protocol responses --message "Review this function" ``` `--output json` returns the OpenAI-compatible choices and usage object for non-streaming requests. The command uses the configured endpoint and credential; applications can continue to use any OpenAI-compatible SDK directly. `--protocol` accepts `chat`, `responses`, `embeddings`, `completions`, or `batch`; the endpoint must explicitly qualify the selected surface. Inspect the persisted routing and timing evidence for a returned `X-Request-Id` without retrieving prompt or output content: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane request inspect req_123 infercrane request inspect req_123 --output json ``` ## Stable endpoints Separate the name applications call from the deployment that currently serves it: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane logical-model create coder --description "Stable coding model" infercrane endpoint create coder-production --model coder --environment production infercrane endpoint bind coder-production --name primary --deployment qwen-prod infercrane endpoint plan coder-production --policy manual --bindings primary infercrane request coder-production --message "Review this function." ``` `endpoint plan` makes the first plan active and stages later plans as candidates. Inspect and promote explicitly: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane endpoints infercrane endpoint inspect coder-production infercrane endpoint guard coder-production --evaluate infercrane endpoint promote coder-production PLAN_ID ``` `--bindings` is ordered and accepts optional bounded weights, for example `primary:80,overflow:20`. See [stable endpoints and serving plans](/features/endpoints). Authenticated external APIs add provider-neutral policy flags to `endpoint bind`: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane endpoint bind coder-production \ --name managed-fallback \ --target managed-coder \ --ownership traffic-managed \ --external-adapter openai-compatible-external \ --secret-reference SECRET_REFERENCE_ID \ --request-limit 1000 \ --cost-limit-usd 25.00 \ --max-request-cost-usd 0.10 \ --acknowledge-external-data \ --enable-external ``` The control plane rejects raw credentials, missing consent, absent hard limits, cross-tenant secret references, and adapter/target mismatches before creating the binding. Stage one environment's active immutable plan as another endpoint's candidate: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane environment promote coder-staging --to coder-production infercrane environment promote coder-staging --to coder-production --yes ``` The first command is a non-mutating preview. Staging never switches production traffic; destination Release Guard and explicit endpoint promotion remain required. ## Connect an existing workload The simple path verifies the upstream model list through the control-plane API and starts in observe-only mode: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane connect https://vllm.internal/v1 --as coder-production --type vllm ``` Use `--model` when the endpoint exposes more than one physical model. Use `--manage-traffic` only when the endpoint has been qualified and should immediately enter the InferCrane logical route. The advanced ownership-compatible command remains available: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane adopt endpoint coder-production \ --url https://vllm.internal/v1 \ --model coder \ --upstream-model Qwen/Qwen3-8B \ --ownership observe-only infercrane adopt promote coder-production --ownership traffic-managed ``` Use `traffic-managed` only when InferCrane should publish the healthy existing target. Neither mode transfers provider lifecycle ownership. See [Adopt and diagnose](/features/adoption-diagnostics). ## Existing targets and routing ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane target add gpu-a \ --url http://gpu-a:8000 \ --runtime vllm \ --upstream-model Qwen/Qwen3-8B infercrane target list --output json infercrane route qwen-prod --strategy cache-aware ``` Supported strategies are `round-robin`, `consistent-hash`, `power-of-two`, and `cache-aware`, delegated to the pinned vLLM Router. ## Observe and explain | Command | Purpose | | ----------------------------------------- | ---------------------------------------------------------------------------------------------------------- | | `inbox [--limit N]` | Rank persisted fleet state requiring operator attention without mutation | | `observe ENDPOINT_OR_DEPLOYMENT` | Join one resource's lifecycle, traffic, Guard, policy, operation, and event evidence | | `deployments [--output json]` | List logical deployments | | `status DEPLOYMENT [--watch]` | Show serving health separately from convergence, readiness, traffic, revisions, and the blocking operation | | `events DEPLOYMENT` | Show ordered durable deployment events | | `logs DEPLOYMENT [--follow]` | Stream a filtered durable operational timeline | | `request ENDPOINT` | Send a capability-qualified OpenAI-compatible inference request | | `inspect DEPLOYMENT` | Show raw targets, replicas, artifacts, request statistics, and infrastructure metadata | | `operation ID` | Inspect durable progress and result once | | `operation watch ID` | Resume following a durable operation after disconnect or from another terminal | | `operation cancel ID` | Request cooperative cancellation | | `orphans` | List unmanaged provisioned resources visible to the control plane | | `integrations` | Inspect provider, runtime, and external composition capabilities and qualification state | | `sandbox connect/list/rotate/revoke` | Manage only endpoint-scoped access for externally owned sandboxes | | `training keygen/sign/verify/attach/list` | Verify and bind signed external training artifact lineage | ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane status qwen-prod --watch infercrane logs qwen-prod --follow infercrane logs qwen-prod --type runtime --since 15m infercrane events qwen-prod --output json infercrane inspect qwen-prod infercrane operation watch OPERATION_ID infercrane integrations infercrane integrations --output json ``` Long operations belong to the control plane, not the terminal. `deploy`, `apply`, rollout, scale, and deletion continue after the CLI disconnects. Pressing Ctrl-C stops only the local watcher. Run `infercrane operation watch ID` later to resume from persisted progress; add `--wait-timeout 20m` to bound only the new local watch. Explicit `infercrane operation cancel ID` is the separate action that requests cooperative server-side cancellation and provider cleanup. `status` deliberately separates two concerns. `Serving` answers whether the current route can accept inference traffic. `Convergence` answers whether desired capacity, a rollout, or deletion is still progressing. A deployment can therefore be `serving · converging` while a provider allocates another replica; this is not reported as an outage. JSON output exposes the same stable fields under `lifecycle_status`, including ready and desired replica counts, provisioning and draining counts, candidate state, and the blocking durable operation. Deterministic explanations use only persisted state and measurements: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane explain qwen-prod infercrane explain scaling qwen-prod infercrane explain rollout qwen-prod infercrane explain cold-start qwen-prod ``` ## Benchmark Run AIPerf and persist the exact reproduction metadata. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane benchmark qwen-prod \ --requests 1000 \ --concurrency 32 \ --random-seed 17 \ --revision active ``` `--revision` accepts `active`, `candidate`, or an explicit revision ID. Defaults are 100 requests, concurrency 10, and seed 17. Capture and search immutable recipes only after a matching benchmark exists: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane recipe create qwen-prod --name qwen3-balanced --version 1.0.0 infercrane recipes qwen3 --limit 20 ``` Compare persisted measured configurations without provisioning new capacity: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane lab 'Qwen/Qwen3-8B@IMMUTABLE_COMMIT' --max-ttft-p95-ms 250 ``` See [Recipes and Inference Lab](/features/recipes-lab) for the provenance and missing-evidence contract. ## Replay and capacity ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane replay coder-production --window 24h infercrane capacity --window 720h ``` Replay captures content-free production shape by default. Running an AIPerf approximation requires both `--execute` and `--acknowledge-cost`. See [Replay and capacity intelligence](/features/replay-capacity). ## Revisions and Release Guard ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane rollout inspect qwen-prod infercrane rollout policy get qwen-prod infercrane rollout policy set qwen-prod \ --require-compatibility \ --require-synthetic \ --auto-rollback \ --validation-max-requests 100 \ --validation-max-concurrency 4 infercrane rollout create qwen-prod \ --model Qwen/Qwen3-8B \ --cloud runpod \ --gpu H100 \ --min 1 \ --max 2 \ --idempotency-key qwen-prod-rev-19 infercrane rollout provision qwen-prod REVISION_ID --wait infercrane rollout validate qwen-prod --acknowledge-validation-cost --wait infercrane rollout promote qwen-prod REVISION_ID --reason 'guard accepted' infercrane rollout reject qwen-prod REVISION_ID --reason 'TTFT regression' infercrane rollout rollback qwen-prod REVISION_ID --wait ``` Candidate creation also accepts `--model-revision`, `--runtime`, `--runtime-version`, `--runtime-args`, `--routing`, and `--region`. Promotion remains policy-gated; no LLM decides the outcome. `rollout validate` is explicit synthetic traffic, not shadowing. It runs the existing AIPerf adapter against active and candidate revisions using the same workload and persisted hard bounds. The acknowledgement is mandatory because both runs may incur provider cost. ## Signed release evidence ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane passport keygen infercrane passport issue qwen-prod --file qwen-prod.passport.json infercrane passport verify qwen-prod.passport.json infercrane passport list qwen-prod --output json ``` `passport keygen` and `passport verify` work without a configured control-plane context. Issue and list use the authenticated API. See [Inference Passports](/features/inference-passports). ## Delete Preview cleanup, then confirm it explicitly. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane delete qwen-prod --plan infercrane delete qwen-prod \ --yes \ --wait \ --idempotency-key qwen-prod-delete-01 infercrane orphans ``` `--plan` is side-effect-free. `--yes` is required for mutation. After a paid test, also verify the provider inventory reaches zero. ## Tenant administration These commands require an admin/bootstrap credential. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane tenant create team-a --name 'Team A' infercrane principal create deploy-bot --role operator --scopes read,deploy infercrane principal rotate PRINCIPAL_ID infercrane principal revoke PRINCIPAL_ID ``` New and rotated tokens are returned once. Service-account scopes can only restrict the role ceiling; they can never grant an action unavailable to `viewer`, `operator`, or `admin`. Omitting `--scopes` uses every action allowed by the selected role for compatibility. ## Secret references Register metadata that points to an injected environment value. InferCrane never accepts the raw secret on the command line or through its API. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane secret create openrouter --from-env OPENROUTER_API_KEY infercrane secret list infercrane secret list --output json infercrane secret delete SECRET_ID --yes ``` ## Signed alerts ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane alert list coder-production infercrane alert configure coder-production --webhook https://alerts.example.com/hook \ --secret-reference SECRET_ID --minimum-severity warning infercrane alert evaluate coder-production ``` Alerts contain deterministic Doctor findings and HMAC headers; delivery is idempotent and bounded. ## Governed external fallback External targets require `manage_external`. They are selected only when ordinary targets are unhealthy and require an explicit privacy acknowledgement plus hard budgets. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane target add openrouter-qwen \ --provider openrouter \ --url https://openrouter.ai/api/v1 \ --upstream-model qwen/qwen3-8b infercrane external configure qwen-prod \ --target openrouter-qwen \ --secret-reference SECRET_REFERENCE_ID \ --request-limit 100 \ --cost-limit-usd 10 \ --max-request-cost-usd 0.10 \ --acknowledge-external-data \ --enable infercrane external inspect qwen-prod --output json ``` See [Governed external capacity](/features/external-capacity) for transmission and reservation semantics. ## SLO policy and recommendations Define explicit fail-closed thresholds, then evaluate persisted benchmark evidence. Recommendations are advisory and never mutate the deployment. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane slo set qwen-prod --ttft-p95 250 --error-rate 0.01 infercrane slo get qwen-prod --output json infercrane recommend qwen-prod infercrane recommend qwen-prod --history --output json infercrane slo delete qwen-prod ``` `recommended` identifies a qualified candidate satisfying the policy. `no_match` means measured candidates violate it. `unknown` means required evidence is missing. See [Inference decisions](/features/inference-decisions). # Choose the right inference approach Source: https://infercrane.mintlify.app/compare Compare InferCrane with managed inference platforms, model APIs, gateways, and Kubernetes-native stacks. # Not every team needs an inference control plane Choose based on the responsibility you want to own. InferCrane is designed for teams that want control of their infrastructure or existing inference stack without building the operational layer from scratch. | Approach | Best when | You delegate | You retain | | -------------------------- | ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | | Managed inference platform | Fastest hosted path matters more than infrastructure portability | Compute, scheduling, builds, scaling, and much of operations | Model/application behavior | | Hosted model API | You want an API call and no model-serving operations | Model weights, runtime, infrastructure, and capacity | Application and provider selection | | AI gateway | You need one API across managed model providers | Protocol translation, provider routing, and accounting | Provider accounts and workload deployment | | Kubernetes-native serving | Your platform team already operates Kubernetes and wants native resources | Cluster reconciliation primitives | Cluster, networking, storage, GPU scheduling, and serving stack | | InferCrane | You want a stable endpoint and evidence-driven lifecycle across infrastructure you control | Durable operations, revisions, rollout policy, explanations, and adapter contracts | Provider accounts, runtime choice, infrastructure visibility, and data boundary | ## InferCrane and managed platforms [Baseten](https://docs.baseten.co/overview) and [Modal](https://modal.com/docs/guide) offer managed compute and highly integrated hosted experiences. They are usually a better fit when the team wants the vendor to own infrastructure and capacity from day one. InferCrane is differentiated by customer-controlled infrastructure, incremental adoption of existing endpoints, replaceable provider/runtime contracts, persisted operational decisions, and explicit qualification boundaries. It is not currently a managed-compute substitute. ## InferCrane and gateways LiteLLM and OpenRouter solve different layers: * A user-managed LiteLLM gateway can translate and route among managed model APIs. * OpenRouter can provide external model capacity through its hosted API. * InferCrane manages stable endpoint identity, lifecycle state, revisions, infrastructure-backed deployments, rollout evidence, and bounded external overflow. These tools can compose. InferCrane can connect a LiteLLM endpoint or use explicitly governed OpenRouter capacity; it does not fork or silently replace either product. ## InferCrane and Kubernetes inference stacks KServe, llm-d, NVIDIA Dynamo, and Kubernetes Gateway API provide powerful cluster-native serving and data-plane capabilities. InferCrane can use qualified infrastructure/runtime integrations while remaining the user-facing lifecycle and evidence layer. It does not build another Kubernetes operator or reimplement distributed serving. ## The decision shortcut You want the vendor to own compute and the fastest route to a hosted endpoint. You want to consume hosted models and do not need to operate weights or runtimes. You already have a platform team and want cluster-native serving resources. You want to build or connect inference on your infrastructure with durable operations and evidence. This comparison describes product categories, not a benchmark. Verify current vendor capabilities, pricing, support, and deployment boundaries directly with each provider. # Compatibility and qualification Source: https://infercrane.mintlify.app/compatibility How InferCrane separates registered adapters, local conformance, and real-infrastructure support evidence. # Compatibility and qualification policy InferCrane follows semantic versioning after `1.0`. The complete API, DeploymentSpec, database, integration-contract, deprecation, mixed-version, and support-window rules are in [Upgrade and compatibility](/upgrade). PostgreSQL migrations are forward-only and must be backed up before rollout. Mixed-version operation is unsupported unless a release explicitly says otherwise. ## Compatibility dimensions Every release candidate must record the tested versions of Go, PostgreSQL, vLLM Router, vLLM, Python, container runtime, GPU driver, CUDA, model, and infrastructure provider. Absence from that matrix means unqualified, not incompatible. `infercrane integrations --output json` is the executable capability inventory. RunPod elastic/serverless, AWS EC2 elastic, GCP Compute elastic, and Kubernetes elastic are distinct provider profiles; OpenRouter is a governed external target profile. Local conformance and real-provider qualification are separate fields. AWS ASG/EKS/SageMaker/Bedrock, GCP MIG/GKE/Vertex, and CoreWeave CKS have independent registered boundaries but remain non-executable and deferred. Advanced KServe/llm-d/ Dynamo topologies and unregistered external adapters remain unqualified. The OpenAI-compatible surface is contract-tested for model listing and chat completions. New API fields should pass through unless InferCrane must interpret them. Removing or changing an accepted field requires a deprecation period after `1.0`. Endpoint admission applies uniformly across qualified protocols. Buffered requests to managed capacity may use a bounded retry budget; streaming and external paid routes are never replayed. Durable async execution supports Chat Completions, Responses, Embeddings, Completions and bounded chat batch only when the selected runtime declares the corresponding protocol capability. Async does not make an unsupported runtime protocol compatible. ## Release qualification gates 1. Unit and PostgreSQL integration tests pass with the race detector and `go vet`. 2. The Docker stack smoke test passes, including planning, diagnostics, routing, metrics, and load. 3. Upgrade and backup/restore drills pass against a copy of production-like data. 4. Worker loss, router failure, PostgreSQL failover, cancellation, and shutdown are exercised. 5. A sustained real-vLLM GPU benchmark records throughput, p50/p95 latency, errors, and versions. Local fake workers validate control flow only. They cannot satisfy gates 3–5 or support performance claims. Repository commands: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} make test-container # race tests, vet, and real PostgreSQL integration make test-stack # full Compose request and CLI smoke path make test-failure # worker loss and control-plane restart recovery make test-kubernetes-kind # Kubernetes ownership and recovery without a GPU make test-kubernetes-kwok # large fleet, pending GPU capacity, node loss, and cleanup make qualify-product-nightly # coverage-guided fuzzing and repeated reliability soak ``` # Core concepts Source: https://infercrane.mintlify.app/concepts The six objects you need to understand InferCrane's deployment and request model. # One stable endpoint, replaceable serving plans Applications call an **endpoint**. Everything behind it can evolve without changing the model name in application code. ```mermaid theme={"theme":{"light":"github-light-default","dark":"vesper"}} flowchart LR APP[Application
model: coder-production] --> EP[Endpoint] LM[Logical model
coder] --> EP ENV[Environment
production] --> EP EP --> PLAN[Active serving plan] EP -. validation .-> CAND[Candidate serving plan] PLAN --> B1[Managed deployment] PLAN --> B2[Adopted or external binding] ``` ## The application layer | Concept | Meaning | Example | | ------------- | ------------------------------------------------------------- | ---------------------------------------- | | Logical model | Product-level identity independent of physical implementation | `coder` | | Environment | Policy and isolation context | `development`, `staging`, `production` | | Endpoint | Stable OpenAI-compatible name used by applications | `coder-production` | | Serving plan | Immutable set of ordered backend bindings and routing policy | primary deployment plus bounded fallback | An endpoint can have one active plan and one candidate plan. Promotion changes the plan behind the stable endpoint; applications do not learn provider URLs or revision IDs. ## The lifecycle layer | Concept | Meaning | | -------------- | ---------------------------------------------------------------------------------- | | DeploymentSpec | Desired model artifact, runtime, compute mode, capacity bounds, and routing policy | | Deployment | A lifecycle-managed realization of a serving plan | | Revision | Immutable snapshot created by an update | | Replica intent | Durable claim that one external worker should exist | | Operation | Leased, retryable state machine for create, update, scale, rollback, or delete | Updates create a candidate revision beside the active revision. Release Guard evaluates persisted readiness and request measurements before explicit promotion. A rejected candidate does not replace the active revision. Replica identity is deterministic, so retrying after a timeout or control-plane restart does not create another provider resource for the same intent. CLI progress is a view of the durable operation; closing the CLI does not cancel it. ## The evidence layer * **ModelArtifact** resolves mutable model references to immutable repository commits where possible. * **Request records** connect latency, tokens, retries, fallback, endpoint, plan, revision, and replica. * **Release Guard evaluations** persist inputs, thresholds, decision, and reasons. * **Inference Passports** sign bounded revision and evidence identity for offline verification. * **Explanations** reproduce conclusions from persisted state and measurements; an LLM does not decide. ## The integration layer Provider and runtime adapters implement narrow contracts. Registration means code is available; qualification means an exact combination has passed a defined evidence gate. The distinction prevents “adapter exists” from becoming an unsupported production claim. Understand control-plane and data-plane ownership. Bind a logical model and environment to serving plans. Follow a durable operation from intent to convergence. # HTTP control API Source: https://infercrane.mintlify.app/control-api Authenticated v1 endpoints, roles, idempotency, and stable errors implemented by InferCrane. # HTTP control API Base path: `/api/v1`. All requests require `Authorization: Bearer TOKEN`. Mutations require operator or admin role; tenant/principal/audit administration requires admin. Cross-tenant resources return `404` to avoid existence disclosure. InferCrane publishes an executable OpenAPI 3.1 document at `api/openapi.json`. The Mintlify navigation generates interactive endpoint pages from the same document used to generate the Python and TypeScript low-level clients. CI compares every contracted method/path pair with the registered routes in `internal/controlapi/api.go` and rejects stale generated files. Errors are stable JSON objects: ```json theme={"theme":{"light":"github-light-default","dark":"vesper"}} {"error":{"code":"forbidden","message":"principal is not allowed to perform this action"}} ``` ## Resources | Method and path | Minimum role | Purpose | | -------------------------------------------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | `GET /doctor` | viewer | Run control-plane dependency diagnostics; optional `cloud`, `serverless`, and `aws` booleans add read-only provider checks. | | `GET /whoami` | viewer | Return the authenticated principal, role, and tenant without exposing credential material. | | `GET /integrations` | viewer | Return versioned provider/runtime contracts, registered capabilities, and honest qualification evidence. | | `POST /deployments/apply` | operator | Queue existing-target convergence; requires `Idempotency-Key`. | | `POST /deployments` | operator | Atomically create desired cloud deployment and queue convergence; requires `Idempotency-Key`. | | `GET /deployments` | viewer | List tenant deployments. | | `GET /deployments/{name}` | viewer | Inspect deployment, targets, replicas, revisions, immutable model artifacts, active durable operation, and persisted request statistics. | | `GET /deployments/{name}/events` | viewer | List durable deployment events. | | `POST /deployments/{name}/benchmarks` | operator | Run and persist AIPerf evidence for `active`, `candidate`, or an explicit revision. | | `GET /deployments/{name}/benchmarks` | viewer | List persisted benchmark history and reproduction metadata. | | `POST /deployments/{name}/passports` | operator | Assemble, sign, verify, and persist a revision's canonical Inference Passport. | | `GET /deployments/{name}/passports` | viewer | List signed release evidence and verification state. | | `GET /deployments/{name}/revisions` | viewer | List immutable revision history. | | `POST /deployments/{name}/rollouts` | operator | Create an immutable candidate revision. | | `POST /deployments/{name}/rollouts/{revision}/provision` | operator | Queue candidate capacity provisioning. | | `POST /deployments/{name}/rollouts/guard/evaluate` | operator | Persist a deterministic Release Guard evaluation. | | `GET /deployments/{name}/release-guard/policy` | viewer | Read the persisted Release Guard policy. | | `PUT /deployments/{name}/release-guard/policy` | operator | Replace the deterministic guard thresholds. | | `POST /deployments/{name}/rollouts/{revision}/promote` | operator | Promote an accepted ready candidate. | | `POST /deployments/{name}/rollouts/{revision}/reject` | operator | Reject a candidate with a persisted reason. | | `POST /deployments/{name}/rollback` | operator | Queue rollback to an immutable revision. | | `GET /deployments/{name}/scaling-decisions` | viewer | List deterministic scaling evaluations and their persisted signals. | | `PUT /deployments/{name}/route` | operator | Change the persisted routing strategy. | | `DELETE /deployments/{name}` | admin | Withdraw routing and queue verified provider cleanup; requires `Idempotency-Key`. | | `GET /operations/{id}` | viewer | Inspect durable progress and result. | | `GET /operations/{id}/events` | viewer | List ordered durable operation progress events. | | `POST /operations/{id}/cancel` | operator | Request cooperative cancellation. | | `GET /targets` | viewer | List registered tenant targets. | | `POST /targets` | operator | Register an existing HTTP(S) inference target. | | `GET /orphans` | viewer | List unowned provisioned resources. | | `GET /audit-events` | admin | List up to 500 events; `before` accepts RFC3339. | | `PUT /tenant/quota` | admin | Set deployment, replica, and distributed per-minute request limits; zero blocks that resource. | | `POST /tenants` | bootstrap admin | Create a tenant. | | `POST /principals` | admin | Create a credential; secret is returned once. | | `POST /principals/{id}/rotate` | admin | Replace a credential immediately. | | `DELETE /principals/{id}` | admin | Revoke a credential immediately. | | `GET /secrets` | admin with `manage_secrets` | List resolver metadata; values are never resolved into the response. | | `POST /secrets` | admin with `manage_secrets` | Create a reference-only secret object. | | `DELETE /secrets/{id}` | admin with `manage_secrets` | Delete a tenant-scoped secret reference. | | `GET /deployments/{name}/external-policy` | viewer | Inspect the persisted fallback policy and reserved hard budgets. | | `PUT /deployments/{name}/external-policy` | operator/admin with `manage_external` | Replace an explicit external policy; enablement requires privacy acknowledgement and positive hard limits. | Existing-target apply request: ```json theme={"theme":{"light":"github-light-default","dark":"vesper"}} { "name": "qwen-prod", "model": "Qwen/Qwen3-8B", "targets": ["gpu-a", "gpu-b"], "routing_strategy": "round-robin" } ``` An accepted mutation returns `202`, an operation object, and a `Location` header. Repeating the same tenant, operation kind, and idempotency key returns the original operation. Diagnostics execute inside the control-plane process. The public CLI receives only check status, messages, and remediation; it never receives or opens the PostgreSQL URL or provider credentials. Non-success responses use one stable envelope: ```json theme={"theme":{"light":"github-light-default","dark":"vesper"}} { "error": { "code": "candidate_not_ready", "category": "conflict", "message": "selected revision has no healthy ready endpoint", "retryable": false, "remediation": "Inspect current status and active durable operations before retrying with the same idempotency key." } } ``` Categories are `authentication`, `authorization`, `validation`, `not_found`, `conflict`, `rate_limit`, `dependency`, `internal`, or `request`. The mapping is deterministic from the HTTP status and error code. A retryable mutation must retain its original idempotency key. The interactive API explorer targets the local server declared in the specification. Use it only against an InferCrane control plane you operate, and never paste production credentials into a shared browser session. # DeploymentSpec Source: https://infercrane.mintlify.app/deployment-spec Declaratively define model identity, runtime, provider, compute, scaling, and routing. # DeploymentSpec New files declare the stable v1 file contract: ```yaml theme={"theme":{"light":"github-light-default","dark":"vesper"}} apiVersion: infercrane.dev/v1 kind: Deployment ``` Pre-v1 files without the header are interpreted as v1. Unknown versions, kinds, and fields fail closed. See [Upgrade and compatibility](/upgrade) for the change policy. The primary path uses defaults: ```console theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane deploy Qwen/Qwen3-8B ``` The YAML form groups model, runtime, compute, provider, resources, scaling, and routing concerns. Mutable model revisions such as `main` are resolved and persisted as immutable Hugging Face commits before provisioning. ```yaml theme={"theme":{"light":"github-light-default","dark":"vesper"}} name: qwen-prod model: id: Qwen/Qwen3-8B revision: main runtime: engine: vllm version: 0.10.2 args: - --enable-prefix-caching compute: mode: elastic provider: cloud: runpod # adapter: skypilot # optional exact profile selection region: EU-RO-1 resources: gpu: L40S scaling: min_replicas: 1 max_replicas: 4 routing: strategy: round-robin ``` SGLang uses a built-in immutable workload profile. Custom OCI images declare the full contract in `runtime.workload`; see [Custom OCI workloads](/features/custom-oci). Mutable image tags and underspecified probes are rejected before provisioning. `compute.mode` defaults to `elastic`; elastic replica bounds default to `1..1`. Serverless requires `min_replicas: 0` and defaults `max_replicas` to one when omitted. Revisions are immutable; changing a field creates a candidate. `provider.adapter` persists the exact implementation when more than one profile can serve a cloud/runtime pair; it is optional for an unambiguous default. Current executable elastic defaults include configured AWS EC2 and GCP Compute, while other provider-product profiles remain registered but deferred until their exact combination is qualified. AWS and GCP require an explicit `provider.region`. Cost is omitted unless a trustworthy provider measurement exists. # Development and testing Source: https://infercrane.mintlify.app/development Fast local feedback, provider contracts, Docker qualification, and paid acceptance boundaries. # Development and testing InferCrane separates product correctness from provider availability. Most changes must be proven without credentials, GPUs, or network access. Real infrastructure is reserved for provider qualification of a frozen release candidate. ## Fast loop ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} make dev-check ``` This runs repository verification and the provider lifecycle contracts. It is the default command while editing and writes full logs under `.infercrane/dev-check/RUN_ID/` while keeping terminal output compact. Passport signing is opt-in in development. Generate a permission-restricted key and inject only its file path into the control-plane process: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane passport keygen export INFERCRANE_PASSPORT_SIGNING_KEY_FILE="$HOME/.config/infercrane/passport-signing-key" ``` ## Full local qualification ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} make dev-check-full ``` The full command creates an isolated Docker Compose project on an available host port and runs: * race-enabled repository and provider-contract tests; * generated OpenAPI drift, Python/TypeScript SDK, GitHub Action, and real Terraform protocol tests; * the containerized test suite with temporary PostgreSQL; * buffered, streaming, tool-call, and structured-output gateway checks; * worker-loss and control-plane restart recovery; * production Compose configuration validation; and * Mintlify build, links, and accessibility checks. The project and volumes are removed on success, failure, interruption, and termination. Each run uses a filesystem lock so two local qualification stacks cannot silently interfere. Full automation qualification requires Terraform 1.15.8 on `PATH` or at `.infercrane/tools/terraform`. It exercises the actual Plugin Protocol against a hermetic control API; it never provisions cloud resources. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} make test-automation # generated clients, packages, action, provider schema make test-automation-full # also real Terraform CRUD/import/interruption acceptance ``` ## Provider contract Every elastic provider adapter must prove deterministic identity, replay-safe ensure/adoption, observation, and idempotent deletion. Every serverless adapter must additionally prove native zero-worker configuration and adoption after a lost create response. These tests run through the adapter's public boundary, not private helper functions: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} make test-provider-contracts ``` Passing the local contract registers an implementation; it does not advertise production support. A provider becomes qualified only after its API canary and complete real-infrastructure lifecycle evidence are recorded for the exact release commit. ## Paid qualification Paid commands require `--approve-paid-resources` and acquire one repository-wide paid-run lock. They refuse concurrent execution, persist the owning PID and run ID, capture sanitized provider inventory on failure, and clean only resources owned by that acceptance run. Use the smallest applicable stage. Do not repeat elastic qualification to debug a serverless template: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} ./scripts/release-acceptance.sh preflight ./scripts/release-acceptance.sh elastic --approve-paid-resources ./scripts/release-acceptance.sh serverless --approve-paid-resources ./scripts/release-acceptance.sh cleanup ``` See [release acceptance](/release-acceptance) for the frozen-RC gates. Provider fakes establish control-plane correctness; they never substitute for final cloud evidence. ## Automated release proof The release orchestrator runs the complete local package gates and emits a machine-readable manifest: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} make qualify-local # .infercrane/qualification/COMMIT/qualification.json ``` For a clean frozen commit, `make qualify-rc` adds independently resumable elastic qualification, serverless qualification, elastic faults, and serverless faults. A passed stage is reused only for the same clean commit. Each provider stage has its own acceptance run ID, cleanup, report, and zero-inventory proof, so a later failure does not repeat earlier paid work. # Frequently asked questions Source: https://infercrane.mintlify.app/faq Product scope, compatibility, data handling, serverless, sessions, and pricing answers. # FAQ ## Does InferCrane support any model, engine, or cloud? No. The current registry contains vLLM, SGLang, and immutable custom OCI profiles across specific RunPod, AWS EC2 BYOC, GCP Compute BYOC, and namespaced Kubernetes modes. `infercrane integrations` reports the exact qualification state; real-GPU evidence remains deferred until real-infrastructure qualification. Every exact provider/runtime/mode combination needs independent evidence. ## Do I need Kubernetes? No. The primary path does not require Kubernetes. A namespace-scoped Kubernetes adapter is available for teams that already operate a cluster; InferCrane does not install a distribution or custom operator. ## Does Release Guard use an LLM? No. It applies a persisted deterministic policy to measured evidence. ## Does serverless mean InferCrane schedules GPUs? No. The registered serverless provider owns worker allocation and scale-to-zero; InferCrane owns logical lifecycle and evidence. RunPod Serverless is the first and currently only registered native Serverless backend. ## Is InferCrane coupled to RunPod or vLLM? No at the lifecycle boundary. Providers, runtimes, serverless status, artifacts, and benchmark tools are external adapters composed around durable InferCrane state machines. `infercrane integrations` shows the current exact combinations and separates simulated, local, deferred and real evidence. ## Are prompts or outputs stored? Not by default. Telemetry and benchmark history contain measurements and operational metadata. ## Does InferCrane preserve agent or inference sessions? Context Passport preserves bounded logical session identity and a preferred-backend hint. Reliability always overrides affinity: when a worker disappears, the stale hint is removed and the next request falls back to an ordinary healthy route. InferCrane does not store conversation bodies by default and does not claim durable KV state or transparent request migration unless the selected backend declares and qualifies that capability. ## Is provider pricing estimated? Only trustworthy observed cost metadata is shown. InferCrane does not fabricate prices. # Admission and async inference Source: https://infercrane.mintlify.app/features/admission-async Bound overload before it reaches GPUs and run reconnectable inference jobs with encrypted persistence. # Admission and async inference InferCrane applies endpoint admission before an inference request reaches a runtime. Policies are loaded from PostgreSQL into an in-memory snapshot, so the request path never waits on a database. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane admission set coder-production \ --max-concurrency 32 \ --max-queue 64 \ --queue-timeout-ms 5000 \ --max-request-bytes 16777216 \ --max-output-tokens 8192 \ --priorities normal,high \ --retry-budget 1 ``` The policy bounds concurrency, queue depth, queue wait, encoded request size, requested output tokens and accepted priority classes. Rejections use OpenAI-compatible errors and happen before upstream transmission. Tenant request/token limits and external-capacity budgets remain separate hard controls. ## Retry semantics Retries are intentionally narrow. InferCrane retries only buffered requests to InferCrane-managed capacity, up to the persisted endpoint budget, for connection failures and HTTP `502`, `503` or `504`. It never automatically retries streaming requests or paid external fallback. Attempts retain one request ID and expose `X-InferCrane-Attempt` to the runtime. ## Durable async requests Create a protocol-native request file: ```json request.json theme={"theme":{"light":"github-light-default","dark":"vesper"}} { "model": "coder-production", "messages": [{ "role": "user", "content": "Summarize this document." }] } ``` Submit it and close the terminal safely: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane async submit coder-production \ --file request.json \ --protocol chat \ --idempotency-key document-42 ``` The command returns a job ID immediately. Resume, poll or cancel from any configured client: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane async get JOB_ID infercrane async get JOB_ID --output json infercrane async cancel JOB_ID ``` Async execution is one bounded inference request, not a workflow engine. Claims use PostgreSQL leases and fencing tokens. Another worker adopts an expired lease; a stale worker cannot commit the result. Deadlines, three execution attempts and encrypted-result retention are bounded. ## Content and keys Async mode is disabled until the control plane receives an encryption key of at least 32 bytes: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} export INFERCRANE_ASYNC_ENCRYPTION_KEY='replace-with-secret-manager-injected-key-material' ``` The API requires `store_encrypted_content: true`. Payloads and results use AES-256-GCM with the tenant and job identity as associated data. Plaintext is never written to PostgreSQL. Losing or rotating a key without retaining the previous key makes existing results unreadable; production key rotation therefore requires an operator-managed overlap procedure. ## Signed completion webhook ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane async submit coder-production \ --file request.json \ --idempotency-key document-42 \ --webhook https://jobs.example.com/infercrane \ --webhook-secret-reference WEBHOOK_SECRET_REFERENCE_ID ``` Webhooks are HTTPS-only and signed with `InferCrane-Timestamp` and `InferCrane-Signature: v1=`. Delivery has at most three attempts. The outbound transport rejects redirects and private, loopback, link-local and multicast addresses after DNS resolution. Completion webhooks contain the inference result. Configure them only when the destination is authorized to receive that content. ## Current limits * Queue order is priority then creation time; it is not a general scheduler. * Results are limited to 32 MiB. * Async streaming is not exposed; use synchronous streaming when incremental tokens matter. * Cross-key decryption and automatic key re-encryption are not currently implemented. # Artifact cache and prewarming Source: https://infercrane.mintlify.app/features/artifact-cache Record provider-neutral cache observations and durable prefetch intent without claiming an unverified cache hit. # Treat model locality as evidence Large model artifacts often dominate readiness time. InferCrane records cache state through a neutral contract while each provider adapter retains its native mechanism: a volume or provider cache, an AWS volume or snapshot, a Kubernetes volume or node cache, or another qualified implementation. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane artifact inspect ARTIFACT_ID ``` The result separates observations from requested work and shows whether an observation is still fresh. ## Request prefetch ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane artifact prefetch ARTIFACT_ID \ --provider aws \ --region eu-central-1 \ --location cache://production-models \ --idempotency-key release-42-prefetch ``` This persists durable intent. When an adapter for the named provider is configured, InferCrane ensures that intent with a stable idempotency key and checkpoints the provider operation identity. If a provider response is lost, a retry may repeat the API call with the same key and adopt the same logical operation; it must not create a second cache resource. If no adapter is configured, the response says `execution: not_configured` instead of implying that warming began. Submission is **not** proof that the artifact is present. The adapter must publish a fresh observation before a planner can rely on locality. ## Record an adapter observation ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane artifact observe ARTIFACT_ID \ --provider aws \ --region eu-central-1 \ --location cache://production-models \ --state present \ --source aws-ebs-adapter \ --ttl 10m ``` Valid states are `present`, `prefetching`, `missing`, and `unknown`. Expiry prevents stale provider state from becoming a permanent planning assumption. Cache population remains adapter-specific and requires qualification on the selected infrastructure. `requested` or `running` describes work, while only a fresh `present` observation describes locality. ## Why prefetch is not a universal download command Providers expose different ownership boundaries. For example, RunPod Serverless configures one [cached model on an endpoint](https://docs.runpod.io/serverless/endpoints/model-caching), while an EC2 or Kubernetes deployment commonly obtains locality from a persistent volume, snapshot, node cache, or image strategy owned by that workload. Those are not interchangeable APIs. InferCrane therefore does not download model weights through a custom protocol and does not mark a prefetch request as a cache hit. An adapter may consume the durable intent using its native mechanism, but it must publish a bounded fresh observation before planning or placement can rely on locality. Until then, `infercrane plan` reports artifact cache and startup time as `unknown` and `unavailable`. # Autoscaling Source: https://infercrane.mintlify.app/features/autoscaling Scale replicas with bounded decisions, durable evidence, and generation-safe drain. # Autoscaling Elastic deployments use bounded queue-aware scaling between explicit minimum and maximum replicas. Persisted vLLM running/waiting signals, consecutive-interval thresholds, and cooldowns produce an auditable scaling decision. Scale-up creates durable replica intents. Scale-down withdraws the worker from the matching router generation, drains it, and then terminates it. `infercrane explain scaling DEPLOYMENT` returns the latest action, old/new capacity, reason, signal snapshot, and timestamp. If evidence is insufficient or cooldown prevents a change, the persisted no-op decision explains why. Serverless deployments delegate zero-to-N worker scheduling to the registered provider-native backend and retain one logical endpoint. InferCrane does not implement a GPU serverless scheduler. RunPod supplies the first registered native Serverless implementation. # Reproducible benchmarking Source: https://infercrane.mintlify.app/features/benchmarking Run AIPerf workloads and persist exact model, runtime, hardware, and workload evidence. # Reproducible benchmarking InferCrane delegates load generation and measurement to [AIPerf](https://github.com/ai-dynamo/aiperf). It does not contain a second load generator. ```console theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane benchmark qwen-prod --requests 1000 --concurrency 32 ``` The CLI submits the benchmark through the authenticated control-plane API. The control plane resolves the active immutable revision, runs AIPerf against the logical InferCrane endpoint, and persists the result. A fixed dataset seed defaults to `17` and can be changed with `--random-seed`. Release Guard validation can benchmark an isolated candidate explicitly: ```console theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane benchmark qwen-prod --revision active --requests 100 --concurrency 4 --random-seed 17 infercrane benchmark qwen-prod --revision candidate --requests 100 --concurrency 4 --random-seed 17 ``` The candidate command selects one healthy ready replica deterministically and runs AIPerf directly from the control plane using its server-side worker credential. It never exposes that credential to the CLI. This is explicit synthetic validation, not shadow traffic: InferCrane does not copy any user request or conversation content. It creates additional inference work and may incur provider cost. Active and candidate results are eligible for Release Guard comparison only when AIPerf tool version and workload parameters match exactly. Each result records the immutable ModelArtifact, runtime and configuration, revision, provider, region, GPU type and grounded GPU count, compute mode, workload parameters, TTFT, TPOT, request latency, throughput, errors, timestamp, and exact reproduction command. The persisted command uses a portable local export prefix rather than the deleted temporary execution directory, and replaces the credential with its environment-variable reference. Goodput and GPU telemetry remain explicit `null` values, while cost metadata contains `available: false` and a reason when AIPerf or the provider did not measure them; none are fabricated. InferCrane asks AIPerf for the `records` export level. This contains per-request measurements but not the raw request/response export, so prompt and generated content are not persisted. Results remain in the InferCrane PostgreSQL database and are never uploaded by default. The control-plane image pins its AIPerf version. For a standalone control plane, install AIPerf with `pipx install aiperf`; `infercrane doctor` verifies that the configured executable is available. # Cold-start intelligence Source: https://infercrane.mintlify.app/features/cold-starts Measure exposed cold-start boundaries without inventing provider-hidden timing. # Cold-start intelligence InferCrane classifies a RunPod Serverless request as cold only when a fresh provider `/health` observation proves that the endpoint had zero idle and zero running workers immediately before the request arrived. A nonzero observation classifies the request as warm. Missing or stale evidence leaves the request unclassified. The background observation uses RunPod's control endpoint and does not send inference traffic, so it does not create or retain a warm worker. Once zero-worker evidence classifies a request, that evidence is invalidated immediately; it cannot label later requests unless RunPod is observed at zero again. Persisted request evidence includes: * cold, warm, or unclassified state; * provider workers observed at arrival; * the provider observation timestamp; * end-to-end request latency; * time to first response byte/token for streaming and non-streaming requests; * deployment, revision, provider, runtime, compute mode, and operation dimensions. The JSON explanation always includes `available_boundaries` and `unavailable_boundaries`. `time_to_ready_p50_ms` and `time_to_ready_p95_ms` are explicit `null` values until a provider exposes a trustworthy readiness boundary. The same rule applies to statistically insufficient TTFT percentiles; absence is never presented as zero. Prompts and generated output are not stored by default. Inspect the deterministic aggregate: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane explain cold-start qwen-prod infercrane explain cold-start qwen-prod --output json ``` The output includes classified request counts, cold and warm TTFT p50, and p95 only after at least 20 samples in the corresponding class. This threshold avoids presenting a tail percentile from a statistically meaningless handful of requests. RunPod does not expose trustworthy per-request boundaries for capacity allocation, container startup, artifact download, model load, runtime initialization, readiness, time-to-ready, or the true model first-token timestamp through the OpenAI-compatible vLLM request. InferCrane measures gateway time to first response byte and labels it accordingly. It reports the machine-readable bottleneck code `provider_capacity_or_worker_initialization` and does not fabricate a more detailed waterfall. When a provider later exposes grounded boundaries, they can be added without changing the meaning of existing evidence. # Context Passport and Burst Guard Source: https://infercrane.mintlify.app/features/context-passport-burst Durable logical session identity, delegated request survival, and budget-bounded overflow. # Context Passport and Burst Guard Context Passport persists bounded logical inference-session identity and best-effort affinity hints: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane session create coder-production --ttl 1h ``` Send the returned ID as `X-InferCrane-Context-Passport`. The in-memory route snapshot prefers the hinted binding or target only while it remains eligible; otherwise ordinary healthy routing wins and the response reports `X-InferCrane-Affinity: fallback`. Context Passport does not store conversation bodies and does not guarantee durable KV state. Logical identity survives a worker; engine cache survival does not unless a separately qualified backend provides it. ## Request survival Request survival is a delegated capability contract. A runtime/backend may claim support only with a named mechanism and local or real qualification evidence. Plain vLLM does not gain request migration from InferCrane; unsupported and unknown states fail closed. InferCrane never implements distributed KV or token migration. ## Burst Guard Burst Guard combines fresh queue evidence, sustained breach/recovery intervals, qualified external health, and a hard incremental hourly cost ceiling: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane burst coder-production \ --queue-depth 8 --breaches 3 \ --external-healthy \ --incremental-cost-microusd-hour 4000000 \ --max-incremental-cost-microusd-hour 5000000 ``` It requires the existing governed external fallback policy, including privacy acknowledgement and its hard request/cost budget. Stale signals, unavailable capacity, or cost above policy produce a fail-closed decision. The evaluator persists evidence; route mutation remains owned by the existing policy controller. # Custom OCI workloads Source: https://infercrane.mintlify.app/features/custom-oci Bring an immutable OpenAI-compatible inference image through the portable runtime contract. # Custom OCI workloads InferCrane can launch a user-supplied inference image without becoming an image builder or container engine. The deployment revision records the exact image digest, argv and observable lifecycle contract before a provider mutation is submitted. ```yaml theme={"theme":{"light":"github-light-default","dark":"vesper"}} name: custom-prod model: id: Qwen/Qwen3-8B runtime: engine: custom-oci workload: image: registry.example/acme/runtime@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef command: ["/opt/acme/serve", "--model", "${MODEL}", "--port", "${PORT}"] protocol: openai port: 8000 readiness_path: /health models_path: /v1/models metrics_path: /metrics cancellation: http-disconnect drain: connection shutdown_grace_seconds: 30 compute: mode: elastic provider: cloud: aws region: eu-central-1 resources: gpu: L40S scaling: min_replicas: 1 max_replicas: 1 routing: strategy: round-robin ``` The command is argv, not a shell program. `${MODEL}`, `${MODEL_REVISION}`, `${PORT}`, and the exact `${WORKER_API_KEY}` argument placeholder are replaced without losing argument boundaries. The workload receives the worker credential as `INFERCRANE_WORKER_API_KEY`; the value is not persisted in revision or provider metadata. InferCrane resolves `model.id` through the Hugging Face `ModelArtifact` adapter before launch; a custom image does not imply arbitrary artifact protocols. ## Runtime contract The image must be pinned by `@sha256`. The supported protocol and probe paths are deliberately narrow: OpenAI-compatible HTTP, `/health`, `/v1/models`, and `/metrics`. Client disconnect must cancel upstream HTTP work, and InferCrane withdraws the router generation and drains active connections before provider deletion. Custom OCI is currently simulated-qualified on the AWS EC2 elastic path, whose user-data bootstrap launches the immutable image directly. Real GPU evidence is deferred to consolidated qualification. RunPod/SkyPilot images require an additional SSH bootstrap contract and are not claimed compatible. Serverless, arbitrary probe scripts, mutable tags, image builds and autoscaling signals for custom runtimes are rejected rather than silently assumed. Inspect the executable support boundary with: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane integrations infercrane integrations --output json ``` # Operations console Source: https://infercrane.mintlify.app/features/dashboard Use InferCrane's authenticated browser console without putting provider credentials or PostgreSQL in the frontend. The InferCrane console is a separate web application over the same authenticated control API used by the CLI, SDKs, Terraform provider, and terminal workspace. It is not a second backend and never reads PostgreSQL or provider credentials directly. The hosted console is currently deny-by-default private preview. The initial public product is CLI- and API-first. Local self-hosted use does not require an InferCrane Cloud or Clerk account. ## What the console covers * fleet attention, stable endpoints, and concrete workloads; * durable operations with reconnectable timelines and cooperative cancellation; * Request Inspector and deterministic Doctor findings; * endpoint monitoring for request rate, errors, fallback, TTFT, queueing, latency, and reported token throughput; * Release Guard, benchmark, replay, revision, and replica evidence where available; * lifecycle overlays, signed alert policies, sourced FinOps reports, and signed output-quality evidence; * provider/runtime capability inventory and secret references; * scoped API-key lifecycle and private-preview team access. Missing or forbidden evidence remains explicit. A failed optional panel does not make a deployment look healthy, and an unavailable measurement is never rendered as zero. The monitoring page queries only the authenticated control API. PostgreSQL request evidence and lifecycle events form the initial local evidence store; OpenTelemetry GenAI semantics define the portable names and dimensions. Runtime-internal and GPU metrics remain unavailable until a qualified runtime or provider adapter reports them. ## Local self-hosted console From an `infercrane-web` checkout, configure the local adapter: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} export INFERCRANE_CONSOLE_AUTH_MODE=local export INFERCRANE_CONSOLE_ORIGIN=http://127.0.0.1:3200 export INFERCRANE_CONTROL_API_URL=http://127.0.0.1:18000 export INFERCRANE_LOCAL_SESSION_SECRET="$(openssl rand -base64 48)" npm install npm run dev:console ``` Open `http://127.0.0.1:3200` and exchange an existing InferCrane API credential. The BFF validates the credential with the control plane and seals it into an eight-hour, encrypted, HttpOnly, SameSite=Strict session. Browser JavaScript does not receive the raw token after exchange. Use a unique session secret and HTTPS in production. Do not place the bootstrap credential in a shared browser session; create a scoped service account instead. ## Hosted private preview Hosted mode uses Clerk for sign-in, sessions, and organization selection. Clerk authentication alone does not grant access. The Go control plane independently requires a mapped InferCrane user, organization membership, role/scopes, and active `web_console_access` entitlement. Default access is denied. Configure the Go verifier with the Clerk instance's HTTPS issuer and public JWT verification key: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} export INFERCRANE_HOSTED_AUTH_ISSUER="https://YOUR-CLERK-DOMAIN" export INFERCRANE_HOSTED_AUTH_AUDIENCE="infercrane-control-api" export INFERCRANE_HOSTED_AUTH_JWT_KEY_FILE="/run/secrets/clerk-jwt-public.pem" export INFERCRANE_HOSTED_AUTH_AUTHORIZED_PARTIES="https://app.infercrane.ai" ``` The private-preview Clerk instance must disable public sign-up and restrict organization creation. Those identity-provider controls improve the sign-in UX; the InferCrane entitlement remains the authoritative access boundary. Every protected page and server action resolves a server-side session. Every control API request then repeats authentication, authorization, and tenant ownership checks. Organization IDs supplied only by browser input never establish authority. ## Durable work Closing the browser does not cancel deployment work. Reopen the console or resume from any terminal: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane operation watch OPERATION_ID ``` Cancellation is cooperative. Provider cleanup may continue after cancellation is requested or the browser closes. ## Terminal equivalent For headless, low-bandwidth, or incident use, the terminal surfaces remain first-class: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane inbox infercrane ui infercrane status DEPLOYMENT --output json infercrane events DEPLOYMENT --output json infercrane explain DEPLOYMENT --output json infercrane inspect DEPLOYMENT --output json ``` The public Dashboard link intentionally leads to a Coming Soon page until hosted access is ready for general users. # Stable endpoints and serving plans Source: https://infercrane.mintlify.app/features/endpoints Keep application model names stable while changing concrete inference implementations. # Stable endpoints and serving plans An endpoint is the model name an application sends to InferCrane. It is deliberately separate from a deployment, provider, and runtime: ```text theme={"theme":{"light":"github-light-default","dark":"vesper"}} application model="coder-production" ↓ endpoint ↓ active serving plan ↓ backend binding ↓ concrete deployment or imported target ``` This lets an operator stage a different serving implementation without changing application code. Existing v1 deployment aliases are migrated automatically to a `production` environment, a logical model, a lifecycle-managed binding, and a one-binding active plan of the same name. ## Create an endpoint ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane logical-model create coder \ --description "Stable coding model" infercrane endpoint create coder-production \ --model coder \ --environment production infercrane endpoint bind coder-production \ --name primary \ --deployment qwen-prod \ --ownership lifecycle-managed infercrane endpoint plan coder-production \ --policy manual \ --bindings primary ``` The first plan becomes active. Later plans are staged as candidates and receive no application traffic until promoted: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane endpoint plan coder-production \ --policy primary-fallback \ --bindings candidate,primary infercrane endpoint inspect coder-production infercrane endpoint guard coder-production --evaluate infercrane endpoint promote coder-production PLAN_ID ``` Plan creation returns `route_refresh: converged` when the in-memory route was published before the response. `pending` means durable state is committed and ordinary reconciliation will publish it. ## Routing policies | Policy | Behavior | | ------------------ | -------------------------------------------------------------------------------------------------- | | `manual` | Exactly one selected binding. | | `primary-fallback` | First available binding in declared priority order. InferCrane does not replay an accepted stream. | | `weighted` | Deterministic bounded weighted selection among currently available bindings. | Serving plans are immutable and SHA-256 identified. Promotion changes only future route acquisitions. A buffered or streaming request remains pinned to the route generation it acquired until the request finishes. Promotion fails closed unless the latest persisted endpoint Release Guard evaluation is `PASS` for the current active/candidate pair. `REJECT` and `INCONCLUSIVE` can be inspected but cannot be promoted. Candidate traffic is never duplicated silently; Release Guard evaluates trustworthy telemetry from the primary deployment-backed binding and reports insufficient evidence as `INCONCLUSIVE`. It does not reuse those primary metrics for a weighted or otherwise unmeasured routing topology. An append-only managed fallback is eligible only when it preserves the active routing prefix and has immutable consent plus hard-budget policy; the persisted evaluation records that topology classification explicitly. ## Ownership boundaries Bindings record `observe-only`, `traffic-managed`, or `lifecycle-managed` ownership. InferCrane supports fully compiled lifecycle-managed deployment bindings. Incremental import/adopt workflows and customer-managed external bindings; creating a record does not imply that InferCrane owns an external workload's lifecycle. The inference hot path reads an immutable in-memory endpoint snapshot. It never queries PostgreSQL. Request telemetry records the logical model, environment, endpoint, serving plan, binding, deployment, revision, replica where known, provider, and runtime without storing prompt or output content by default. ## Add an authenticated managed API An OpenRouter or generic OpenAI-compatible API can be staged behind the same endpoint. Provider credentials remain reference-only, external data transmission requires explicit consent, and hard request/cost reservations fail closed before any bytes are sent: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} export MANAGED_MODEL_API_KEY='...' infercrane secret create managed-model-api \ --from-env MANAGED_MODEL_API_KEY \ --output json infercrane target add managed-coder \ --provider openai-compatible-external \ --runtime openai-compatible \ --url https://models.example.com/v1 \ --upstream-model provider/coder-model infercrane endpoint bind coder-production \ --name managed-fallback \ --target managed-coder \ --ownership traffic-managed \ --external-adapter openai-compatible-external \ --secret-reference SECRET_REFERENCE_ID \ --request-limit 1000 \ --cost-limit-usd 25.00 \ --max-request-cost-usd 0.10 \ --acknowledge-external-data \ --enable-external infercrane endpoint plan coder-production \ --policy primary-fallback \ --bindings primary,managed-fallback ``` The new plan is a candidate. It receives no application traffic until Release Guard passes and an operator explicitly promotes it. Adding a fallback never changes the application request: ```python theme={"theme":{"light":"github-light-default","dark":"vesper"}} client.responses.create(model="coder-production", input="Explain this incident.") ``` The web console exposes the same staging workflow on the endpoint page. It never receives the provider credential; it sends only the selected secret-reference ID to the control API. # Environment promotion Source: https://infercrane.mintlify.app/features/environment-promotion Stage an immutable serving plan from development or staging into a destination endpoint without changing production traffic. # Promote evidence, not mutable configuration Development, staging, and production endpoints can share one logical model while retaining separate policies, budgets, networking, and active serving plans. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane environment promote coder-staging \ --to coder-production ``` The default command prints a semantic plan and makes no changes. It verifies that both endpoints belong to the same logical model and that the source has an active immutable plan. ```text theme={"theme":{"light":"github-light-default","dark":"vesper"}} + clone source bindings into destination + stage immutable destination candidate = keep destination active plan serving = require destination Release Guard PASS before activation ``` Apply the staging transaction explicitly: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane environment promote coder-staging \ --to coder-production \ --yes \ --idempotency-key release-2026-08-14 ``` InferCrane clones the source bindings into destination-scoped identities and stages an immutable candidate atomically. It never activates the destination plan as part of promotion staging. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane observe coder-production infercrane endpoint guard coder-production --evaluate infercrane endpoint promote coder-production PLAN_ID ``` The destination Release Guard remains the decision authority. A concurrent promotion, occupied candidate slot, different logical model, or missing source plan fails safely. # Deterministic explanations Source: https://infercrane.mintlify.app/features/explanations Explain degraded state, scaling, rollouts, and cold starts from persisted evidence. # Deterministic explanations InferCrane explanations are projections of persisted state, events, decisions, policies, and measurements. They do not call an LLM and do not infer facts that were not recorded. ```console theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane explain qwen-prod infercrane explain scaling qwen-prod infercrane explain rollout qwen-prod infercrane explain cold-start qwen-prod ``` The general explanation reports observed deployment state, unhealthy replica evidence, and the active durable operation that is blocking convergence, including its persisted kind, status, progress, message, and error code. Scaling explanations reproduce the latest persisted autoscaling action, reason, signal snapshot, and evaluation timestamp. Rollout explanations reproduce the Release Guard evaluation ID, active and candidate revisions, decision, reason codes, metric snapshot, policy snapshot, and timestamp. Cold-start explanations use the provider-worker observation and TTFT evidence described in [Cold-start intelligence](/features/cold-starts). Every form supports `--output json`. Repeating an explanation against unchanged persisted state produces the same explanation code and evidence. If no evaluation exists, InferCrane says so instead of inventing a cause. # Governed external capacity Source: https://infercrane.mintlify.app/features/external-capacity Explicit, budgeted health or queue overflow to an OpenAI-compatible external target. # Governed external capacity InferCrane can route to a registered external API when all primary targets are unhealthy or an explicit bounded queue policy is satisfied. This is emergency capacity, not a model marketplace: InferCrane does not resell access, select a model, or hide the external provider from the operator. External fallback can transmit prompts and generated output outside infrastructure you control and can create a separate provider charge. Enabling it requires an explicit privacy acknowledgement and hard request and cost-reservation limits. External capacity has two explicit scopes: * **Stable endpoint binding:** an authenticated external API participates in an immutable `manual`, `primary-fallback`, or `weighted` serving plan. This is the preferred one-endpoint composition. * **Deployment overflow:** emergency external capacity is selected when one concrete deployment's primary targets are unhealthy or its bounded queue policy is satisfied. Both scopes use reference-only credentials, consent, in-memory budget leases, and no request replay. They are configured separately so a deployment policy cannot silently change an endpoint plan. See [Stable endpoints](/features/endpoints#add-an-authenticated-managed-api) for first-class endpoint bindings. ## Configure OpenRouter fallback Inject the credential into the control-plane environment, then register only its reference: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} export OPENROUTER_API_KEY='...' infercrane secret create openrouter --from-env OPENROUTER_API_KEY --output json ``` Register the exact endpoint and model mapping. Replace `SECRET_REFERENCE_ID` with the returned ID: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane target add openrouter-qwen \ --provider openrouter \ --url https://openrouter.ai/api/v1 \ --upstream-model qwen/qwen3-8b infercrane external configure qwen-prod \ --target openrouter-qwen \ --adapter openrouter \ --secret-reference SECRET_REFERENCE_ID \ --request-limit 100 \ --cost-limit-usd 10.00 \ --max-request-cost-usd 0.10 \ --acknowledge-external-data \ --enable ``` The policy attaches the registered fallback target to `qwen-prod`; it is excluded from ordinary healthy-primary routing. Inspect the durable policy and reserved budget: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane external inspect qwen-prod infercrane external inspect qwen-prod --output json ``` For queue overflow, opt in to hysteresis and cooldown explicitly: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane external configure qwen-prod \ --target openrouter-qwen \ --adapter openrouter \ --secret-reference SECRET_REFERENCE_ID \ --mode health_and_queue \ --queue-threshold 4 \ --breach-intervals 3 \ --recovery-intervals 3 \ --cooldown-seconds 60 \ --signal-max-age-seconds 30 \ --request-limit 100 \ --cost-limit-usd 10.00 \ --max-request-cost-usd 0.10 \ --acknowledge-external-data \ --enable ``` Missing or stale queue metrics never imply an empty queue. Consecutive observations and cooldown prevent route oscillation. Every selection, recovery, denial, reason change, and hysteresis-counter transition is persisted with the exact policy and signal snapshot. Identical steady-state holds are coalesced rather than writing an unbounded row on every health interval. ## Selection and budget behavior The reconciler publishes one external route after every ordinary target is unhealthy or after the configured queue breach persists for the required intervals. Before each external transmission, the gateway atomically consumes a request reservation and the configured worst-case cost reservation. Exhaustion returns an error before sending bytes. Reservations are deliberately conservative. A request that reserves more than its eventual provider charge does not receive an automatic refund because InferCrane does not ingest an authoritative provider invoice. `cost_limit_usd` is therefore an authorization ceiling, not an estimated bill. InferCrane selects the provider before transmission. It never replays a request after a possible send, never duplicates streaming traffic, and does not silently shadow user requests. Selection, denial, budget counters, and health changes remain available through persisted events and request records. ## Disable fallback Re-run `external configure` without `--enable` using the same target, reference, acknowledgement, and limits. This replaces the policy with a disabled policy; it does not delete the target or secret reference. ## Current limits * Weighted, semantic, shadow, and request-duplicating external routing are not implemented. * Environment references are currently the only secret resolver. * Provider prices are not fetched or fabricated. * Real OpenRouter billing qualification is deferred to the consolidated manual release gate. # FinOps and advisory Autopilot Source: https://infercrane.mintlify.app/features/finops-autopilot Explain sourced inference cost and create human-approved serving recommendations. # FinOps and advisory Autopilot InferCrane treats cost as evidence, not a guess. A FinOps report accepts only cost metadata carrying a source and observation time. Missing cost remains unavailable, currencies are never silently converted, and avoidable spend remains unknown until utilization and a qualified alternative directly support it. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane finops coder-production --window 720h ``` The report persists its exact evidence, evaluation window, disclosure set, and canonical input digest. ## Advisory Autopilot Autopilot consumes the deterministic SLO recommendation already persisted for a deployment: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane recommend coder-production infercrane autopilot plan coder-production --objective minimize_cost infercrane autopilot approve PLAN_ID ``` `plan` creates an immutable evidence snapshot. `approve` records the authenticated human decision. Neither command changes a deployment, provisions capacity, or promotes a revision. The next production step is an ordinary explicit candidate rollout followed by Replay, benchmark, and Release Guard. Approval is not execution. InferCrane intentionally has no autonomous production mutation path. # Inference decisions Source: https://infercrane.mintlify.app/features/inference-decisions Deterministic SLO policies, evidence-based recommendations, and explicit unknowns. # Inference decisions InferCrane compares persisted, reproducible benchmark evidence against an explicit deployment SLO policy. It does not ask an LLM to choose infrastructure, mutate a deployment automatically, or invent missing price and capacity measurements. ## Define the acceptance envelope Set at least one threshold. Omitted metrics are unconstrained; configured metrics fail closed when the corresponding benchmark signal is missing. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane slo set qwen-prod \ --ttft-p95 250 \ --latency-p95 1200 \ --error-rate 0.01 \ --output-tokens-second 30 ``` Hourly cost is accepted only when benchmark cost metadata includes an authoritative source and observation timestamp. InferCrane does not convert unavailable pricing into zero. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane slo get qwen-prod --output json infercrane slo delete qwen-prod ``` ## Evaluate persisted evidence Collect comparable AIPerf measurements, then request a recommendation: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane benchmark qwen-prod infercrane recommend qwen-prod infercrane recommend qwen-prod --history --output json ``` Every evaluation persists its status, algorithm version, canonical input digest, immutable benchmark provenance, exact compatibility state, selected and rejected candidates, violated constraints, missing evidence, and current bounded capacity disclosure where available. Candidates must reference the active immutable model artifact and the same canonical benchmark workload as the newest observation. InferCrane will not rank unlike models, request shapes, or concurrency profiles as though they were interchangeable performance samples. A recommendation is advisory. It never provisions resources, changes the DeploymentSpec, or substitutes hardware. Apply a selected configuration explicitly after reviewing its evidence. ## Unknown is a useful answer InferCrane returns `unknown` when a configured metric, qualification record, or required cost signal is unavailable. Capacity is disclosed as available, constrained, unavailable, or unknown with an expiry. Stale evidence becomes unknown; it is never retained as live stock. The same policy and canonical evidence snapshot reproduce the same output. This supports audit and CI review without turning the recommendation into an opaque optimizer. # Inference Passports Source: https://infercrane.mintlify.app/features/inference-passports Canonical, signed, reproducible evidence for an immutable inference revision. # Inference Passports An Inference Passport answers four release questions with persisted evidence: what revision ran, which immutable artifacts and runtime configuration it used, how it was measured, and which policy decision allowed it to ship. It is an evidence envelope—not a compliance certificate. ## Configure signing Generate an Ed25519 key once on a trusted operator machine: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane passport keygen export INFERCRANE_PASSPORT_SIGNING_KEY_FILE="$HOME/.config/infercrane/passport-signing-key" ``` The command creates the private key with mode `0600` and refuses to overwrite an existing key. Mount the key into the control-plane process. InferCrane persists only the public key, key identity, signature, digest, and signed payload. Back up and rotate private keys using your normal secret management system. ## Issue and verify ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane passport issue qwen-prod --file qwen-prod.passport.json infercrane passport verify qwen-prod.passport.json infercrane passport list qwen-prod ``` Verification is offline and requires no control-plane credential or private key. It recomputes the SHA-256 digest, verifies the Ed25519 signature, and confirms the derived key ID. Any payload, signature, public-key, digest, or key-ID change fails closed. The signed v1 payload contains: * immutable revision ID and complete normalized `DeploymentSpec`; * resolved model repository, immutable revision, model identity, and known cache state; * runtime, runtime version, OCI workload identity, provider, region, GPU, and compute mode; * revision-scoped AIPerf result identities, workloads, reproduction commands, and sourced cost data; * available cold-start measurements and explicitly unavailable timing boundaries; and * the latest relevant Release Guard policy, metrics, reasons, decision, and evidence identity. Passports never contain provider credentials, API tokens, prompt bodies, or generated output. An unavailable measurement remains unavailable; issuing a passport does not turn simulated or missing qualification into real evidence. Issuance is allowed when evidence is incomplete so an operator can inspect the signed gap list. Such a passport remains cryptographically `verified` but reports `complete: false` and deterministic `missing_evidence` codes. GitHub release checks require both `verified` and `complete`; a signature alone is never treated as release qualification. PostgreSQL stores the canonical payload byte-for-byte rather than normalizing it as JSONB. This is required so offline verification remains stable after reads, backups, and restores. # Inference projects Source: https://infercrane.mintlify.app/features/inference-projects Scaffold, validate, build, and deploy one reproducible inference workload from its own directory. # One directory, one serving intent An inference project keeps the deployment specification beside the code and configuration that produce it. InferCrane discovers `infercrane.yaml` from the current directory or a parent, validates it locally, and uses the same file for planning and deployment. ```bash Start from a model theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane workload init ./fraud-explainer \ --model mistralai/Mistral-7B-Instruct-v0.3 \ --name fraud-explainer cd fraud-explainer infercrane workload validate infercrane workload plan infercrane workload deploy --wait ``` ```bash Start from a curated recipe theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane recipes curated mistral infercrane workload init ./fraud-explainer \ --recipe mistral-7b-instruct \ --name fraud-explainer ``` `workload init` writes a valid DeploymentSpec with a JSON Schema directive understood by YAML language servers in VS Code, JetBrains editors, and other schema-aware tools. Fields, enums, and unknown keys are checked while you type. A curated recipe also pins the model commit. Recipes are reviewed configuration starting points, not performance claims; use benchmark or replay evidence for serving decisions. ## Local validation before GPU allocation ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane workload validate infercrane workload plan ``` Validation catches schema, runtime, provider, and workload-contract problems without contacting a GPU provider. `plan` is also non-mutating. This keeps an invalid container command or unsupported runtime combination from becoming a paid provisioning attempt. The versioned schema is published from [`schemas/deployment-v1.schema.json`](https://github.com/infercrane/infercrane/blob/main/schemas/deployment-v1.schema.json). The Go loader remains authoritative; the schema improves editing and never weakens server-side validation. ## Build a custom OCI workload Custom OCI projects can build through Docker Buildx: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane workload build \ --tag ghcr.io/acme/fraud-explainer:v1 ``` A local build is useful for development, but it is deliberately **not** written into the production DeploymentSpec as deployable proof. Publish the image to record a registry-confirmed immutable digest: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane workload build \ --tag ghcr.io/acme/fraud-explainer:v1 \ --push ``` The Dockerfile must remain inside the project directory. InferCrane passes arguments directly to Docker rather than invoking a shell, and the resulting DeploymentSpec references the immutable registry digest. ## Run a custom workload locally ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane workload dev --port 8000 --detach ``` The development container binds only to `127.0.0.1`. The command is available for `custom-oci` projects; vLLM and SGLang model projects use their qualified runtime adapters. InferCrane owns the reproducible serving intent, not a new container build system. Docker/Buildx, your registry, vLLM, SGLang, and custom OCI runtimes retain their established responsibilities. # Deployment lifecycle Source: https://infercrane.mintlify.app/features/lifecycle How durable operations survive disconnects, retries, restarts, updates, and deletion. # Deployment lifecycle Create and apply requests are validated and persisted before external provisioning begins. A leased worker resumes incomplete steps after a control-plane restart. Each replica intent has one deterministic provider identity, so replay adopts the same resource rather than submitting another. Readiness requires the provisioned runtime to serve the expected model. Updates create immutable candidates, Release Guard records a deterministic decision, promotion switches routing generations atomically, and old capacity drains before termination. A bad candidate never replaces the active revision. Delete first withdraws desired routing, then drains and removes external resources. Restarting midway resumes cleanup. Completion requires provider absence, removed targets and replicas, and a deployment tombstone. Operators should still verify provider inventory after paid acceptance tests. # Model artifacts Source: https://infercrane.mintlify.app/features/model-artifacts Resolve mutable model references to immutable, evidence-bearing artifact identity. # Model artifacts InferCrane resolves a Hugging Face repository and requested revision through `huggingface_hub.HfApi.model_info`. The resulting commit SHA is attached once to the immutable deployment revision and passed to vLLM with `--revision`. Retries reuse the persisted artifact; they do not resolve a mutable branch again. Persisted evidence includes the repository, requested reference, immutable commit, canonical model identity, approximate Hub storage when returned, and grounded library/pipeline metadata. Cache state is `unknown` unless the execution backend can measure the worker cache. The control-plane host cache is never presented as worker cache evidence. The production image installs `huggingface_hub` and `hf_xet` in an isolated virtual environment so their dependency versions cannot alter SkyPilot's environment. Private or gated repositories use the standard Hugging Face token environment/configuration; InferCrane does not implement a model download protocol. # Observe operations Source: https://infercrane.mintlify.app/features/observe Read one useful snapshot of a deployment or stable endpoint, then reconnect when work takes longer than a terminal session. # Start with one command ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane observe coder-production ``` `observe` resolves either a stable endpoint or a deployment and presents the highest-value persisted evidence together. Endpoint output includes its logical model, environment, active/candidate serving plans, Release Guard, admission policy, and alerts. Deployment output includes desired and observed lifecycle, traffic, the active operation, Guard decision, and recent events. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane observe coder-production --output json infercrane observe qwen-prod --watch ``` The default command is read-only. `--watch` redraws only when state changes and can be closed safely; the control-plane operation continues. ## Reconnect to durable work ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane operation inspect OPERATION_ID infercrane operation watch OPERATION_ID infercrane events qwen-prod ``` Closing a laptop or losing a network connection stops the client watcher, not the deployment. The operation ID is the resume handle. Retrying a mutation with the original idempotency key is safe when the request result was uncertain. ## Ask for a deterministic diagnosis ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane observe coder-production --diagnose infercrane request inspect REQUEST_ID infercrane explain rollout qwen-prod ``` `--diagnose` is the one intentionally mutating form: it persists a fresh Doctor evaluation derived from metrics, events, provider observations, and revision state. InferCrane does not ask an LLM to invent the cause. Use `infercrane ui` for a keyboard-driven operations workspace and the separately released [operations console](/features/dashboard) for the browser view. Both reconstruct state from the same control-plane API; neither is the source of truth. # Inference protocols Source: https://infercrane.mintlify.app/features/protocols Faithful OpenAI-compatible protocol proxying with explicit runtime capability gates. InferCrane exposes one stable logical endpoint while preserving the selected runtime's native OpenAI-compatible request and response shape. It does not translate every workload into a lossy universal schema. ## Surfaces | Protocol | Gateway path | Pinned vLLM profile | | ----------------- | --------------------------------- | ------------------------------------------------- | | Chat Completions | `POST /v1/chat/completions` | Qualified | | Completions | `POST /v1/completions` | Qualified for text-generation models | | Embeddings | `POST /v1/embeddings` | Qualified for embedding-capable models | | Responses | `POST /v1/responses` | Gateway implemented; pinned runtime not qualified | | Online chat batch | `POST /v1/chat/completions/batch` | Gateway implemented; pinned runtime not qualified | The current [vLLM protocol documentation](https://docs.vllm.ai/en/latest/serving/online_serving/openai_compatible_server/) lists these upstream surfaces, but availability depends on both runtime version and model task. InferCrane therefore treats each capability independently. An unknown or unsupported claim returns `422 unsupported_protocol` before any request reaches the workload. ## Model identity Send the stable InferCrane endpoint name as `model`. The gateway selects a pinned route generation and rewrites only that field to the binding's upstream model identity. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} curl -fsS "$INFERCRANE_URL/v1/embeddings" \ -H "Authorization: Bearer $INFERCRANE_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"model":"search-production","input":["first document","second document"]}' ``` All other protocol fields pass through. Upstream status, content type, response body, cancellation, and streaming semantics are preserved. InferCrane never retries a partially transmitted stream. ## Telemetry and privacy Every accepted surface records the protocol operation, logical endpoint, selected binding, deployment/revision where known, provider/runtime dimensions, latency, status, token counts where the upstream reports them, and streaming errors. Prompt, response, embedding vectors, and tool arguments are not persisted by default. ## Current boundary The default vLLM image remains pinned to `0.8.5.post1`; its profile does not claim Responses or the newer online chat-batch endpoint. This is deliberate capability honesty, not automatic version guessing. A later runtime update must pass protocol conformance and real GPU qualification before those claims become default. # Provisioning and readiness Source: https://infercrane.mintlify.app/features/provisioning Follow capacity allocation, artifact preparation, runtime startup, readiness, and metrics. # Provisioning, runtimes and metrics Status: Existing targets implemented; SkyPilot experimental ## Entry points * SkyPilot adapter: `internal/provision/skypilot.go` * Declarative specification: `internal/spec/spec.go` * vLLM runtime inspection: `internal/runtime/vllm.go` * vLLM Prometheus parsing: `internal/metrics/vllm.go` * Provider-neutral capacity contracts and placement: `internal/capacity` * Timestamped pricing contract: `internal/pricing` ## Contract The support matrix and backend registry are deliberately separate. At process composition, an elastic backend binds a stable adapter name, cloud, runtime, and provider implementation; durable workflows select it without provider conditionals. Serverless and direct-target reconciliation follow the same pattern. Registering an adapter does not make it supported until its configuration, documentation, and real lifecycle acceptance are complete. See [ADR 0009](/adr/0009-qualified-support-and-backend-registration). Provisioners return ordinary targets so routing and reconciliation remain provider-neutral. Provider resource IDs and non-secret details may be stored for inspection and cleanup. Worker API keys are injected as SkyPilot secrets and are never stored in provider detail JSON. The SkyPilot replica lifecycle is discovery-first and keyed by a stable external name. `Ensure` checks JSON cluster inventory before an asynchronous named launch, `Observe` refreshes cluster state and resolves the exposed endpoint, `Delete` treats an absent cluster as success, and `Inventory` returns owned clusters for leak reconciliation. Repeating ensure or delete does not create or destroy a second resource. The durable workflow persists the external key and deterministic cluster identity before calling these methods. The `deployment.converge`/`replica.provision` workflow persists replica intent and that deterministic cluster identity before calling `sky launch`. Every retry re-runs discovery, provider observation, and vLLM readiness checks before registering a route. Its delete path re-observes asynchronous deletion and does not mark a replica deleted while it remains in provider inventory. These handlers are locally qualified with fault-injected providers; real RunPod qualification is still required. Capacity availability is an optional backend capability, not a provider conditional in the lifecycle state machine. Before the first create, the workflow discovers the deterministic resource. If it already exists, InferCrane adopts it without consulting mutable stock. If it is absent, the registered advisor may return `available`, `constrained`, `unavailable`, or `unknown`; the complete result is persisted in operation progress. Explicitly unavailable capacity defers creation with a retryable error. Constrained capacity proceeds with a warning because a stock query is a point-in-time signal, not a reservation. An unavailable advisory service does not make an otherwise healthy provider unusable. Provider observation details are also classified at the integration boundary. Known container bootstrap failures such as an interrupted image pull or exhausted host storage remain retryable while the provider retains the resource, but operation progress exposes the concrete boundary and an explicit cancel-before-replacement instruction. InferCrane does not create a second resource or silently select different hardware in response to these diagnostics. The RunPod advisor queries secure-cloud GPU stock without creating a Pod. A region-qualified request is clearly labeled as using a global signal because the provider response cannot prove availability in one requested region. Credentials are sent in an authorization header and are never written to URLs, checkpoints, or durable events. The superseded synchronous `Deploy`/`Destroy` adapter and direct-running operation store APIs have been removed. Provider mutation is reachable only through leased workflow handlers. Runtime inspection requires both a healthy endpoint and the expected served model. Metrics parsing normalizes supported vLLM metric aliases and ignores malformed or non-finite samples. ## Qualification SkyPilot requires credentialed acceptance tests for each supported provider/region/GPU combination. The production image pins SkyPilot 0.13.0 with its RunPod extra; changing this pin requires repeating the real-cloud lifecycle and zero-leak acceptance gate. Development fake workers demonstrate behavior only and cannot support performance or reliability claims. Placement prefers eligible warm model caches before known lower prices and is deterministic for equal candidates. A missing or stale price is explicit and must never be represented as zero cost. # Recipes and Inference Lab Source: https://infercrane.mintlify.app/features/recipes-lab Capture immutable serving evidence and compare measured candidates without hidden provisioning. # Recipes and Inference Lab Recipes turn one real deployment revision into a content-addressed, reproducible record. InferCrane will only capture a recipe when the active revision has an immutable ModelArtifact, an explicit runtime version, and a matching persisted AIPerf benchmark. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane benchmark qwen-prod --requests 100 --concurrency 10 infercrane recipe create qwen-prod \ --name qwen3-8b-balanced \ --version 1.0.0 infercrane recipes qwen3 ``` The recipe payload records the immutable model commit, runtime/version/arguments, provider adapter, region, GPU, compute mode, workload contract, benchmark workload, and benchmark ID. Provenance records the deployment/revision, artifact, benchmark tool/version, InferCrane version, and evidence class. The SHA-256 digest covers both canonical objects. Retrying the same name/version is idempotent only for identical content; different content is rejected. ## Compare evidence Inference Lab v1 compares existing benchmark history. It does not provision hardware or run another load generator: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane lab 'Qwen/Qwen3-8B@IMMUTABLE_COMMIT' \ --max-ttft-p95-ms 250 ``` Rows are ordered by measured p95 TTFT and include runtime, provider, GPU, error rate, throughput, SLO result when measurable, and cost metadata exactly as persisted. Current Lab results emit only `MEASURED` rows. The schema reserves `modeled` and `heuristic` labels for future evidence sources, but InferCrane never substitutes them silently. With no comparable benchmark, the result is an empty persisted evaluation. Use `--workload-digest` to require an exact canonical benchmark workload. Prompt and output content are not part of recipes, benchmark history, or Lab evaluations. ## Qualification boundary A captured recipe proves provenance, not universal portability. Provider/runtime support remains scoped to the integration matrix, and local benchmark fixtures are not real GPU evidence. Cost remains unavailable unless a trustworthy source and observation timestamp were persisted with the benchmark. # Release Guard Source: https://infercrane.mintlify.app/features/release-guard Compare active and candidate evidence with deterministic, persisted promotion policy. # Release Guard Release Guard is a deterministic, persisted comparison between an active revision and its candidate. It never uses an LLM to decide whether a candidate should be promoted. Animated Release Guard flow comparing persisted active and candidate evidence against deterministic policy before returning wait, reject, or accept. ```console theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane rollout validate qwen-prod --acknowledge-validation-cost --wait infercrane rollout inspect qwen-prod infercrane rollout policy get qwen-prod ``` An evaluation returns one of three decisions: * `ACCEPT`: enough evidence exists and every measured regression is within policy. * `REJECT`: readiness failed, proven compatibility mismatches, or a measured regression exceeds policy. * `WAIT`: the candidate is ready but there is not enough trustworthy evidence yet. Release Guard V2 also supports exact model/runtime compatibility evidence, explicit synthetic validation, sourced cost regression, and a bounded post-promotion automatic rollback window. Each evaluation snapshots the exact policy, active and candidate metrics, reason codes, and revision identities. Repeating an explanation therefore produces the same answer from stored evidence. `infercrane rollout inspect DEPLOYMENT` renders the latest persisted active/candidate comparison as a metric table and shows unavailable measurements explicitly. JSON output retains the complete policy, measurements, reason codes, revision identities, and evaluation timestamp. Missing measurements are not fabricated. Output throughput is compared only when both revisions report token usage. TTFT is required before acceptance. A candidate with no healthy ready replica is rejected immediately. Endpoint Release Guard never applies one primary deployment's metrics to an arbitrary routing graph. It currently qualifies single-primary comparisons, a primary change with an unchanged `primary-fallback` graph, and an append-only managed fallback whose immutable policy includes explicit privacy consent and hard request/cost reservations. Weighted changes or other unmeasured topology changes persist `INCONCLUSIVE` with `serving_plan_topology_unqualified`; they cannot be promoted until per-binding evidence exists. Infrastructure can be healthy while model behavior has regressed. For quality-sensitive changes, run a task-specific customer-owned evaluation and attach its [signed aggregate evidence](/features/semantic-quality). Release Guard can require comparable suite/evaluator versions, a minimum score, and a bounded regression. InferCrane still does not select an LLM judge, retain evaluation prompts or outputs, or let an evaluator promote a revision. Because a candidate is deliberately absent from the logical route, operators gather bounded candidate evidence explicitly with AIPerf rather than duplicating production requests: ```console theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane rollout policy set qwen-prod \ --require-compatibility \ --require-synthetic \ --auto-rollback \ --auto-rollback-window 300 \ --validation-max-requests 100 \ --validation-max-concurrency 4 infercrane rollout validate qwen-prod \ --requests 100 \ --concurrency 4 \ --acknowledge-validation-cost \ --wait ``` Release Guard uses a persisted active/candidate benchmark pair only when tool version and workload parameters match. The evaluation snapshot records `aiperf_benchmark` plus both benchmark IDs as its evidence source. Otherwise it waits for comparable evidence instead of mixing measurements. InferCrane does not silently duplicate inference requests. `rollout validate` prints a cost/privacy notice, enforces persisted request and concurrency ceilings, runs AIPerf against each revision, and then queues the durable evaluation. It does not retain prompts or generated output. When automatic rollback is enabled, promotion retains the previous healthy capacity until the persisted observation monitor reaches `ACCEPT` or `REJECT`. The monitor snapshots its policy and deadline at creation, so a concurrent policy edit cannot silently weaken an in-flight decision. Rejection atomically restores the old revision and target set, waits for its router generation, drains active streams safely, and deletes only failed revision capacity. A restart resumes the same monitor and deadline. After acceptance, issue an [Inference Passport](/features/inference-passports) to make the exact revision and release evidence independently verifiable. # Replay and capacity intelligence Source: https://infercrane.mintlify.app/features/replay-capacity Capture privacy-preserving workload shape and reason from observed capacity evidence. # Replay and capacity intelligence Inference Replay records the timing and token-count shape of production traffic without storing prompt or output bodies. Session, parent-session, and shared-prefix identities are tenant-secret HMACs, not raw identifiers. A trace records its window, sample count, schema, canonical digest, and evidence class. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane replay coder-production --window 24h --max-requests 1000 ``` This command only captures persisted observations. It sends no workload and creates no infrastructure. To approximate the captured mean token sizes and peak concurrency with AIPerf, opt in explicitly: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane replay coder-production \ --execute --acknowledge-cost --revision candidate ``` Execution is an AIPerf approximation, not a reproduction of prompt semantics or exact arrival timing. The distinction is preserved in output and evidence. ## Capacity intelligence ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane capacity --window 720h ``` Capacity Intelligence groups this tenant's observed lifecycle attempts by provider adapter, runtime, compute mode, region, and GPU. It reports sample counts, success rate, normalized capacity/runtime failures, and p50/p95 operation duration. It does not claim global availability or combine customer data. ## Artifact placement The artifact cache contract records short-lived provider-native observations (`present`, `prefetching`, `missing`, or `unknown`). Prefetch requests are durable and idempotent, but execution belongs to the selected infrastructure adapter. InferCrane does not implement a model CDN or download protocol. Cache observations expire after at most 24 hours. Missing or stale evidence must never be treated as a cache hit or a readiness guarantee. ## Current boundary Local qualification proves capture privacy, deterministic digests, tenancy, aggregation, and delegated prefetch semantics. Real cache behavior and capacity distributions require the consolidated provider qualification run. # Revisions and rollouts Source: https://infercrane.mintlify.app/features/revisions Create immutable candidates, inspect evidence, promote safely, and roll back. # Revisions and rollout operations Every deployment starts with an immutable active revision. A rollout creates a separate candidate revision; it does not mutate or replace the active revision. Candidate creation, promotion, rejection, and rollback are durable control-plane operations and may be safely retried after a CLI disconnect or control-plane restart. ```console theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane rollout create qwen-prod --model Qwen/Qwen3-8B --min 1 --max 4 --wait infercrane rollout create qwen-prod --model Qwen/Qwen3-8B --cloud runpod --gpu H100 --wait infercrane rollout provision qwen-prod REVISION_ID --wait infercrane rollout inspect qwen-prod infercrane rollout promote qwen-prod REVISION_ID --wait infercrane rollout reject qwen-prod REVISION_ID --reason "readiness failed" --wait infercrane rollout rollback qwen-prod REVISION_ID --reason "operator rollback" --wait ``` Only one candidate may exist for a deployment. Rejections and rollbacks require a persisted reason. Replaying the operation that created a candidate returns the same candidate, and replaying an already committed transition is a no-op. Elastic candidates persist their RunPod cloud, GPU, region, vLLM version and arguments, model revision, and replica bounds in the immutable revision spec. Candidate provisioning uses revision-scoped provider identities and does not publish those workers into active routing. Cancelling provisioning or rejecting the candidate removes only candidate capacity; the active revision is never part of that cleanup set. Promotion is an explicit operator action and is refused unless the latest persisted Release Guard evaluation accepted that candidate against the still-current active revision. The revision and candidate target set are committed atomically. InferCrane then waits for the newest router generation to publish exactly that worker set before it drains and deletes the old revision. Candidate creation and provisioning alone never route traffic. If the control plane restarts after the database cutover but before provider cleanup, the durable promotion resumes at router-generation verification. Cancellation before cutover removes candidate capacity; cancellation after cutover finishes safe draining because abandoning old billable capacity would leak resources. # Semantic quality evidence Source: https://infercrane.mintlify.app/features/semantic-quality Bind signed, aggregate task-quality evidence to exact revisions and enforce deterministic rollout thresholds. # Healthy infrastructure is not enough A candidate may be ready, fast, and error-free while producing worse answers. InferCrane accepts aggregate evidence from a customer-owned evaluation suite, verifies its signature and revision identity, and lets Release Guard enforce explicit score thresholds. InferCrane does not store prompts or generated outputs in this evidence format and does not choose an LLM judge for you. ## Create an evaluator key ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane evaluation keygen --file ./quality-evidence.key ``` Keep the private Ed25519 key outside the control plane. The operator authorized to attach evidence is the trust boundary. ## Ingest a result from any evaluator Have Ragas, DeepEval, a custom CI evaluator, or another customer-controlled system emit the strict content-free [evaluator result contract](https://github.com/infercrane/infercrane/blob/main/schemas/evaluator-result-v1.schema.json): ```json evaluator-result.json theme={"theme":{"light":"github-light-default","dark":"vesper"}} { "schema": "infercrane.dev/evaluator-result/v1", "suite": "support-answers", "suite_version": "git:8a91d7c", "evaluator": "customer-eval-ci", "evaluator_version": "1.4.0", "score": 0.93, "passed": true, "sample_count": 250, "artifact_digest": "sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "evaluated_at": "2026-08-13T20:00:00Z" } ``` Bind that aggregate result to the exact immutable candidate revision, sign it, and explicitly attach it through the control-plane API: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane evaluation ingest qwen-prod REVISION_ID \ --result ./evaluator-result.json \ --key ./quality-evidence.key \ --file ./candidate-quality.json \ --attach infercrane evaluation verify ./candidate-quality.json ``` Unknown fields are rejected, so prompt and generated-output bodies cannot accidentally enter the evidence envelope. If API attachment fails, the signed local file remains available for a safe `evaluation attach` retry. ## Sign aggregate evidence directly ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane evaluation sign qwen-prod REVISION_ID \ --suite support-answers \ --suite-version git:8a91d7c \ --evaluator ragas \ --evaluator-version 0.3.9 \ --score 0.91 \ --passed=true \ --samples 250 \ --artifact-digest sha256:RESULT_ARTIFACT_SHA256 \ --key ./quality-evidence.key \ --file ./candidate-quality.json infercrane evaluation verify ./candidate-quality.json infercrane evaluation attach qwen-prod --file ./candidate-quality.json ``` The signed payload records deployment, immutable revision, suite and evaluator versions, normalized score, pass/fail result, sample count, result-artifact digest, and evaluation time. Attaching the same evidence twice is idempotent. ## Fail closed in Release Guard ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane rollout policy set qwen-prod \ --require-quality \ --minimum-quality-score 0.90 \ --max-quality-regression 3 infercrane rollout evaluate qwen-prod infercrane rollout inspect qwen-prod ``` Active and candidate evidence must use the same suite version and evaluator version to be comparable. Missing or incomparable required evidence leaves the decision waiting. A failed suite, score below the minimum, or regression beyond policy rejects the candidate. The evaluator cannot activate a revision; promotion remains a separate, authorized control-plane decision. An artifact digest proves which private result bundle was evaluated, not that the evaluator was well-designed. Teams remain responsible for representative datasets, evaluator calibration, privacy, and human review of high-risk changes. # Provider-native serverless Source: https://infercrane.mintlify.app/features/serverless Preserve a stable endpoint while a qualified provider owns workers and scale-to-zero. # Provider-native serverless InferCrane delegates worker allocation, queueing, scale-up, idle scale-down, and GPU scheduling to a registered provider-native backend. InferCrane owns the logical deployment, durable endpoint operation, immutable model identity, routing metadata, telemetry, deletion, and explanations. Animated provider-native serverless lifecycle from zero workers through cold allocation, a warm request, and provider idle scale-down to zero. Backends implement one lifecycle contract for endpoint creation, observation, deletion, inventory, health, and an OpenAI-compatible endpoint URL. InferCrane does not contain a GPU scheduler or a provider switch in its durable serverless workflow. ## RunPod implementation RunPod Serverless is the first qualified backend. Create or select a template using RunPod's maintained vLLM worker. The template must set: * `MODEL_NAME` to the exact Hugging Face repository, such as `Qwen/Qwen3-8B`. * `MODEL_REVISION` to the immutable Hugging Face commit resolved for the deployment. `main` and `master` are rejected. * `RAW_OPENAI_OUTPUT=1` so streaming remains OpenAI-compatible SSE. * `ENABLE_AUTO_TOOL_CHOICE=true` and a model-compatible `TOOL_CALL_PARSER`. For `Qwen/Qwen3-8B`, RunPod recommends `TOOL_CALL_PARSER=hermes`. Configure the control plane, keeping the RunPod credential separate from InferCrane client credentials: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} export RUNPOD_API_KEY='...' export INFERCRANE_RUNPOD_SERVERLESS_TEMPLATE_ID='...' infercrane doctor --serverless ``` The template ID is intentionally explicit. InferCrane does not build or own a custom inference image, and it refuses to create an endpoint when the template does not match the requested immutable model artifact. InferCrane also constrains RunPod worker placement to hosts with a CUDA 13-capable driver. The maintained `worker-v1-vllm` image requires CUDA 13 or newer; without that provider constraint a worker can be placed successfully and then exit before model initialization begins. ## Deploy ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane plan Qwen/Qwen3-8B --compute serverless --cloud runpod --gpu L40S --max 4 infercrane deploy Qwen/Qwen3-8B --compute serverless --cloud runpod --gpu L40S --max 4 --wait ``` Serverless deployments always use zero minimum workers. The logical InferCrane endpoint remains stable while the provider scales workers from zero on the first request, back to zero after its idle timeout, and from zero again on later requests. InferCrane does not poll the inference URL for health because doing so would create or retain warm workers. Inference requests continue to use the InferCrane credential and logical model name. The gateway replaces that credential with the registered upstream credential only for the upstream request. It forwards streaming incrementally and propagates client cancellation through the request context. ## Delete and recovery Deletion first withdraws the logical route, then deletes the provider endpoint, confirms that the endpoint is absent from provider inventory, removes persisted target capacity, and finally removes the logical deployment. Every step is a durable operation and can resume after a control-plane restart. Endpoint creation is replay-safe. Before creating capacity, InferCrane lists endpoints for the deterministic deployment/revision key. A retry adopts the one exact matching endpoint; multiple matches or immutable-spec mismatches fail visibly instead of creating another billable resource. ## Current limitations * The first backend supports one configured immutable vLLM template per control-plane process. * RunPod is currently the only executable native Serverless adapter. Real cold/warm, streaming, cancellation, scale-to-zero, and billing acceptance remains a final manual gate. * InferCrane records request timing and token metadata but does not record prompts or generated content by default. See [cold-start intelligence](/features/cold-starts) for the exact classification evidence and unavailable provider timing boundaries. # Inference telemetry Source: https://infercrane.mintlify.app/features/telemetry Normalize latency, token, error, runtime, deployment, revision, and provider evidence. # Inference telemetry InferCrane records operational measurements for each request without storing prompts or generated content. Request bodies are used only to forward the OpenAI-compatible request, and response chunks are observed transiently to extract timing and usage metadata when the runtime supplies it. Persisted request dimensions are: * deployment and active revision * provider, runtime, and compute mode * GenAI operation name (`chat`) * requested logical model and runtime-reported response model * OpenTelemetry GenAI schema identity (`https://opentelemetry.io/schemas/gen-ai/1.42.0`) * HTTP status, error type, and whether the response streamed * response model, when returned by the runtime Persisted measurements are request latency, time to first response byte/chunk at the InferCrane gateway boundary, and input/output token counts when vLLM returns OpenAI usage fields. For streaming requests this timing maps to `gen_ai.response.time_to_first_chunk`; InferCrane does not claim it is the model server's internal `gen_ai.server.time_to_first_token`. Missing token usage remains unknown; InferCrane does not estimate it. Replica identity remains unset when the standalone router does not provide a trustworthy selected-worker identity. The corresponding OpenTelemetry GenAI concepts are `gen_ai.operation.name`, `gen_ai.provider.name`, `gen_ai.request.model`, `gen_ai.response.model`, `gen_ai.request.stream`, `gen_ai.usage.input_tokens`, `gen_ai.usage.output_tokens`, `gen_ai.server.request.duration`, and `gen_ai.response.time_to_first_chunk`. InferCrane-specific deployment, revision, provider/runtime, compute-mode, and operation dimensions are retained with the durable request record so decisions can be reproduced later. `runpod` is a grounded custom provider value because the convention permits provider-specific names outside its well-known list. Aggregated deployment statistics expose request rate, error rate, latency p50/p95, TTFT p50/p95, and observed input/output tokens per second over the selected window. Token throughput is emitted only from runtime-reported usage. The endpoint monitoring API returns the same content-free evidence as a bounded time series, plus binding/deployment/revision attribution and persisted lifecycle overlays. The console uses this API; it never queries PostgreSQL or an OpenTelemetry collector from the browser. Missing buckets and unsupported runtime metrics stay null or explicitly unavailable rather than becoming zero. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane observe coder-production ``` The human view includes the latest traffic summary. Use the authenticated console for 1-hour to 30-day charts and correlated scaling or release events. The Prometheus endpoint also exposes accounting queue depth and capacity, persisted and dropped request-record counters, and persistence failures. These distinguish inference-path health from telemetry backpressure without putting PostgreSQL on the request path. vLLM running/waiting and cache signals are persisted with autoscaling decisions; streaming cancellations and upstream disconnects are persisted as `client_cancelled` and `upstream_disconnect` error types. GPU metrics remain unavailable unless the provider/runtime exposes a trustworthy measurement. # Terminal operations workspace Source: https://infercrane.mintlify.app/features/terminal-ui Observe and safely operate deployments from a reconnectable terminal interface. `infercrane ui` opens an interactive operations workspace backed by the same authenticated control-plane API and durable operations as the scriptable CLI. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane ui ``` The workspace complements commands and JSON output. Use it for investigation and deliberate operator actions; use normal commands in automation, CI, redirected output, and agent workflows. ## Product views | View | What it answers | | -------------- | --------------------------------------------------------------------------------------- | | Overview | Is inference serving, what changed, and why? | | Operations | What durable work is active, when will it retry, and can it be cancelled? | | Rollout | Which revision is active, is there a candidate, and what did Release Guard decide? | | Performance | What are latency, TTFT, throughput, errors, cold-start evidence, and benchmark history? | | Infrastructure | Which provider adapter, targets, replicas, and immutable model artifact are involved? | | Scaling | What are the bounds and why did capacity change? | | Events | What persisted event occurred, when, and with what machine-readable payload? | Use `←` and `→` to change views, or press `1`–`7` to jump directly. Navigation uses compact labels on narrow terminals and adds a contextual workspace column on ultrawide terminals. On the Events view, use `j` and `k` to inspect full historical details. Old events remain visible but are separated from live health so historical failures do not look like current incidents. ## Safe actions Press `Ctrl-K` or `:` to open the action palette. InferCrane only shows actions applicable to the selected deployment and persisted state. Direct guarded actions include: * cooperatively cancel an active durable operation * evaluate Release Guard for the current candidate * promote only when the current candidate has a persisted accepting Guard decision Every mutation shows its impact, requires a second confirmation, uses an idempotency key, and queues a durable control-plane operation. Release Guard evaluation explicitly warns that measured candidate traffic may incur provider cost. Closing the terminal never cancels queued work. Complex authoring remains a CLI handoff. The palette copies exact commands for test requests, reproducible benchmarks, and semantic capacity plans. Candidate creation, rollback, rejection reasons, deletion plans, and administrative workflows remain explicit CLI/spec operations where inputs and diffs are easier to review. Promotion is unavailable when an evaluation is missing, rejecting, or belongs to a previous candidate. InferCrane never treats historical acceptance as permission to promote a new revision. ## Read-only environments Start the same workspace with mutation controls disabled: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane ui --read-only ``` The action palette retains copyable command handoffs but cannot construct API mutations. This is useful for shared incident sessions, demos, and restricted credentials. Server-side authorization remains authoritative in both modes. ## Reconnection The control plane—not the terminal—owns deployment work. Quit, disconnect SSH, or close the laptop, then reopen: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane ui ``` The workspace reconstructs itself from persisted deployments, operations, revisions, Guard evaluations, benchmarks, scaling decisions, and events. tmux is optional and InferCrane does not manage tmux sessions. ## Keyboard reference | Key | Action | | --------------------- | ------------------------------------------------ | | `←`, `h`, `Shift-Tab` | Previous product view | | `→`, `l`, `Tab` | Next product view | | `1`–`7` | Jump directly to a product view | | `j`, `↓` / `k`, `↑` | Select deployment, or event on the Events view | | `Ctrl-K`, `:` | Open applicable action palette | | `r` | Refresh immediately | | `c` | Copy endpoint or active operation resume command | | `?` | Toggle safety and keyboard help | | `q`, `Ctrl-C` | Close without cancelling operations | The workspace detects light and dark terminal backgrounds, adapts to narrow screens, requires an interactive TTY, and reconnects after transient API failures. For screen readers and logs, use `--output json` or the equivalent `status`, `events`, `explain`, and `operation` commands. # Deploy and operate AI models across your infrastructure. Source: https://infercrane.mintlify.app/index Build or connect inference with durable operations, autoscaling, safe releases, and evidence you can inspect.
Open-source inference control plane
Start the quickstart View on GitHub
Build or connect Safe releases Explainable operations No Kubernetes required
```bash Deploy a model theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane deploy mistralai/Mistral-7B-Instruct-v0.3 \ --name support-production # The operation continues if this terminal disconnects. infercrane status support-production --watch ``` ```bash Send a streaming request theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane request support-production \ --message "Summarize this incident." \ --stream ``` Build a deployment from a model or custom OCI workload, or connect inference you already run. InferCrane gives applications one OpenAI-compatible logical endpoint while durable control-plane operations provision, reconcile, scale, and safely replace workers behind it. Providers and runtimes integrate through explicit contracts; Kubernetes is not required.
requestOpenAI client
stable identityendpoint
policyroute generation
healthyruntime replicas
## The operational layer around inference runtimes Start from a model, recipe, or immutable custom OCI workload. Disconnecting the CLI does not abandon the operation. Compare active and candidate revisions with deterministic, persisted Release Guard policy. Explain scaling, rollout, degradation, and cold starts from recorded state and measurements. ## Start from where you are Plan a qualified serving configuration and create a durable endpoint. Add health and operational evidence without migrating or transferring lifecycle ownership. Run the complete GPU-free control and request path locally in under five minutes. ## One product, two compute modes A registered elastic backend provisions runtime replicas. InferCrane reconciles desired capacity, routes only to ready workers, and fences scale-down before provider termination. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane deploy mistralai/Mistral-7B-Instruct-v0.3 \ --cloud runpod \ --gpu L40S \ --min 1 \ --max 4 ``` A provider-native serverless backend owns worker allocation and scale-to-zero. InferCrane preserves the logical endpoint, lifecycle evidence, cancellation, and cleanup. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane deploy mistralai/Mistral-7B-Instruct-v0.3 \ --compute serverless \ --cloud runpod \ --gpu L40S \ --max 4 ``` InferCrane is provider- and runtime-extensible by design. Provider and runtime capabilities are declared and conformance-tested; each adapter still has an independent qualification status. vLLM, SGLang, and custom OCI have separate evidence states, as do RunPod and narrow AWS BYOC adapters. Consult [capability status](/project-status) before relying on a combination. ## Evidence, not guesses InferCrane records durable operation events, immutable model and revision identity, normalized request telemetry, benchmark reproduction metadata, and deterministic policy decisions. It does not fabricate provider pricing or timing boundaries that the provider does not expose. Run the GPU-free development stack and send your first OpenAI-compatible request. See the control-plane and data-plane boundaries behind durable operations. Deploy a model, connect LiteLLM, scope a sandbox, attach trained artifact lineage, and reject a bad release. # AIPerf Source: https://infercrane.mintlify.app/integrations/aiperf Run reproducible load generation without sending benchmark data elsewhere. # AIPerf InferCrane delegates load generation to AIPerf and persists the workload, runtime, model artifact, provider, GPU, revision, results, and exact reproduction command. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane benchmark qwen-prod \ --requests 1000 \ --concurrency 32 \ --random-seed 17 ``` Use `--revision candidate` only when you intend to benchmark isolated candidate capacity. Benchmark data remains in the InferCrane control plane; it is not uploaded by default. Understand measurements, persisted reproduction metadata, and evidence limits. # AWS EC2 BYOC Source: https://infercrane.mintlify.app/integrations/aws-ec2 Configure the narrow, private-network AWS EC2 provider adapter. # AWS EC2 BYOC The AWS adapter provisions one EC2 instance per durable replica intent through Provider Contract V1. InferCrane assumes a customer role, uses explicit private networking, and adopts resources by idempotency token and ownership tags after uncertain responses. This is intentionally narrow. It is not EKS, SageMaker, automatic instance selection, public-IP bootstrap, or a general AWS abstraction. ## Prerequisites * AWS CLI v2 on the control-plane host * a source identity permitted to call `sts:AssumeRole` * a role trust policy scoped to that source identity and, preferably, an external ID * an explicit private subnet and security group path between the control plane and worker port `8000` * a GPU-compatible AMI containing NVIDIA drivers, Docker, and AWS CLI v2 * an EC2 instance profile permitted to read exactly the worker API-key secret * an OCI runtime image pinned by `sha256` digest The assumed control-plane role needs the narrow EC2 describe, run, tag, and terminate permissions for InferCrane-owned instances. Restrict resources and tag conditions according to your AWS account policy. ## Control-plane configuration Configure the complete set. Partial configuration fails startup rather than silently disabling safety controls. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} export INFERCRANE_AWS_ROLE_ARN='arn:aws:iam::123456789012:role/infercrane-control-plane' export INFERCRANE_AWS_EXTERNAL_ID='organization-controlled-value' export INFERCRANE_AWS_REGION='eu-central-1' export INFERCRANE_AWS_SUBNET_ID='subnet-0123456789abcdef0' export INFERCRANE_AWS_SECURITY_GROUP_IDS='sg-0123456789abcdef0' export INFERCRANE_AWS_AMI_ID='ami-0123456789abcdef0' export INFERCRANE_AWS_INSTANCE_TYPE='g6e.xlarge' export INFERCRANE_AWS_GPU='L40S' export INFERCRANE_AWS_INSTANCE_PROFILE_ARN='arn:aws:iam::123456789012:instance-profile/infercrane-worker' export INFERCRANE_AWS_WORKER_SECRET_ARN='arn:aws:secretsmanager:eu-central-1:123456789012:secret:infercrane-worker-key' export INFERCRANE_AWS_IMAGE_DIGEST='vllm/vllm-openai@sha256:REPLACE_WITH_QUALIFIED_DIGEST' ``` The Secrets Manager value referenced by `INFERCRANE_AWS_WORKER_SECRET_ARN` must contain the same worker credential configured as `INFERCRANE_API_KEY` on this self-hosted control plane. InferCrane uses that value for private worker health checks, routing, and explicit candidate validation; it persists only the secret ARN in provider metadata. `INFERCRANE_AWS_IMAGE_DIGEST` is the configured vLLM default and remains required for the adapter's complete startup configuration. An SGLang or custom OCI revision supplies its own immutable image and argv; the EC2 adapter uses that revision workload instead of the vLLM default. It still uses the same private network, instance profile, worker secret and ownership tags. Validate role assumption without creating a resource: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane doctor --aws ``` ## Deploy The requested region and GPU must exactly match the configured, qualified instance profile: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane plan Qwen/Qwen3-8B \ --name qwen-aws \ --cloud aws \ --region eu-central-1 \ --gpu L40S infercrane deploy Qwen/Qwen3-8B \ --name qwen-aws \ --cloud aws \ --region eu-central-1 \ --gpu L40S \ --idempotency-key qwen-aws-initial ``` Closing the terminal does not stop provisioning. Resume with the operation ID printed by `deploy`. Deletion terminates only instances carrying InferCrane ownership tags and the persisted replica key. For the simulated portable-runtime path, apply [`examples/sglang.yaml`](https://github.com/infercrane/infercrane/blob/main/examples/sglang.yaml) or replace the placeholder image in [`examples/custom-oci.yaml`](https://github.com/infercrane/infercrane/blob/main/examples/custom-oci.yaml). Real GPU compatibility remains a deferred manual qualification gate. ## Security and accounting behavior STS credentials are short lived and exist only in the child AWS CLI process environment. InferCrane does not persist or return them. Workers retrieve their API key directly from Secrets Manager through the instance profile. EC2 is launched without a public IP. Cost is reported as `unknown`. InferCrane does not ship a live AWS pricing catalog and will not infer cost from an instance-type name. ## Qualification state Hermetic contract tests cover create-response loss, adoption, replay, deletion, tag-scoped inventory, private networking, immutable images, and credential redaction. Real AWS provisioning remains deferred until consolidated manual qualification; inspect `infercrane integrations` for the exact state. # GCP Compute BYOC Source: https://infercrane.mintlify.app/integrations/gcp-compute Configure the private, identity-based GCP Compute provider adapter. # GCP Compute BYOC The `gcp-compute` profile realizes one durable replica intent as one private Compute Engine VM. A deterministic resource name lets reconciliation adopt the VM after an uncertain create response. InferCrane does not store a service-account key, assign a public IP, or infer provider pricing. The adapter is hermetically qualified. Real GCP GPU execution is deferred to consolidated manual qualification and must not be described as production-qualified yet. ## Configure The production image contains a checksum-pinned `gcloud` client. Authenticate with Application Default Credentials using an identity allowed to create, describe, list, and delete only the intended project resources. For Docker Compose, set `GCLOUD_CONFIG_DIR` to a read-only gcloud configuration directory. Prefer workload identity when the control plane runs on GCP; do not put a service-account key in a DeploymentSpec. Configure all fields together: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} export INFERCRANE_GCP_PROJECT='acme-production' export INFERCRANE_GCP_ZONE='europe-west4-a' export INFERCRANE_GCP_SUBNET='private-inference' export INFERCRANE_GCP_MACHINE_TYPE='g2-standard-4' export INFERCRANE_GCP_GPU='nvidia-l4' export INFERCRANE_GCP_SERVICE_ACCOUNT='runtime@acme-production.iam.gserviceaccount.com' export INFERCRANE_GCP_VM_IMAGE='projects/cos-cloud/global/images/cos-stable-QUALIFIED_VERSION' export INFERCRANE_GCP_WORKER_SECRET='infercrane-worker-key' export INFERCRANE_GCP_CONTAINER_IMAGE='REGISTRY/IMAGE@sha256:QUALIFIED_DIGEST' export GCLOUD_CONFIG_DIR="$HOME/.config/gcloud" ``` Validate identity, Compute API access, and the configured zone without creating capacity: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane doctor --gcp ``` The attached service account reads the worker credential from Secret Manager at startup. Grant it only secret-version access to that secret. The subnet must allow the control plane to reach the runtime port over private addressing. ## Deploy The advanced `provider.adapter` field selects an exact infrastructure profile. It is optional while only one default adapter exists for a cloud/runtime pair. ```yaml theme={"theme":{"light":"github-light-default","dark":"vesper"}} apiVersion: infercrane.dev/v1 kind: Deployment name: qwen-gcp model: id: Qwen/Qwen3-8B runtime: engine: vllm compute: mode: elastic resources: gpu: nvidia-l4 provider: cloud: gcp adapter: gcp-compute region: europe-west4 scaling: min_replicas: 1 max_replicas: 1 ``` ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane deploy deployment.yaml --idempotency-key qwen-gcp-initial ``` The operation remains durable if the terminal disconnects. Inventory and deletion are restricted to resources labeled `infercrane-managed=true`; real cleanup must still be confirmed during manual qualification. The guarded real-provider harness is available when an isolated paid project is ready: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} ./scripts/portable-provider-acceptance.sh gcp --approve-paid-resources ``` ## Other GCP profiles `gcp-mig`, `gcp-gke`, and `gcp-vertex` have independent registered capability boundaries. They are not aliases for Compute Engine and are not executable or locally qualified in this milestone until their own lifecycle contracts pass. `infercrane integrations --output json` is authoritative. # GitHub Actions Source: https://infercrane.mintlify.app/integrations/github-actions Deterministic pull-request plans and protected InferCrane release checks. The repository action renders an InferCrane semantic plan into the job summary and writes the exact JSON plan as an artifact. Plan mode is read-only. Pin the action to a published release tag or full commit SHA. Do not use a floating branch for a production delivery workflow. ```yaml theme={"theme":{"light":"github-light-default","dark":"vesper"}} name: inference delivery on: [pull_request] jobs: plan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: infercrane/infercrane/actions/infercrane@v2.0.0 with: mode: plan spec: deploy/qwen.yaml env: INFERCRANE_CONTROL_URL: ${{ secrets.INFERCRANE_CONTROL_URL }} INFERCRANE_API_KEY: ${{ secrets.INFERCRANE_API_KEY }} - uses: actions/upload-artifact@v4 with: name: infercrane-plan path: infercrane-delivery.json ``` ## Protected apply Apply requires both `mode: apply` and `confirm-apply: "true"`. Configure a GitHub environment with required reviewers; the action cannot and does not infer organizational approval policy. ```yaml theme={"theme":{"light":"github-light-default","dark":"vesper"}} jobs: deploy: environment: production runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: infercrane/infercrane/actions/infercrane@v2.0.0 with: mode: apply confirm-apply: "true" spec: deploy/qwen.yaml wait-timeout: 30m env: INFERCRANE_CONTROL_URL: ${{ secrets.INFERCRANE_CONTROL_URL }} INFERCRANE_API_KEY: ${{ secrets.INFERCRANE_API_KEY }} ``` Closing or cancelling the job stops only its waiter. The action reports the durable operation ID so an operator can resume with `infercrane operation watch`. ## Exact release check ```yaml theme={"theme":{"light":"github-light-default","dark":"vesper"}} - uses: infercrane/infercrane/actions/infercrane@v2.0.0 with: mode: release-check deployment: qwen-prod revision: ${{ needs.deploy.outputs.revision }} ``` The check passes only when the expected revision is active, serving, converged, has no active operation, and has a persisted complete, cryptographically verified Inference Passport. The job summary and machine-readable artifact include its digest and public key identity. Output is stripped of terminal escapes, bounded for GitHub summaries, and redacts values from credential-like environment variables. The action does not print or upload prompt content. # Hugging Face models Source: https://infercrane.mintlify.app/integrations/hugging-face Resolve mutable Hugging Face model references to immutable artifacts. # Hugging Face models InferCrane uses `huggingface_hub` and `hf_xet` rather than a custom transfer protocol. Before provisioning, it resolves a repository and mutable reference such as `main` to an immutable commit when the provider exposes that evidence. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane plan Qwen/Qwen3-8B --cloud runpod --gpu L40S infercrane deploy Qwen/Qwen3-8B --cloud runpod --gpu L40S ``` The resulting `ModelArtifact` can include repository identity, immutable revision, approximate size, and grounded compatibility/cache metadata. Missing provider evidence remains unavailable; InferCrane does not infer it. See the persisted identity and evidence model. # Kubernetes Source: https://infercrane.mintlify.app/integrations/kubernetes Run InferCrane-owned inference workloads in a namespace without adding another operator or scheduler. # Kubernetes The Kubernetes provider maps one durable replica intent to either a `Deployment` plus `Service`, or one standard KServe `InferenceService`. Kubernetes owns scheduling and Pods. InferCrane owns revision lifecycle, rollout policy, routing membership, evidence, and deletion of its exact labeled resources. The adapter has hermetic and Kind lifecycle qualification. Real GPU, vLLM, SGLang, and custom OCI compatibility remains deferred to consolidated manual qualification. Registration is not a real-cluster support claim. ## Choose the workload API | Mode | InferCrane creates | Use when | | ------------ | --------------------------------------------------------- | ---------------------------------------------------------------------------- | | `deployment` | one `apps/v1 Deployment` and one `v1 Service` | You want the narrowest dependency set | | `kserve` | one standard `serving.kserve.io/v1beta1 InferenceService` | KServe Standard mode is already installed and operated by your platform team | InferCrane does not create child Pods directly. It does not install KServe, Gateway API, a GPU device plugin, model storage, or a Kubernetes distribution. ## Bootstrap a namespace Review the manifests before applying them: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} kubectl apply -f deploy/kubernetes/base/namespace.yaml kubectl apply -f deploy/kubernetes/base/service-accounts.yaml kubectl apply -f deploy/kubernetes/base/provider-rbac.yaml ``` The included Role is namespace-scoped and contains no wildcard, Secret, Pod, cluster-wide, or RBAC mutation permission. If the control plane runs outside the cluster, bind the same Role to the user or identity in its kubeconfig instead of the included service account subject. Create the worker credential without putting it in Git or shell history. Its value must equal the control-plane worker credential used for health checks and routing: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} kubectl --namespace infercrane-system create secret generic infercrane-worker \ --from-file=api-key="$HOME/.config/infercrane/worker-key" ``` ## Configure the control plane ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} export INFERCRANE_KUBERNETES_CONTEXT='production-cluster' export INFERCRANE_KUBERNETES_NAMESPACE='infercrane-system' export INFERCRANE_KUBERNETES_WORKLOAD_API='deployment' export INFERCRANE_KUBERNETES_SERVICE_ACCOUNT='infercrane-runtime' export INFERCRANE_KUBERNETES_WORKER_SECRET_NAME='infercrane-worker' export INFERCRANE_KUBERNETES_WORKER_SECRET_KEY='api-key' export INFERCRANE_KUBERNETES_IMAGE_DIGEST='vllm/vllm-openai@sha256:REPLACE_WITH_QUALIFIED_DIGEST' export INFERCRANE_KUBERNETES_GPU_RESOURCE='nvidia.com/gpu' export INFERCRANE_KUBERNETES_GPU_PRODUCT_LABEL='nvidia.com/gpu.product' ``` Configuration is all-or-nothing. The image must be immutable. The adapter always passes an explicit context and namespace to `kubectl`; it never relies on or changes the current context. Validate the Kubernetes API, optional KServe CRD, and every required namespaced permission without creating a workload: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane doctor --kubernetes ``` ## Deploy The GPU value maps to the configured product-label value. It is never silently substituted. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane plan Qwen/Qwen3-8B \ --name qwen-kubernetes \ --cloud kubernetes \ --gpu NVIDIA-L40S infercrane deploy Qwen/Qwen3-8B \ --name qwen-kubernetes \ --cloud kubernetes \ --gpu NVIDIA-L40S \ --idempotency-key qwen-kubernetes-initial ``` Provisioning uses strict server-side dry-run followed by server-side apply with the `infercrane-provider-v1` field manager. InferCrane does not use `--force-conflicts`; ownership drift fails visibly. A lost apply response is safe to retry because resource names and ownership metadata derive from the durable replica key. ## KServe Standard mode Install and operate a compatible KServe release separately, apply `deploy/kubernetes/kserve/provider-rbac.yaml`, then set: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} export INFERCRANE_KUBERNETES_WORKLOAD_API='kserve' ``` The provider verifies the `InferenceService` API and required permissions during `doctor`. KServe owns generated Deployments, Services, and Pods; InferCrane inventories and deletes only the parent InferenceService. Raw KServe condition metadata remains available through `infercrane inspect`. KServe `LLMInferenceService`, llm-d, and Dynamo are not enabled because each can own routing, scheduling, or disaggregation. They require a future explicit ownership contract rather than a hidden second router. ## Expose the logical endpoint `deploy/kubernetes/gateway-api/httproute.yaml` is an optional placeholder. Replace the Gateway and hostname, then apply it only if your cluster already has Gateway API and a controller. It routes to the InferCrane gateway—not directly to revisions or workers—so safe rollout ownership stays singular. ## Local conformance ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} make test-kubernetes-manifests make test-kubernetes-kind ``` The disposable Kind test proves strict apply, restart observation, lost-state repair, foreign field ownership rejection, idempotent deletion, and zero remaining run-owned resources. It schedules no GPU and sends no paid provider request. # LiteLLM Source: https://infercrane.mintlify.app/integrations/litellm Keep LiteLLM provider translation and credentials while InferCrane adds stable endpoint identity, lifecycle evidence, and release policy. # Connect LiteLLM without replacing it LiteLLM and InferCrane own different problems. LiteLLM translates provider protocols and holds its upstream credentials. InferCrane owns the stable application endpoint, adoption state, persisted request evidence, and safe release decisions. ```mermaid theme={"theme":{"light":"github-light-default","dark":"vesper"}} flowchart LR APP[Application
model=support-production] --> IC[InferCrane
endpoint · policy · evidence] IC --> LL[User-managed LiteLLM
translation · provider credentials] LL --> API1[Managed API] LL --> API2[Other model provider] IC --> SELF[Self-hosted vLLM or SGLang] ``` ## Connect in observe-only mode ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane connect https://litellm.internal.example/v1 \ --as support-production \ --type litellm \ --model company-coder infercrane observe support-production infercrane doctor support-production ``` InferCrane verifies the OpenAI-compatible discovery surface before persisting the connection. It does not install, configure, upgrade, or fork LiteLLM. The private console exposes the same path under **New inference → Connect existing inference**. Choose **LiteLLM** as the connector. Connections start observe-only; traffic ownership never transfers silently. ## Promote traffic ownership explicitly After you have inspected health and evidence: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane adopt promote support-production --ownership traffic-managed ``` The application continues calling: ```python Python theme={"theme":{"light":"github-light-default","dark":"vesper"}} from openai import OpenAI client = OpenAI( base_url="https://inference.example.com/v1", api_key="INFERCRANE_ENDPOINT_TOKEN", ) response = client.responses.create( model="support-production", input="Summarize this support case.", ) ``` ```typescript TypeScript theme={"theme":{"light":"github-light-default","dark":"vesper"}} import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://inference.example.com/v1", apiKey: "INFERCRANE_ENDPOINT_TOKEN", }); const response = await client.responses.create({ model: "support-production", input: "Summarize this support case.", }); ``` ## Ownership and qualification | Concern | Owner | | ------------------------------------- | ----------------------- | | Provider API credentials | LiteLLM | | Provider protocol translation | LiteLLM | | LiteLLM install and upgrades | Your LiteLLM deployment | | Stable application model name | InferCrane | | Observe/route ownership state | InferCrane | | Request Inspector and Doctor evidence | InferCrane | | Release policy across serving plans | InferCrane | The OpenAI-compatible behavior is locally qualified with hermetic fixtures. Real LiteLLM versions, plugins, upstream providers, and credential policy still require qualification in your environment. ## Why not bundle LiteLLM? Bundling would make InferCrane responsible for another gateway's security patches, license boundary, provider catalog, and upgrades. The composition contract keeps that dependency replaceable and lets teams use LiteLLM, another gateway, or InferCrane's native data plane without changing the logical endpoint contract. # MCP for coding agents Source: https://infercrane.mintlify.app/integrations/mcp Give coding agents read-only access to persisted InferCrane evidence without granting deployment authority. # Operational context without mutation InferCrane includes an MCP server over standard input/output: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane mcp ``` Configure your MCP-compatible client to launch that command with the same InferCrane context and credential it would use for read-only CLI inspection. ```json theme={"theme":{"light":"github-light-default","dark":"vesper"}} { "mcpServers": { "infercrane": { "command": "infercrane", "args": ["mcp"], "env": { "INFERCRANE_CONTEXT": "production" } } } } ``` The server exposes six bounded tools: | Tool | Evidence | | --------------------------------- | ----------------------------------------------------------------------------------------- | | `infercrane_list_deployments` | Logical deployments and lifecycle state | | `infercrane_inspect_deployment` | Desired/observed state, revisions, replicas, operations, measurements, and Guard evidence | | `infercrane_inspect_endpoint` | Logical model, environment, bindings, active plan, and candidate plan | | `infercrane_inspect_request` | Content-free routing, latency, tokens, retries, and fallback evidence | | `infercrane_inspect_operation` | Durable operation state and resume identity | | `infercrane_list_curated_recipes` | Reviewed, commit-pinned configuration recipes | All tools declare read-only, non-destructive, closed-world annotations. The server has no deploy, scale, promote, delete, budget, secret, or provider mutation tool. Read-only access can still reveal operational metadata. Use a least-privilege InferCrane principal, scope it to the appropriate tenant, and do not place credentials in the client configuration when the client supports secret references or environment injection. Mintlify also publishes the navigable documentation as [`llms.txt`](https://infercrane.mintlify.site/llms.txt) and [`llms-full.txt`](https://infercrane.mintlify.site/llms-full.txt) for agents that need product knowledge rather than live operational evidence. # Integration model Source: https://infercrane.mintlify.app/integrations/overview How providers, runtimes, artifacts, routers, metrics, and benchmark tools extend InferCrane without forking its lifecycle. # Integration model InferCrane is a durable inference control plane, not a wrapper around one cloud. Its deployment, revision, operation, Release Guard, explanation, and telemetry models do not belong to RunPod, SkyPilot, or vLLM. External systems enter through capability-specific contracts. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane integrations ``` This authenticated read returns the compiled Provider Contract, Runtime Contract, and Composition Contract versions, registered adapters, capabilities, ownership boundaries, and separate local versus real-system qualification states. It never upgrades registration or hermetic simulation into a public support claim. | Concern | InferCrane owns | Adapter owns | | ------------------------- | ------------------------------------------------------------------------ | ----------------------------------------------------------------- | | Elastic infrastructure | Replica intent, retries, drain and deletion ordering | Ensure, observe, delete and inventory | | Serverless infrastructure | Logical endpoint, durable operation and evidence | Endpoint lifecycle, workers and scale-to-zero | | Inference runtime | Expected model identity and normalized health | Model execution and runtime-specific inspection | | Replica routing | Desired membership and generation cutover | Request distribution among standalone replicas | | Model artifacts | Immutable `ModelArtifact` identity and attachment | Repository resolution and transfer | | Benchmarking | Reproduction record and history | Workload generation and raw measurements | | Metrics | Normalized dimensions and persisted evidence | Runtime/provider signal extraction | | Gateway composition | Stable endpoint, adoption state, policy, and evidence | Protocol translation, upstream credentials, and gateway lifecycle | | External sandbox | External reference and endpoint-scoped access | Isolation, commands, files, network policy, and sandbox lifecycle | | Training handoff | Signature verification, immutable artifact lineage, and revision binding | Training data, execution, checkpoints, and scheduler | ## Registration is not qualification A control-plane process registers concrete adapters during startup. Durable replicas persist the adapter identity used to create them, so restart, rollback, and deletion return to the same implementation without guessing from a cloud name. The release support matrix is a separate policy. An adapter can exist in development without being advertised publicly. Qualification requires configuration, documentation, compatibility records, failure testing, real infrastructure acceptance, and zero leaked billable resources. The current adapter registry includes RunPod elastic/serverless, narrow AWS EC2, GCP Compute, and Kubernetes elastic adapters; vLLM, SGLang, custom OCI, and governed external targets; plus LiteLLM, external-sandbox access, and signed-artifact-handoff composition profiles. The compatibility matrix qualifies only exact combinations; registration never implies real-system evidence. ## Adding an integration 1. Implement only the narrow capability contract the external system owns. 2. Give the adapter a stable durable identity and register it at process composition. 3. Map trustworthy observations into InferCrane's normalized state and telemetry. 4. Add configuration, diagnostics, documentation, and deterministic failure behavior. 5. Qualify the exact cloud/runtime/compute-mode combination with real lifecycle evidence. The versioned contract details are documented in [Provider Contract V1](/architecture/provider-contract), [Runtime Contract V1](/architecture/runtime-contract), and [ADR 0033](/adr/0033-replaceable-external-composition-contracts). Do not add a provider conditional to a generic workflow, expose registration as support, build a second scheduler, or silently fabricate unavailable provider data. See [ADR 0009](/adr/0009-qualified-support-and-backend-registration) for the accepted boundary. # Provider profiles Source: https://infercrane.mintlify.app/integrations/provider-profiles Understand executable, registered, and deferred infrastructure profiles. # Provider profiles InferCrane separates the stable cloud identity from the adapter that implements a particular provider product. For example, `aws-ec2`, `aws-asg`, and `aws-sagemaker` are different profiles even though their cloud is `aws`. This prevents managed endpoint semantics from being forced into a one-resource-per-replica contract. | Cloud | Profile | Local state | Ownership boundary | | --------- | --------------- | ------------------- | --------------------------------------------------------------------- | | AWS | `aws-ec2` | Locally qualified | One private VM per replica intent | | AWS | `aws-asg` | Registered | ASG owns instances and replacement | | AWS | `aws-eks` | Registered | Reuse namespaced Kubernetes lifecycle | | AWS | `aws-sagemaker` | Registered | SageMaker owns endpoint children | | AWS | `aws-bedrock` | Registered external | Customer-governed external capacity | | GCP | `gcp-compute` | Locally qualified | One private VM per replica intent | | GCP | `gcp-mig` | Registered | MIG owns instances and rolling replacement | | GCP | `gcp-gke` | Registered | Reuse namespaced Kubernetes lifecycle | | GCP | `gcp-vertex` | Registered | Vertex owns deployed-model children | | CoreWeave | `coreweave-cks` | Registered | Reuse namespaced Kubernetes lifecycle; CKS owns GPU platform services | Registered means the capability and ownership boundary is modeled and inspectable. It does **not** mean InferCrane can execute that profile. Local and real qualification are separate evidence states. Use `infercrane integrations` rather than relying on this prose for the running binary's exact state. ## Exact selection Use an adapter only when a cloud/runtime pair has multiple installed implementations: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane deploy Qwen/Qwen3-8B \ --cloud gcp \ --provider-adapter gcp-compute \ --region europe-west4 \ --gpu nvidia-l4 ``` The adapter identity is persisted in immutable revision state. Reconciliation therefore resumes the same implementation after a control-plane restart instead of guessing from currently installed plugins. # Python SDK Source: https://infercrane.mintlify.app/integrations/python Submit and resume durable InferCrane operations from typed Python applications. The zero-dependency Python SDK uses the authenticated control-plane API. It does not connect to PostgreSQL, invoke infrastructure providers, or implement deployment lifecycle logic in the client. ## Install from the repository Install the SDK from the same checked-out InferCrane tag as your control plane until a matching published Python distribution is listed in the release notes. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} python -m pip install ./sdk/python ``` ## Submit durable work ```python theme={"theme":{"light":"github-light-default","dark":"vesper"}} from infercrane import InferCrane client = InferCrane( api_key="...", base_url="https://infercrane.internal", ) operation = client.deploy( name="qwen-prod", model="Qwen/Qwen3-8B", cloud="runpod", # use a provider qualified by your installation gpu="L40S", min_replicas=1, max_replicas=4, idempotency_key="qwen-prod-initial", ) ready = client.wait(operation.id, timeout=900) ``` A wait timeout raises `OperationTimeout` and includes the operation ID. It does not call the cancel endpoint. A later process can resume with `client.wait(operation_id)`. ```python Synchronous stream theme={"theme":{"light":"github-light-default","dark":"vesper"}} for event in client.stream_chat( "qwen-prod", [{"role": "user", "content": "Summarize durable operations."}], ): print(event) ``` ```python Async operation theme={"theme":{"light":"github-light-default","dark":"vesper"}} from infercrane import AsyncInferCrane client = AsyncInferCrane(api_key="...", base_url="https://infercrane.internal") operation = await client.deploy( name="qwen-prod", model="Qwen/Qwen3-8B", cloud="runpod", gpu="L40S", ) ready = await client.wait(operation.id, timeout=900) ``` The stream parser yields each SSE JSON event once and requires `[DONE]`. Closing the iterator closes the HTTP response; it never replays a partially transmitted inference request. ## Evaluate inference evidence ```python theme={"theme":{"light":"github-light-default","dark":"vesper"}} client.set_slo_policy( "qwen-prod", max_ttft_p95_ms=250, max_error_rate=0.01, ) recommendation = client.recommend("qwen-prod") history = client.recommendations("qwen-prod", limit=20) ``` The async client exposes the same SLO and recommendation methods. Recommendations are persisted, advisory decisions; these calls never create or resize provider resources. ## Errors | Error | Meaning | | -------------------- | ---------------------------------------------------------------------- | | `APIError` | Typed status, code, retryability, and remediation from the control API | | `OperationFailed` | Persisted durable operation reached `failed` | | `OperationCancelled` | Persisted operation reached `cancelled` | | `OperationTimeout` | This client stopped waiting; server-side work continues | | `StreamError` | Malformed or incomplete SSE stream | The generated low-level client is available as `client.api`. Generated files carry a do-not-edit header and are checked against [`openapi.json`](/control-api) during qualification. # RunPod Source: https://infercrane.mintlify.app/integrations/runpod Configure the RunPod elastic and provider-native Serverless adapter. # RunPod RunPod is one registered infrastructure adapter. Elastic deployments use SkyPilot to provision RunPod Pods; Serverless deployments use RunPod's native endpoint lifecycle. InferCrane's base production stack does not require RunPod—enable it explicitly with `compose.production.runpod.yaml`. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane doctor --cloud infercrane plan Qwen/Qwen3-8B --cloud runpod --gpu L40S infercrane deploy Qwen/Qwen3-8B \ --cloud runpod \ --gpu L40S \ --min 1 \ --max 4 ``` ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane doctor --serverless infercrane deploy Qwen/Qwen3-8B \ --compute serverless \ --cloud runpod \ --gpu L40S \ --max 4 ``` Both paths can create billable resources. Inspect existing pods and endpoints before retrying a provider operation, retain the original idempotency key, and verify provider inventory after deletion. See [provider setup](../provider-setup.md) for credentials and the [serverless lifecycle](../features/serverless.md) for worker-zero behavior. # External agent sandboxes Source: https://infercrane.mintlify.app/integrations/sandboxes Give an externally operated sandbox short-lived access to exactly one InferCrane endpoint without storing commands, files, prompts, or outputs. # Least-privilege inference for an agent sandbox Keep tool execution in E2B, Modal, Kubernetes, or another sandbox specialist. InferCrane records only the external sandbox identity and issues an expiring inference credential restricted to one stable endpoint. ```mermaid theme={"theme":{"light":"github-light-default","dark":"vesper"}} flowchart LR USER[Agent application] --> SB[External sandbox
isolation · files · commands] SB -->|short-lived endpoint token| IC[InferCrane
coder-production only] IC --> MODEL[Qualified serving plan] SB -. provider lifecycle .-> OWNER[Sandbox provider] ``` ## Issue access Create the sandbox with its native API or control plane first. Then connect its external identity: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane sandbox connect \ --provider e2b \ --external-id sandbox-01JCGW \ --external-revision template-v3 \ --endpoint coder-production \ --ttl 30m ``` The command prints the credential once. Inject it using the sandbox provider's secret mechanism: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} export INFERCRANE_URL="https://inference.example.com" export INFERCRANE_API_KEY="ic_...shown-once..." ``` Inside the sandbox, use an ordinary OpenAI client: ```python theme={"theme":{"light":"github-light-default","dark":"vesper"}} import os from openai import OpenAI client = OpenAI( base_url=os.environ["INFERCRANE_URL"].rstrip("/") + "/v1", api_key=os.environ["INFERCRANE_API_KEY"], ) result = client.responses.create( model="coder-production", input="Explain the failing test without modifying files.", ) print(result.output_text) ``` That token cannot enumerate or invoke a different endpoint alias, and it cannot call the InferCrane control API. ## Inspect, rotate, and revoke ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane sandbox list infercrane sandbox rotate SANDBOX_REFERENCE_ID infercrane sandbox revoke SANDBOX_REFERENCE_ID --yes ``` Rotation invalidates the previous credential. Revocation disables InferCrane access but does not delete, pause, snapshot, or mutate the external sandbox. The issuing control-plane instance refreshes its database-independent credential snapshot before it returns. In a horizontally scaled control plane, other gateway replicas converge on the persisted change on their bounded credential refresh interval (one second by default). Keep a retry for an initial `401` from a newly issued credential. Rotation and revocation may take that same bounded interval to reach every replica. InferCrane does not provide sandbox isolation and never stores sandbox commands, files, prompts, outputs, or provider credentials. Configure network policy, filesystem access, resource limits, and secret injection in the sandbox system that owns execution. ## Console workflow Open **Settings → Gateways, sandboxes, and training**. The console can issue, rotate, and revoke the same scoped credentials through the authenticated control API. Credentials are revealed only in the mutation response and are never persisted in browser-accessible storage. ## Local proof and real-system qualification Local black-box acceptance proves endpoint restriction, old-token invalidation, revocation, and the external-resource ownership boundary. It cannot prove a third-party sandbox's isolation, secret injection, network policy, or lifecycle semantics; qualify those with the chosen provider. # SGLang Source: https://infercrane.mintlify.app/integrations/sglang The second Runtime Contract V1 engine profile. # SGLang SGLang is InferCrane's second registered inference engine. The runtime profile pins the official `lmsysorg/sglang:v0.5.12` multi-platform manifest by digest and launches its OpenAI-compatible server through the same provider-neutral workload contract used by custom OCI images. The image tag and launch form follow the [official SGLang release and Docker documentation](https://github.com/sgl-project/sglang/releases/tag/v0.5.12). InferCrane resolved the manifest digest during implementation; the immutable value is visible through `infercrane integrations --output json` and the persisted revision. ```yaml theme={"theme":{"light":"github-light-default","dark":"vesper"}} name: qwen-sglang model: id: Qwen/Qwen3-8B runtime: engine: sglang version: 0.5.12 compute: mode: elastic provider: cloud: aws region: eu-central-1 resources: gpu: L40S scaling: min_replicas: 1 max_replicas: 1 routing: strategy: round-robin ``` The built-in profile declares the immutable image and argv, so normal users do not repeat them. It is simulated-qualified for readiness/model identity, buffered and streaming OpenAI transport, client cancellation, connection draining, the metrics endpoint and immutable launch intent. Real SGLang GPU behavior—including model compatibility, tool calling, structured output, performance and provider shutdown behavior—remains deferred until consolidated manual qualification. Autoscaling is rejected for SGLang because normalized SGLang scaling signals are not yet qualified. # Terraform provider Source: https://infercrane.mintlify.app/integrations/terraform Manage logical InferCrane deployments without transferring provider-resource ownership to Terraform. The Terraform provider manages `infercrane_deployment` through the control-plane API. InferCrane continues to own replicas, provider request identity, drain fencing, revisions, Release Guard, and cleanup. `infercrane_slo_policy` manages the deterministic policy used by `infercrane recommend`: ```hcl theme={"theme":{"light":"github-light-default","dark":"vesper"}} resource "infercrane_slo_policy" "qwen" { deployment = infercrane_deployment.qwen.name max_ttft_p95_ms = 250 max_error_rate = 0.01 min_output_tokens_second = 30 } ``` Destroying this resource deletes the policy but preserves benchmark and recommendation history. Recommendations remain an explicit evaluation rather than a Terraform apply. The provider is not yet published in the Terraform Registry. Local qualification builds it from `integrations/terraform`; registry installation begins only after release publication. ```hcl theme={"theme":{"light":"github-light-default","dark":"vesper"}} terraform { required_providers { infercrane = { source = "infercrane/infercrane" version = "2.0.0" } } } provider "infercrane" { endpoint = "https://infercrane.internal" # Prefer INFERCRANE_API_KEY; api_key is sensitive when set here. } resource "infercrane_deployment" "qwen" { name = "qwen-prod" model = "Qwen/Qwen3-8B" runtime = "vllm" cloud = "runpod" compute_mode = "elastic" gpu = "L40S" min_replicas = 1 max_replicas = 4 operation_timeout_seconds = 900 } ``` ## Lifecycle behavior | Terraform transition | InferCrane behavior | | -------------------- | ------------------------------------------------------------------------- | | Create | Submit one idempotent durable deployment operation and wait | | Read | Refresh logical state and active revision through the API | | Update | Candidate → provision → Release Guard → promote; a rejection fails safely | | Delete | Submit durable logical deletion and wait for fenced cleanup | | Import | `terraform import infercrane_deployment.qwen qwen-prod` | If Terraform is interrupted, InferCrane continues the operation. The next apply derives the same idempotency identity, adopts the original logical deployment, and resumes observation. Terraform state never stores a provider API key supplied through `INFERCRANE_API_KEY`, and it does not contain provider-owned replica identifiers as desired inputs. An update can remain unpromoted when Release Guard lacks sufficient evidence or rejects the candidate. Inspect the persisted reason with `infercrane rollout inspect qwen-prod`; Terraform does not bypass the guard to force convergence. # Training artifact handoffs Source: https://infercrane.mintlify.app/integrations/training-artifacts Attach signed, content-free lineage from an external training pipeline to one immutable InferCrane revision. # Bring trained artifacts into the release path InferCrane does not schedule training jobs. MLflow, Kubeflow, SkyPilot, a managed fine-tuning system, or your existing pipeline owns data, execution, and checkpoint storage. The pipeline hands InferCrane a signed immutable artifact identity for release qualification. ```mermaid theme={"theme":{"light":"github-light-default","dark":"vesper"}} flowchart LR DATA[Private training data] --> TRAIN[External training system] TRAIN --> CHECKPOINT[Immutable checkpoint] TRAIN --> SIGNED[Signed content-free handoff] SIGNED --> IC[InferCrane candidate revision] CHECKPOINT -. identity + digest .-> IC IC --> QUALIFY[Benchmark · Replay · quality evidence] QUALIFY --> GUARD[Release Guard] ``` ## Create a signing key Keep this key in the training system's secret manager: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane training keygen --file training-handoff.key ``` The private key file is created with mode `0600` and is never uploaded to InferCrane. ## Sign immutable provenance ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane training sign coder-runtime REVISION_ID \ --provider mlflow \ --run run-2026-08-14-42 \ --repository mlflow://registry/coder/42 \ --immutable-revision 42 \ --digest sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \ --base-model meta-llama/Llama-3.1-8B-Instruct@IMMUTABLE_COMMIT \ --method lora \ --framework transformers \ --framework-version 5.0.0 \ --key training-handoff.key \ --file coder-42.handoff.json ``` Use the checkpoint digest produced by your registry or artifact store. The handoff contains no dataset rows, prompts, outputs, logs, credentials, or checkpoint bytes. ## Verify and attach ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane training verify coder-42.handoff.json infercrane training attach coder-runtime coder-42.handoff.json infercrane training list coder-runtime ``` Attachment fails closed when: * the signature or payload was modified; * the path deployment does not match the signed deployment; * the revision belongs to another tenant or does not exist; * the revision already references a different immutable artifact; * the repository contains credentials, query parameters, or a mutable/unsafe location. ## Promotion remains separate Artifact provenance is not evidence that a candidate should receive traffic. Continue with: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane benchmark coder-runtime infercrane replay coder-runtime --candidate REVISION_ID infercrane evaluation attach coder-runtime --file quality-evidence.json infercrane rollout inspect coder-runtime ``` Release Guard decides from compatible persisted policy and evidence. An external training system never promotes a revision by merely attaching a checkpoint. ## Console workflow Workload detail displays signed training lineage and accepts an already signed handoff JSON file. Signing remains a CLI/CI operation so private training keys never enter browser code. # TypeScript SDK Source: https://infercrane.mintlify.app/integrations/typescript Typed durable operations and cancellation-aware inference streams for Node.js. The TypeScript SDK targets Node.js 20 or newer and uses the platform `fetch` implementation. It has no runtime dependency and calls only the InferCrane HTTP surfaces. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} cd sdk/typescript npm ci npm run build ``` `@infercrane/sdk` is repository-local during release-candidate qualification. Do not depend on an npm package until InferCrane publishes and signs it. ```typescript theme={"theme":{"light":"github-light-default","dark":"vesper"}} import { InferCrane } from '@infercrane/sdk'; const client = new InferCrane({ apiKey: process.env.INFERCRANE_API_KEY!, baseUrl: 'https://infercrane.internal', }); const operation = await client.deploy({ name: 'qwen-prod', model: 'Qwen/Qwen3-8B', cloud: 'runpod', gpu: 'L40S', idempotencyKey: 'qwen-prod-initial', }); await client.wait(operation.id, { timeoutMs: 900_000 }); ``` `wait` accepts an `AbortSignal`. Aborting the local wait does not cancel the durable operation. Call `client.cancel(operation.id)` only when cooperative server-side cancellation is intentional. ```typescript theme={"theme":{"light":"github-light-default","dark":"vesper"}} const controller = new AbortController(); for await (const event of client.streamChat( 'qwen-prod', [{ role: 'user', content: 'Explain this rollout.' }], { signal: controller.signal }, )) { console.log(event); } ``` The SDK verifies HTTP status before decoding, exposes `ApiError`, `OperationFailed`, `OperationCancelled`, `OperationTimeout`, and `StreamError`, and never retries a streaming request after transmission begins. ## Evaluate inference evidence ```typescript theme={"theme":{"light":"github-light-default","dark":"vesper"}} await client.setSloPolicy('qwen-prod', { max_ttft_p95_ms: 250, max_error_rate: 0.01, }); const recommendation = await client.recommend('qwen-prod'); const history = await client.recommendations('qwen-prod', 20); ``` SLO thresholds are validated before transmission. These methods persist and inspect deterministic, advisory decisions; they do not apply a candidate configuration automatically. # vLLM Source: https://infercrane.mintlify.app/integrations/vllm How InferCrane manages and routes requests to vLLM runtimes. # vLLM vLLM is InferCrane's default qualified runtime profile. InferCrane owns deployment state and lifecycle; vLLM owns model execution. A supervised [vLLM Router](https://github.com/vllm-project/semantic-router) process distributes requests across healthy standalone replicas. ## Connect existing workers Each worker must expose the OpenAI-compatible vLLM API and be reachable from the InferCrane gateway. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane target add gpu-a \ --url http://gpu-a:8000 \ --runtime vllm \ --upstream-model Qwen/Qwen3-8B infercrane apply Qwen/Qwen3-8B \ --name qwen-prod \ --targets gpu-a \ --idempotency-key qwen-prod-initial \ --wait ``` The reconciler verifies health and served-model identity before publishing a route. An unhealthy or mismatched worker does not enter the request path. ## Responsibility boundary | InferCrane | vLLM | | ------------------------------------- | ----------------------------- | | Desired and observed deployment state | Model loading and execution | | Durable operations and revisions | OpenAI-compatible worker API | | Health/model reconciliation | Token generation and KV cache | | Safe routing generations | Per-replica runtime metrics | InferCrane does not implement an inference engine or distributed KV cache. SGLang and custom OCI workloads use the same versioned runtime boundary and have independent qualification states. Follow an OpenAI request from alias resolution to a healthy vLLM replica. # Capability status Source: https://infercrane.mintlify.app/project-status The authoritative implementation and qualification state of every InferCrane capability. # Project status Status labels are strict: **implemented** is tested in this repository; **local-qualified** has passed the maintained hermetic/local gates; **in qualification** has an implemented surface with incomplete release evidence; **experimental** works but lacks production qualification; **planned** is not a product capability. None of these labels substitutes for real-provider evidence where the behavior depends on external infrastructure. | Capability | Status | Notes | | --------------------------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Inference project workflow | Local-qualified | `workload init`, `validate`, `build`, `dev`, `plan`, and `deploy` share one schema-backed project; remote deployment requires an immutable pushed image digest. Real registry and GPU qualification remain external. | | Unified operations observation | Local-qualified | `inbox` deterministically ranks tenant-scoped persisted fleet attention and fails closed on partial inventory; `observe` joins one deployment or endpoint's state, traffic, operations, Release Guard, policy, and events. `--diagnose` remains the explicit persisted-diagnosis boundary. | | Safe environment promotion | Local-qualified | Promotion is plan-first and atomically stages a source serving plan as the destination candidate; it never activates traffic, requires the same logical model, and remains subject to Release Guard. | | Signed semantic evaluation evidence | Local-qualified | A strict evaluator-neutral result contract lets CI, Ragas, DeepEval, or custom suites produce aggregate evidence; `evaluation ingest` rejects unknown content fields, binds the result to an immutable revision, signs it, and optionally attaches it. Incompatible evidence fails closed and promotion remains a deterministic policy decision. External evaluator quality and key custody remain user responsibilities. | | Artifact cache operations | Local-qualified | Inspect, observe, and prefetch-intent workflows separate requested cache work from fresh provider observation; only observation proves availability. Real provider cache qualification remains external. | | Read-only MCP operations server | Local-qualified | The stdio server exposes closed-world inspection tools for deployments, endpoints, requests, operations, and curated recipes; it intentionally exposes no mutation tools. Client-specific interoperability remains externally qualified. | | Curated configuration recipes | Local-qualified | Maintained recipes pin model commits and licenses and can initialize projects; recipes are configuration evidence, not performance claims. | | Side-effect-free deployment planning | Implemented | Deterministic human and JSON output makes unknown capacity, cache locality, startup timing, and live cost explicit instead of fabricating estimates. | | Hermetic product proof | Local-qualified | `make demo` proves adoption, a proxied request, Request Inspector, Doctor, immutable candidate creation, deterministic Release Guard rejection, active-revision preservation, candidate cleanup, and isolated teardown without provider or GPU mutation. | | CLI discovery and contexts | Implemented | Cobra grouped help, suggestions, generated completion, named contexts, authenticated identity, and durable timeline following are wired. | | Terminal operations workspace | Experimental | Responsive evidence views and state-valid guarded actions use authenticated APIs and durable operations; `--read-only` disables mutations, and broader terminal compatibility qualification remains. | | Separate operations console | Private preview | Endpoint-first views, content-free monitoring with lifecycle overlays, durable operations, Request Inspector, Doctor, Release Guard, signed alerts, sourced FinOps and quality evidence, API-key/team management, encrypted local sessions, hosted identity boundaries, explicit partial states, responsive Playwright and accessibility tests pass locally; hosted deployment remains private. | | Environment diagnostics | Implemented | Read-only checks for API auth, PostgreSQL, vLLM Router, SkyPilot/RunPod, Serverless, AWS role assumption, and Kubernetes API/RBAC. | | Declarative existing-target apply | Implemented | Atomic convergence of routing, replica bounds, and target membership. | | Durable lifecycle operations | Implemented | Idempotency, progress, retry classification, and cooperative cancellation state. | | Leased operation execution engine | Experimental | Existing-target, elastic, revision, scale, delete, and serverless handlers resume from durable state; real provider restart qualification remains. | | Versioned control-plane API | Experimental | Tenant-scoped operations, apply, targets, deployments, orphans, audit, quota, and principal endpoints exist. | | OpenAPI and generated SDKs | Experimental | Full route coverage, deterministic Python/TypeScript low-level generation, typed durable helpers, and hermetic SSE tests are implemented; public package publication is deferred. | | Terraform provider | Experimental | Logical deployment CRUD, import, guarded update, and interrupted-apply adoption pass real Terraform protocol fixtures; Registry publication is deferred. | | GitHub delivery action | Experimental | Read-only semantic PR plans, explicit protected apply, exact-revision plus verified-passport checks, bounded summaries, and secret redaction are implemented; Marketplace publication is deferred. | | Production configuration gates | Implemented | Production mode enforces strong API secrets and PostgreSQL TLS; the base Compose stack is provider-neutral and RunPod, AWS, and Kubernetes use explicit overlays. | | Safe deletion and orphan discovery | Implemented | Side-effect-free deletion plans, explicit confirmation, and provisioned-resource inventory. | | PostgreSQL control-plane state | Implemented | Transactional advisory-locked migrations, checksum/gap/newer-binary rejection, every-prefix upgrade coverage, concurrent-start serialization, and bounded pool. | | Control-plane HA and recovery | Local-qualified | Stateless replicas, fenced work reclaim, protocol-overlap admission, TLS 1.3/mTLS, guarded backup/restore, and restored-database startup pass local Docker drills; customer database topology and RTO/RPO remain external. | | Release packaging | Implemented | Exact-version darwin/linux amd64/arm64 archives, checksums, SPDX SBOMs, native smoke verification, and generated Homebrew formula run locally without publication. | | Existing vLLM target registration | Implemented | Persistent, idempotent registration. | | Logical deployments and aliases | Implemented | One common upstream model per deployment. | | Stable endpoint domain | Local-qualified | Logical models, environments, immutable serving plans, lifecycle-managed deployment bindings, route generation pinning, legacy alias backfill, and deterministic endpoint Release Guard pass local clean-tree gates. | | Incremental adoption and diagnostics | Local-qualified | Observe-only and traffic-managed adoption, content-free request inspection, deterministic Doctor findings, and bounded signed webhook alerts pass clean-tree gates. Real external workloads remain deferred to consolidated manual qualification. | | Capability-qualified inference protocols | Local-qualified | Chat, Completions, Embeddings, Responses, and online chat-batch paths are independently gated and faithfully proxied. The pinned vLLM profile locally qualifies Chat, Completions, and model-dependent Embeddings; Responses and online batch require a newer explicitly qualified runtime profile. | | OpenAI-compatible chat proxy | Implemented | Streaming, auth, alias rewrite, request accounting. | | vLLM health and model reconciliation | Implemented | Bounded concurrent probes. | | Supervised vLLM Router processes | Implemented | Instance-owned generations and deterministic ports. | | Prometheus gateway telemetry | Implemented | Core counters/gauges; expand before public SLOs. | | Prometheus latency histograms and alerts | Implemented | Baseline rules require workload-specific tuning. | | Reproducible benchmark and recovery tooling | Experimental | AIPerf execution and benchmark history are implemented; local control-plane HA/restore is qualified while real GPU and customer PostgreSQL evidence remain external. | | Model Recipes and Inference Lab | Local-qualified | Immutable artifact/revision/AIPerf recipes and tenant-scoped measured comparisons are implemented; public registry and real GPU catalog evidence are deferred. | | Inference Replay and Capacity Intelligence | In qualification | Content-free workload-shape capture, explicit AIPerf approximation, bounded cache observations, delegated prefetch intents, and tenant-scoped capacity evidence are implemented; real-provider evidence remains deferred. | | FinOps and advisory Autopilot | In qualification | Sourced cost reports and immutable human-approved recommendation plans are implemented; savings remain unavailable without direct evidence and approval never mutates production. | | Context Passport and Burst Guard | In qualification | Bounded logical session identity, reliability-first affinity fallback, delegated request-survival contracts, and fresh hard-cost-bounded overflow decisions are implemented; real backend migration remains deferred. | | Provider pricing contract | Implemented | Timestamp and staleness semantics; no live provider catalog is shipped. | | Bounded autoscaling controller | Experimental | Durable fleet scaling and router-fenced scale-down are enabled; real RunPod 1→N→1 acceptance remains. | | Immutable ModelArtifact identity | Experimental | Hugging Face references resolve to immutable commits with grounded metadata; real transfer/cache evidence remains. | | Release Guard V2 | Experimental | Compatibility, explicit bounded AIPerf, performance, error, sourced-cost policy, persisted post-promotion monitoring, and restart-safe automatic rollback pass hermetic tests; real active/candidate evidence remains. | | Inference Passports | Experimental | Canonical Ed25519-signed revision, artifact, benchmark, cold-start and policy evidence is byte-preserving, tenant-safe, and offline-verifiable; organizational key custody and public release qualification remain. | | Provider-native serverless contract | Experimental | Replay-safe endpoint lifecycle, scale-to-zero routing, cancellation, accounting, and registered direct-target reconciliation are implemented. RunPod is the first adapter; real cold/warm acceptance remains. | | Cold-start intelligence | Experimental | Grounded worker-at-arrival and gateway TTFT evidence persist; provider-hidden substages remain unavailable. | | Deterministic explanations | Implemented | Deployment, scaling, rollout, and cold-start output is reproduced from persisted state and measurements. | | Integration registration and qualification | Implemented | Lifecycle backends resolve by cloud/runtime and durable adapter identity; the release qualification matrix remains separate. | | Versioned provider/runtime contract inventory | Experimental | V1 descriptors, validated executable bindings, capabilities, authenticated inspection, and hermetic conformance evidence are implemented; real-provider/runtime qualification remains deferred. | | Portable custom OCI workloads | Experimental | Immutable digest, argv, OpenAI protocol, standard probes, cancellation/drain and shutdown declarations persist in revisions and pass hermetic launch conformance; real GPU evidence is deferred. | | SGLang runtime profile | Experimental | Official v0.5.12 image manifest is digest-pinned and hermetic fixtures exercise Runtime Contract V1 on the AWS EC2 elastic adapter; real GPU and feature-level compatibility evidence is deferred. | | Tiered developer qualification | Implemented | Fast provider contracts, isolated Docker recovery checks, coverage-guided fuzzing, shuffled race soak, a three-version Kind matrix, KWOK fleet simulation, paid-run locking, and commit-bound CI evidence separate local correctness from real-cloud qualification. | | Capacity and runtime adapter contracts | Experimental | GPU/cache-aware deterministic placement exists; adapters are registered independently for RunPod, AWS EC2, Kubernetes, governed external targets, vLLM, SGLang, and custom OCI with explicit qualification states. | | Provider capacity preflight | Experimental | Optional provider advisors persist available/constrained/unavailable/unknown evidence; RunPod secure-GPU stock is the first read-only implementation. | | Inference decisions and SLO policy | Experimental | Versioned deterministic recommendations persist canonical benchmark provenance, exact compatibility, missing signals and sourced cost constraints; autonomous apply is excluded. | | Scoped tenant identity and RBAC | Experimental | Role-bounded service-account scopes, hashed rotation/revocation credentials, audit attribution, and adversarial tenant isolation are wired. | | Distributed request-rate quotas | Implemented | PostgreSQL reserves aggregate UTC-minute leases; gateways authorize from memory and fail closed without adding database reads to the inference path. | | Reference-only secrets | Experimental | Environment references persist without values; additional production secret-manager resolvers remain planned. | | Governed external capacity | Experimental | Explicit health/queue overflow, hysteresis, cooldown, privacy acknowledgement, atomic request/cost reservations, OpenRouter, and no-replay streaming behavior are hermetically qualified; real billing evidence is deferred. | | Managed external endpoint bindings | Local-qualified | Authenticated OpenRouter and generic OpenAI-compatible targets can participate in immutable endpoint plans with reference-only credentials, explicit consent, hard request/cost reservations, no replay, and candidate-only console staging. Real provider billing/protocol evidence remains deferred. | | LiteLLM gateway composition | Local-qualified | Existing LiteLLM OpenAI-compatible surfaces can be discovered and adopted without bundling or managing LiteLLM. InferCrane owns stable endpoint identity and evidence; real LiteLLM/plugin/provider combinations remain externally qualified. | | External sandbox access | Local-qualified | Externally owned sandboxes can receive expiring credentials restricted to one endpoint. Rotation, revocation, control-API denial, alias filtering, and content-free persistence pass local black-box and adversarial tests; sandbox isolation and lifecycle remain external. | | Signed training artifact handoff | Local-qualified | Ed25519-verified, content-free provenance binds one immutable external checkpoint to one tenant-scoped deployment revision. Training execution and registry availability remain external; promotion still requires compatible release evidence. | | AWS EC2 BYOC | Experimental | Private-network, role-assumed, tag-owned, immutable-image elastic lifecycle passes Provider Contract V1 hermetically; real AWS evidence is deferred. | | GCP Compute BYOC | Experimental | Private-network, attached-identity, label-owned, immutable-image lifecycle passes hermetic adapter tests; real GCP GPU evidence is deferred. | | Managed provider profiles | Planned | AWS ASG/EKS/SageMaker/Bedrock, GCP MIG/GKE/Vertex, and CoreWeave CKS have explicit ownership/capability boundaries but are not executable or locally qualified. | | Kubernetes elastic | Experimental | Namespace-scoped Deployment/Service and optional standard KServe ownership pass hermetic and Kind lifecycle gates; real Kubernetes GPU/runtime evidence is deferred. | | SkyPilot RunPod provisioning | Experimental | Requires credentialed elastic lifecycle acceptance and soak tests. | | Production performance claims | Planned | Must be backed by reproducible real-vLLM benchmarks. | Update this table whenever a feature changes maturity. Never describe planned behavior in present tense elsewhere in the documentation. # Provider setup Source: https://infercrane.mintlify.app/provider-setup Configure credentials and prerequisites for qualified infrastructure adapters. # Provider setup Provider integrations are registered control-plane adapters. Each provider owns its credentials, infrastructure semantics, and billable resources; InferCrane owns durable intent, reconciliation, and cleanup. A provider is supported only after its adapter combination appears in the release qualification matrix. ## RunPod Set a scoped `RUNPOD_API_KEY` on the control plane and configure SkyPilot's RunPod credentials for elastic workers. Run `infercrane doctor --cloud` before provisioning. For Serverless, create a RunPod vLLM template with `MODEL_NAME`, immutable `MODEL_REVISION`, and `RAW_OPENAI_OUTPUT=1`, then set `INFERCRANE_RUNPOD_SERVERLESS_TEMPLATE_ID`. `infercrane doctor --serverless` reads and validates the template without creating an endpoint. Set `INFERCRANE_URL` to a URL reachable from AIPerf and clients. Keep provider and InferCrane credentials out of specifications, logs, issue reports, and benchmark artifacts. Always inspect existing pods/endpoints before retrying manual acceptance and delete paid resources after the test. ## AWS EC2 BYOC AWS elastic support uses a separately registered EC2 adapter rather than provider conditionals in the lifecycle engine. It requires a complete role, private network, AMI, instance profile, worker secret, instance type/GPU, region, and immutable image configuration. See [AWS EC2 BYOC](/integrations/aws-ec2) and run `infercrane doctor --aws` before provisioning. ASG, EKS, SageMaker, and Bedrock have separate registered profiles. Registration documents their ownership boundary; it is not executable qualification. Inspect `infercrane integrations`. ## GCP Compute BYOC The `gcp-compute` adapter launches private, digest-pinned workers with an attached service account and deterministic adoption identity. Configuration is all-or-nothing. See [GCP Compute BYOC](/integrations/gcp-compute). MIG, GKE, and Vertex remain separate registered, deferred profiles rather than implicit aliases. Run `infercrane doctor --gcp` before provisioning; it performs only identity and Compute API reads. ## CoreWeave The `coreweave-cks` profile is CKS-first: InferCrane reuses its namespaced Kubernetes lifecycle and does not install or own the provider-managed GPU operator. The profile is registered but not yet executable or locally qualified; real CKS qualification remains deferred. ## Kubernetes The Kubernetes adapter uses an explicit kubeconfig context, one namespace, an immutable default runtime image, and a worker Secret reference. It owns a bounded Deployment/Service set or one optional KServe InferenceService. Apply the reviewed namespace and RBAC manifests, then run `infercrane doctor --kubernetes`. See [Kubernetes](/integrations/kubernetes) for exact configuration, security boundaries, local Kind qualification, and current real-GPU limitations. # Quickstart Source: https://infercrane.mintlify.app/quickstart Run InferCrane locally and send an OpenAI-compatible request in under five minutes. # Your first InferCrane request In this guide you will start the complete control and request path, call a stable model endpoint, and inspect the durable state behind it. No GPU or cloud account is required. The local stack uses GPU-free fake vLLM workers. It proves application and lifecycle behavior, not model quality, GPU performance, or real-provider compatibility. ## See the complete safety loop first From a repository checkout, one command runs the local product proof and cleans up its isolated Docker project: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} make demo ``` It connects an existing endpoint, sends and inspects a request, creates an intentionally unready candidate without provisioning it, records a deterministic Release Guard rejection, verifies the active revision did not change, rejects the candidate, and removes all temporary state. The output is explicitly marked as fixture evidence; it does not claim GPU or provider qualification. ## Prerequisites * Git * Docker with Compose v2 * Port `18000` available ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} git clone https://github.com/infercrane/infercrane.git cd infercrane ``` ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} docker compose up --build -d curl -fsS http://127.0.0.1:18000/readyz ``` The stack includes PostgreSQL, InferCrane, two fake workers, and a development router. The development API key is `infercrane`; production mode rejects that default. ```bash InferCrane CLI theme={"theme":{"light":"github-light-default","dark":"vesper"}} docker compose exec infercrane \ infercrane request qwen-prod --message "Explain durable operations in one sentence." ``` ```bash cURL theme={"theme":{"light":"github-light-default","dark":"vesper"}} curl -fsS http://127.0.0.1:18000/v1/chat/completions \ -H 'Authorization: Bearer infercrane' \ -H 'Content-Type: application/json' \ -d '{ "model": "qwen-prod", "messages": [{"role": "user", "content": "Hello"}] }' ``` ```python Python theme={"theme":{"light":"github-light-default","dark":"vesper"}} from openai import OpenAI client = OpenAI( base_url="http://127.0.0.1:18000/v1", api_key="infercrane", ) response = client.chat.completions.create( model="qwen-prod", messages=[{"role": "user", "content": "Hello"}], ) print(response.choices[0].message.content) ``` ```typescript TypeScript theme={"theme":{"light":"github-light-default","dark":"vesper"}} import OpenAI from "openai"; const client = new OpenAI({ baseURL: "http://127.0.0.1:18000/v1", apiKey: "infercrane", }); const response = await client.chat.completions.create({ model: "qwen-prod", messages: [{ role: "user", content: "Hello" }], }); console.log(response.choices[0].message.content); ``` Add `--stream` to the CLI request to print response text as chunks arrive. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} docker compose exec infercrane infercrane status qwen-prod docker compose exec infercrane infercrane events qwen-prod docker compose exec infercrane infercrane explain qwen-prod ``` These commands use the authenticated control-plane API. Public CLI workflows never connect directly to PostgreSQL. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} docker compose exec infercrane infercrane ui ``` The terminal workspace reads the same durable control API and can be closed without cancelling operations. The separately released browser console is currently in private preview; see [Operations console](/features/dashboard) for the local self-hosted boundary. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} docker compose down ``` This preserves PostgreSQL data. Add `--volumes` only when you intend to delete the local state. ## Choose your next path Plan provider and runtime choices before creating billable capacity. Observe an existing vLLM, LiteLLM, or OpenAI-compatible endpoint first. Learn endpoints, environments, serving plans, deployments, and revisions. ## Before creating real infrastructure The Homebrew formula and release archives are prepared but not yet publicly released. Until the release package is published, build the CLI from source: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} go build -o ./bin/infercrane ./cmd/infercrane export INFERCRANE_API_KEY='ISSUED_CONTROL_PLANE_CREDENTIAL' ./bin/infercrane init --url https://infercrane.example ./bin/infercrane auth status ./bin/infercrane doctor --cloud ./bin/infercrane plan Qwen/Qwen3-8B --cloud runpod --gpu L40S ``` `plan` is side-effect free. A real `deploy` can create billable resources, so check [provider setup](/provider-setup) and the [capability matrix](/project-status) first. Adapter registration does not prove that an exact model, runtime, GPU, and provider combination has passed real-infrastructure qualification. # Roadmap Source: https://infercrane.mintlify.app/roadmap InferCrane's product direction, priorities, and explicit non-goals. # Build trust before automation InferCrane's direction is to become the trusted decision and operations layer between AI applications and heterogeneous inference capacity. The roadmap is ordered around user trust, not the number of integrations in a logo grid. This page describes direction, not a delivery promise. Current capability and qualification status lives in [Project status](/project-status). ## Now — prove the production core * Complete real-provider and real-runtime qualification for the current release. * Keep one stable endpoint identity across customer-operated workers and explicitly budgeted managed model APIs; credentials remain server-side references and new bindings begin as candidates. * Make build, connect, update, rollback, autoscaling, serverless, and deletion boring and recoverable. * Publish reproducible model/runtime/GPU evidence instead of unsupported performance claims. * Tighten the five-minute path from installation to a successful request. ## Next — broaden adoption safely * Make development, staging, and production promotion explicit and reproducible. * Qualify additional provider and runtime combinations through stable contracts. * Improve private networking, workload identity, HA, backup/restore, and upgrade evidence. * Turn Request Inspector, Doctor, alerts, and FinOps evidence into a daily operator workflow. * Expand verified recipes and Inference Lab with measured, reproducible results. ## Later — decision intelligence * Replay privacy-preserving production workload shape against candidate serving plans. * Learn provider capacity and cold-start reliability from grounded observations. * Recommend model/runtime/GPU/provider plans with measured, modeled, and heuristic evidence clearly separated. * Verify recommendations through benchmark, Release Guard, human approval, and post-change results. * Explore policy-bounded automation only after recommendations repeatedly predict reality. ## Dependency order toward end-to-end inference operations InferCrane expands around one control loop rather than accumulating unrelated infrastructure: 1. **Serve:** build or connect a workload, then expose one stable endpoint. 2. **Govern:** admission, quotas, referenced credentials, budgets, private networking, and identity. 3. **Observe:** request evidence, deterministic Doctor findings, alerts, cold starts, and cost. 4. **Change safely:** immutable candidates, replay or benchmark evidence, Release Guard, and rollback. 5. **Optimize:** artifact prewarming, capacity history, Inference Lab, and advisory recommendations. 6. **Expand by adapters:** runtimes, clouds, external APIs, sandbox access, and training lineage stay behind narrow contracts. Sandbox execution and training orchestration are not part of the current release. InferCrane now tracks external sandbox identity plus endpoint-scoped access and verifies signed training artifact handoffs while delegating isolation and training execution to qualified systems. Managed compute remains demand-gated because it adds billing, abuse, capacity, and support obligations—not just another adapter. ## Explicit non-goals InferCrane will not become another inference engine, GPU scheduler, distributed KV cache, generic router, cloud-provisioning framework, workflow engine, agent framework, or sandbox isolation runtime. Those systems remain replaceable integrations. InferCrane owns lifecycle, policy, evidence, and decision semantics. ## How priorities are chosen A roadmap item moves forward when it does at least one of the following: 1. Reduces time from model or existing endpoint to dependable production service. 2. Prevents an outage, leaked resource, unsafe rollout, privacy violation, or unbounded spend. 3. Produces trustworthy evidence for a decision operators currently make by guesswork. 4. Proves provider/runtime modularity without weakening the core domain model. 5. Creates repeat daily value rather than a deployment command used once. Public milestones are intentionally outcome-oriented. Engineering checkpoint history, ADRs, and release qualification procedures remain in the repository for contributors without occupying the primary user documentation navigation. # PostgreSQL backup and restore Source: https://infercrane.mintlify.app/runbooks/backup-restore Back up control-plane state, restore into a safe target, and reconcile external resources. # PostgreSQL backup and restore drill Set a TLS-protected `INFERCRANE_DATABASE_URL`, then create and validate a custom-format backup: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} scripts/backup-postgres.sh infercrane-$(date +%Y%m%d).dump ``` Restore only into a verified empty or disposable target first: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} export INFERCRANE_ALLOW_RESTORE=yes export INFERCRANE_RESTORE_TARGET_DATABASE=infercrane_restore_drill scripts/restore-postgres.sh infercrane-20260809.dump ``` Restart InferCrane, check `/readyz`, list deployments, send an inference request, and compare row counts and recent audit/operation events. The restore refuses a target-name mismatch or a database with live control-plane heartbeats. Record recovery-point and recovery-time measurements in the release evidence. Never test destructive restore behavior against the only production copy. Set an operational backup schedule from the required recovery point objective (RPO); InferCrane does not silently choose one. Measure restore plus reconciliation against the recovery time objective (RTO). A database restore is incomplete until owned external resources have been inventoried and reconciled without duplicate mutation. # Security Source: https://infercrane.mintlify.app/security Authentication, tenant isolation, secret references, network boundaries, and secure deployment guidance. # Security InferCrane authenticates the control and data planes with bearer credentials and tenant-scopes public API reads and writes. Use separate, least-privilege provider credentials and rotate them through your secret manager. Production PostgreSQL must use TLS; back up and restore it as the lifecycle source of truth. The identity boundary is a tenant. Principals are service accounts with a role ceiling and explicit action scopes. A scope can remove a role permission but cannot add one. Credentials are shown once, stored only as SHA-256 digests, and support rotation and revocation. Existing legacy principals are migrated to their previous explicit action set; new secret and external-capacity permissions are never granted implicitly during upgrade. Gateway authentication uses an in-memory last-known-good credential snapshot so an established data plane does not add PostgreSQL latency or fail immediately during a database outage. Rotation and revocation take effect on the next successful snapshot refresh. If immediate revocation is required while PostgreSQL is unreachable, restore authoritative database access or fence/restart the affected gateway instances; InferCrane cannot infer a revocation it cannot read. Secret objects are references, not a secret store. For example: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} export OPENROUTER_API_KEY='...' infercrane secret create openrouter --from-env OPENROUTER_API_KEY ``` PostgreSQL stores the resolver (`env`) and reference (`OPENROUTER_API_KEY`), never the environment value. Resolved values stay in process memory and are excluded from API responses, logs, audit payloads and qualification evidence. Operators should inject referenced variables from their existing secret manager and restrict the control-plane process environment. Prompt and output content are not recorded by default. Request telemetry stores identifiers, dimensions, status, timing, and token counts. AIPerf uses metrics-only record exports; InferCrane does not upload benchmark data. Shadow traffic is not implemented, so requests are never duplicated silently. Durable async inference is the explicit exception. It remains disabled until an operator injects `INFERCRANE_ASYNC_ENCRYPTION_KEY`, and every submission must acknowledge encrypted content storage. Request and result bodies are stored only as AES-256-GCM ciphertext bound to tenant and job identity. Completion webhooks are signed, HTTPS-only, redirect-free and resolved through an SSRF-hardened transport. Webhook payloads contain results, so their destinations are part of the application data boundary. Synchronous inference remains content-free by default. External fallback is disabled by default. Enabling it requires a persisted acknowledgement that prompt and output data can leave controlled infrastructure, plus atomic hard request and worst-case cost reservations. Selection happens before transmission; InferCrane does not replay a stream or retry after bytes may have reached an external provider. AWS BYOC uses STS role assumption for each provider call and passes temporary credentials only to the child AWS CLI process. EC2 receives no public IP. The worker retrieves its API key from AWS Secrets Manager through a narrowly scoped instance profile; the control plane stores the secret ARN, not the value. Require an external ID, restrict trust and permissions, and use tag conditions in production. The Kubernetes adapter always uses an explicit context and namespace. Its reference Role contains no wildcards and cannot read Secrets, mutate RBAC, or create Pods directly. Workers read one named Secret through their service account; the control plane stores only its name and key. Strict server-side apply preserves field ownership and never force-steals conflicts. InferCrane deletes only exact names with matching durable ownership labels and annotations. Run the container as its non-root user, pin immutable image tags, restrict network access, and protect `/metrics` according to your environment. Report vulnerabilities privately as described in the repository [security policy](https://github.com/infercrane/infercrane/blob/main/SECURITY.md). # Build your inference deployment Source: https://infercrane.mintlify.app/showcase/build-inference Go from a model or immutable OCI workload to a durable, OpenAI-compatible endpoint. # A model is enough to start InferCrane turns a model reference and a serving plan into a durable deployment. The CLI submits the intent to the control plane and can disconnect safely while provider allocation, artifact transfer, runtime startup, readiness, and route publication continue. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane deploy Qwen/Qwen3-8B ``` Qwen3-8B is intentionally used as the release acceptance baseline: it is small enough for frequent single-GPU qualification and exercises the production lifecycle without making every test unusually expensive. It is not embedded in the InferCrane domain model. ## Use the model your workload needs The same model-to-endpoint path accepts other Hugging Face repository identities. These examples show portable input syntax; they do **not** claim that every model fits every GPU or that every adapter has been production-qualified for it. ```bash Qwen theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane plan Qwen/Qwen3-8B --cloud runpod --gpu L40S ``` ```bash Meta Llama theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane plan meta-llama/Llama-4-Scout-17B-16E-Instruct \ --cloud aws \ --gpu H100 ``` ```bash Google Gemma theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane plan google/gemma-3-4b-it \ --cloud runpod \ --gpu L40S ``` ```bash Moonshot Kimi theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane plan moonshotai/Kimi-K2-Instruct \ --cloud aws \ --gpu H100 ``` `plan` validates InferCrane's serving intent without creating resources. Before `deploy`, confirm the model card license or access grant, total and active parameter memory, quantization, tensor-parallel topology, runtime version, multimodal requirements, and provider capacity. Large MoE models such as Llama 4 and Kimi generally require materially different topology from an 8B dense model; the example GPU flag alone is not a sizing recommendation. | Example family | Why teams use it | Qualification concern | | -------------- | -------------------------------------------------------- | ----------------------------------------------------------------------- | | Qwen | Compact general and coding deployments | Exact chat template, tool calling, and quantization | | Meta Llama | Broad ecosystem and open-weight deployment | Meta license/access and multi-GPU topology for larger variants | | Google Gemma | Small-to-large open-weight family | Google terms, multimodal/runtime support, and artifact access | | Moonshot Kimi | Long-context, reasoning, coding, and multimodal variants | Very large MoE topology and version-specific runtime requirements | | Your fine-tune | Private or domain-specific behavior | Immutable artifact commit, tokenizer compatibility, and registry access | Model popularity changes faster than InferCrane releases. The source of truth is the immutable model artifact and the evidence attached to its serving plan—not a marketing list of “supported models.” The short path uses configured defaults. Make infrastructure choices explicit when you need them: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane plan Qwen/Qwen3-8B \ --cloud runpod \ --gpu L40S \ --min 1 \ --max 4 infercrane deploy Qwen/Qwen3-8B \ --cloud runpod \ --gpu L40S \ --min 1 \ --max 4 ``` `plan` is side-effect free. `deploy` returns a durable operation unless `--wait` is supplied. Closing the terminal stops only the local watch; use the returned operation ID to reconnect: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane operation watch OPERATION_ID infercrane status qwen3-8b infercrane events qwen3-8b ``` RunPod is one currently qualified adapter, not the InferCrane domain model. AWS BYOC, Kubernetes, existing targets, and future providers implement the same provider contract with independent qualification evidence. Check the [capability matrix](/project-status) before selecting a backend. ## Bring an immutable runtime when a model flag is not enough For a qualified custom runtime, describe the OCI image, digest, startup contract, health contract, and protocol capabilities in a DeploymentSpec. InferCrane persists that configuration as an immutable revision and manages its lifecycle; it does not build images or execute arbitrary build scripts. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane plan deployment.yaml infercrane apply deployment.yaml --idempotency-key release-2026-08-12 ``` See [Custom OCI workloads](/features/custom-oci) for the exact schema and safety requirements. ## What “build” means here | InferCrane owns | Existing tools keep owning | | --------------------------------------------------- | ---------------------------------- | | Serving intent and stable endpoint identity | Model implementation | | Provider and runtime adapter selection | Container registry and image build | | Durable create, update, rollback, scale, and delete | CUDA/runtime internals | | Immutable revisions and artifact identity | Inference engine execution | | Readiness, routing, telemetry, and policy evidence | Provider infrastructure primitives | This boundary keeps the product extensible: vLLM, SGLang, a custom OCI runtime, or another qualified runtime can change without changing the application-facing endpoint. ## Separate development, staging, and production Environments are first-class, tenant-scoped resources. Bind separate stable endpoints to the same logical model so application configuration and policy do not leak across stages: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane environment create development infercrane environment create staging infercrane environment create production infercrane logical-model create coder --description "Stable coding model" infercrane endpoint create coder-development --model coder --environment development infercrane endpoint create coder-staging --model coder --environment staging infercrane endpoint create coder-production --model coder --environment production ``` Each endpoint has independent active and candidate serving plans. Request records preserve logical model, endpoint, and environment identity. Stage the exact serving plan from staging as a production candidate without changing production traffic: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane environment promote coder-staging --to coder-production infercrane environment promote coder-staging --to coder-production --yes ``` The first command is a side-effect-free plan. The second atomically clones destination-scoped bindings and stages an immutable candidate. Production Release Guard remains the authority for activation. See [Environment promotion](/features/environment-promotion). ## Make the next revision safely Use the same declarative path for updates: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane plan deployment-v2.yaml infercrane apply deployment-v2.yaml --idempotency-key release-2026-08-13 infercrane rollout inspect qwen-prod ``` InferCrane creates an immutable candidate and preserves the active revision until promotion policy is satisfied. Continue with the [safe rollout showcase](/showcase/safe-rollouts). # Operate through slow and uncertain capacity Source: https://infercrane.mintlify.app/showcase/capacity-evidence Resume durable deployment work, explain cold starts, compare measured plans, and bound external overflow. # A slow provider operation should not own your terminal Cloud deployment is submitted as one durable operation. The operation worker—not the CLI process—owns provider mutation, retries, and reconciliation. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane deploy Qwen/Qwen3-8B \ --cloud runpod \ --gpu L40S \ --min 1 \ --max 4 ``` The command reports the durable operation ID before waiting. You may close the terminal and resume from another session without sending another provider create request: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane operation watch op_01JEXAMPLE \ --wait-timeout 15m ``` Idempotency, provider-resource identity, leased execution, and reconciliation protect the operation across CLI disconnects and control-plane worker restarts. They cannot make unavailable GPU capacity appear faster, but they prevent waiting from becoming an unsafe client-side workflow. ## Explain what the backend actually exposed ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane explain cold-start qwen-prod infercrane explain cold-start qwen-prod --output json ``` Cold-start explanations label observed and unavailable timing boundaries independently. A provider that exposes only zero-worker state and gateway time to first response byte does not produce a fabricated artifact-download or model-load waterfall. ## Compare measured serving plans Use AIPerf once per real deployment, then compare compatible persisted results: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane benchmark qwen-l40s --requests 100 --concurrency 10 infercrane benchmark qwen-h100 --requests 100 --concurrency 10 infercrane lab 'Qwen/Qwen3-8B@IMMUTABLE_COMMIT' \ --max-ttft-p95-ms 250 ``` Inference Lab currently emits `MEASURED` candidates from benchmark history. It does not silently provision hardware, estimate missing performance, or mix incompatible workloads. Cost is shown only when a trustworthy source and observation timestamp were persisted. ## Add governed external overflow When every ordinary target is unhealthy—or a bounded queue policy remains breached—InferCrane can select an explicitly configured external target: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane external configure qwen-prod \ --target openrouter-qwen \ --adapter openrouter \ --secret-reference SECRET_REFERENCE_ID \ --request-limit 100 \ --cost-limit-usd 10.00 \ --max-request-cost-usd 0.10 \ --acknowledge-external-data \ --enable ``` ```mermaid theme={"theme":{"light":"github-light-default","dark":"vesper"}} flowchart TD REQ[Request] --> POLICY{Primary route healthy?} POLICY -->|yes| GPU[Self-hosted capacity] POLICY -->|no| BUDGET{Privacy acknowledged
and reservation available?} BUDGET -->|yes| EXT[Approved external target] BUDGET -->|no| DENY[Reject before sending bytes] ``` External fallback can transmit prompts and generated output outside infrastructure you control and can create a separate provider charge. InferCrane requires explicit acknowledgement and hard request and worst-case cost reservations. It never fabricates a provider price or silently retries a request after a possible send. This is a safety valve, not automatic provider shopping. Selection, denial, recovery, budget counters, and the signal snapshot remain available as persisted evidence. # Connect the stack you already run Source: https://infercrane.mintlify.app/showcase/connect-existing Get useful evidence from an existing vLLM, LiteLLM, or OpenAI-compatible endpoint without migrating it. # Useful in minutes, without a migration A real local InferCrane terminal run connecting an externally owned vLLM-compatible worker, sending a request, inspecting content-free request evidence, and running deterministic Doctor diagnostics. The recording is generated from [`scripts/demo-connect.sh`](https://github.com/infercrane/infercrane/blob/main/scripts/demo-connect.sh) against GPU-free local fixtures. It proves the product workflow, not real-runtime performance. Connect an existing endpoint in observe-only mode. InferCrane performs bounded discovery and records the result without publishing a route or taking provider ownership. ```bash Automatic discovery theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane connect https://vllm.internal.example/v1 \ --as coder-production ``` ```bash Explicit vLLM theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane connect https://vllm.internal.example/v1 \ --as coder-production \ --type vllm ``` ```bash Machine-readable theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane connect https://vllm.internal.example/v1 \ --as coder-production \ --output json ``` When discovery cannot determine a physical model safely, provide it explicitly: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane connect https://gateway.internal.example/v1 \ --as coder-production \ --type openai-compatible \ --model Qwen/Qwen3-32B ``` `connect` is intentionally conservative. Runtime detection is reported only when the endpoint provides grounded signals. Unknown capability remains unknown rather than being inferred from a URL. ## Turn evidence into a daily workflow ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane doctor coder-production --window 1h infercrane request inspect req_fa098a6488ec2bedcf025844adda5f45 ``` Doctor evaluates persisted `Evidence → Rule → Finding` logic. Request Inspector reconstructs the logical endpoint, resolved target, revision or upstream where known, queue and response timing, tokens, retry count, and fallback reason. Prompt and output content are not recorded by default. After reviewing health and evidence, transfer routing ownership explicitly: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane adopt promote coder-production --ownership traffic-managed ``` The workload remains externally managed: InferCrane does not create, scale, update, or delete it. ## Use a user-managed LiteLLM gateway LiteLLM can sit behind InferCrane as an optional external OpenAI-compatible gateway: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane connect https://litellm.internal.example/v1 \ --as company-models \ --type litellm \ --model coder ``` ```mermaid theme={"theme":{"light":"github-light-default","dark":"vesper"}} flowchart LR APP[Application
model: company-models] --> IC[InferCrane
identity · policy · evidence] IC --> LL[User-managed LiteLLM
protocol translation] LL --> OAI[Managed model API] LL --> OTHER[Other configured targets] ``` InferCrane does not bundle, fork, install, or license LiteLLM. The operator supplies and manages the gateway and its provider credentials. This keeps the core integration generic: the same connection path works with another compatible gateway when it passes discovery and health checks. Connecting an endpoint does not prove every protocol or model behavior. Qualify streaming, tool calls, structured output, cancellation, and model identity for the exact upstream before production traffic. The current simple discovery path requires the control plane to read `/v1/models` without an upstream credential. Keep authenticated gateways externally configured until a reference-only upstream credential binding is qualified; never place credentials in the endpoint URL. ## Why this pattern matters * **Platform teams** can observe one workload before adopting a fleet. * **vLLM operators** can retain their existing compute and container setup. * **LiteLLM users** can retain broad managed-provider translation while InferCrane owns durable operational evidence and logical endpoint identity. * **Migration-sensitive teams** can progress from observe-only to traffic-managed ownership without transferring provider lifecycle. # Compose gateways and agent sandboxes Source: https://infercrane.mintlify.app/showcase/gateways-and-sandboxes Keep InferCrane focused on inference lifecycle while integrating gateways, external capacity, and sandbox runtimes through explicit boundaries. # Use the right owner for each layer InferCrane does not need to replace every component in an inference or agent stack. It provides the stable model endpoint, durable lifecycle, routing policy, and operational evidence. A user-managed gateway can translate provider protocols, and a sandbox can execute agent tools while calling that endpoint like any other application. ```mermaid theme={"theme":{"light":"github-light-default","dark":"vesper"}} flowchart LR APP[Application or agent] --> IC[InferCrane endpoint
identity · lifecycle · evidence] IC --> DEP[InferCrane-managed deployment] IC --> LL[User-managed LiteLLM gateway] IC -. governed binding or overflow .-> OR[External model API] SB[User-managed sandbox
E2B · Daytona · Modal · Kubernetes] --> IC ``` ## Connect a user-managed LiteLLM gateway Keep LiteLLM's provider configuration and credentials in LiteLLM. Connect its OpenAI-compatible surface to InferCrane in observe-only mode first: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane connect https://litellm.internal.example/v1 \ --as company-models \ --type litellm \ --model coder infercrane doctor company-models ``` After qualification, transfer routing ownership explicitly: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane adopt promote company-models --ownership traffic-managed ``` InferCrane does not bundle, fork, install, or license LiteLLM. It owns the logical endpoint and operational evidence; LiteLLM remains responsible for protocol translation and its upstreams. ## Add managed APIs without changing application code An authenticated OpenRouter or OpenAI-compatible API can be a first-class endpoint binding. Stage it as a fallback while the application continues sending `model="coder-production"`: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane endpoint bind coder-production \ --name managed-fallback \ --target managed-coder \ --ownership traffic-managed \ --external-adapter openai-compatible-external \ --secret-reference SECRET_REFERENCE_ID \ --request-limit 1000 \ --cost-limit-usd 25.00 \ --max-request-cost-usd 0.10 \ --acknowledge-external-data \ --enable-external infercrane endpoint plan coder-production \ --policy primary-fallback \ --bindings self-hosted,managed-fallback ``` The plan remains a candidate until evaluated and promoted. InferCrane never forwards its public API key to the provider and never stores the provider key in binding configuration. ## Use OpenRouter as deployment overflow OpenRouter can also be optional deployment-level emergency capacity, not an implicit default. Configure it with a secret reference, explicit model mapping, privacy acknowledgement, and hard request and cost reservation ceilings. InferCrane selects it before sending bytes and never silently duplicates or shadows a request. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} export OPENROUTER_API_KEY='...' infercrane secret create openrouter --from-env OPENROUTER_API_KEY --output json infercrane target add openrouter-qwen \ --provider openrouter \ --url https://openrouter.ai/api/v1 \ --upstream-model qwen/qwen3-8b ``` Complete the bounded policy using [Governed external capacity](/features/external-capacity). Real OpenRouter billing qualification is still deferred; InferCrane does not fabricate price evidence. ## Call InferCrane from an agent sandbox The sandbox is the application execution environment. Create it with the sandbox provider, then issue a short-lived credential restricted to exactly one InferCrane endpoint: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane sandbox connect \ --provider e2b \ --external-id sandbox-01JCGW \ --external-revision template-v3 \ --endpoint coder-production \ --ttl 30m ``` Inject the shown-once credential through the sandbox provider's secret mechanism, then use an ordinary OpenAI client inside the sandbox: ```python Python theme={"theme":{"light":"github-light-default","dark":"vesper"}} import os from openai import OpenAI client = OpenAI( base_url=os.environ["INFERCRANE_URL"].rstrip("/") + "/v1", api_key=os.environ["INFERCRANE_API_KEY"], ) response = client.responses.create( model="coder-production", input="Summarize the test failure in /workspace/test.log.", ) print(response.output_text) ``` ```typescript TypeScript theme={"theme":{"light":"github-light-default","dark":"vesper"}} import OpenAI from "openai"; const client = new OpenAI({ baseURL: `${process.env.INFERCRANE_URL}/v1`, apiKey: process.env.INFERCRANE_API_KEY, }); const response = await client.responses.create({ model: "coder-production", input: "Summarize the test failure in /workspace/test.log.", }); console.log(response.output_text); ``` Use the sandbox provider's secret injection and network allow-list controls. InferCrane's issued token cannot enumerate or invoke another endpoint alias and cannot access the control API. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane sandbox list infercrane sandbox rotate SANDBOX_REFERENCE_ID infercrane sandbox revoke SANDBOX_REFERENCE_ID --yes ``` InferCrane does not create, pause, snapshot, isolate, or delete sandboxes, and it does not record sandbox commands, files, prompts, or outputs. E2B, Modal, Kubernetes, and similar names describe the external execution owner, not an InferCrane sandbox runtime. Real provider secret injection and isolation remain provider-specific qualification. ## Bring a trained artifact into the release path Keep training data and execution in MLflow, Kubeflow, SkyPilot, or your existing pipeline. Hand InferCrane a signed content-free artifact identity bound to one immutable candidate revision: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane training keygen --file training-handoff.key infercrane training sign coder-runtime REVISION_ID \ --provider mlflow \ --run run-2026-08-14-42 \ --repository mlflow://registry/coder/42 \ --immutable-revision 42 \ --digest sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \ --key training-handoff.key \ --file coder-42.handoff.json infercrane training verify coder-42.handoff.json infercrane training attach coder-runtime coder-42.handoff.json ``` Attachment does not promote the revision. Continue through benchmark, Replay, semantic quality evidence, and Release Guard. See [Training artifact handoffs](/integrations/training-artifacts). ## Why the boundary is useful * Change inference providers without rebuilding the agent sandbox. * Change sandbox vendors without changing the logical model endpoint. * Keep model rollout evidence separate from tool-execution security policy. * Move externally trained artifacts into a guarded release without moving training data or keys. * Avoid turning InferCrane into a gateway fork, workflow engine, or sandbox isolation runtime. # What you can build Source: https://infercrane.mintlify.app/showcase/index Production inference patterns that start with one command and preserve evidence, ownership, and control. # Build, connect, and operate production inference Start from a model, a custom OCI workload, or an endpoint you already run. InferCrane can own the complete deployment lifecycle or add policy and evidence around existing infrastructure. Your application keeps one OpenAI-compatible model name while providers, runtimes, and capacity plans change behind it. Qwen, Llama, Gemma, Kimi, and private fine-tunes all enter through the same model-artifact contract. Support is evidence-based per model, runtime, accelerator, and provider combination—not a blanket “every model everywhere” promise. Turn a model and serving plan into a durable endpoint, then evolve it through immutable revisions. Scaffold, validate, build, and deploy a reproducible workload from one project directory. Add health, request evidence, and deterministic diagnosis around an existing vLLM, LiteLLM, or OpenAI-compatible endpoint. Combine LiteLLM, governed OpenRouter overflow, endpoint-scoped agent sandboxes, and signed training artifacts without merging ownership boundaries. Combine bounded performance validation with signed task-quality evidence and keep production unchanged when policy rejects it. Resume long operations, explain cold starts, compare measured serving plans, and govern external overflow. ## One stable application contract ```python Python theme={"theme":{"light":"github-light-default","dark":"vesper"}} from openai import OpenAI client = OpenAI( base_url="https://infercrane.example/v1", api_key="${INFERCRANE_API_KEY}", ) response = client.responses.create( model="coder-production", input="Review this function for concurrency bugs.", ) ``` ```typescript TypeScript theme={"theme":{"light":"github-light-default","dark":"vesper"}} import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://infercrane.example/v1", apiKey: process.env.INFERCRANE_API_KEY, }); const response = await client.responses.create({ model: "coder-production", input: "Review this function for concurrency bugs.", }); ``` ```bash cURL theme={"theme":{"light":"github-light-default","dark":"vesper"}} curl https://infercrane.example/v1/responses \ -H "Authorization: Bearer $INFERCRANE_API_KEY" \ -H "Content-Type: application/json" \ -d '{"model":"coder-production","input":"Review this function for concurrency bugs."}' ``` `coder-production` is the stable product identity. A binding may resolve it to an InferCrane-managed deployment, an adopted workload, or governed external capacity. Applications do not need provider credentials or physical model names when the serving plan changes. ## Choose how much InferCrane owns | Start here | InferCrane can observe | InferCrane can route | InferCrane can create or delete compute | | ---------------------------- | ---------------------- | -------------------- | --------------------------------------- | | `observe-only` connection | Yes | No | No | | `traffic-managed` connection | Yes | Yes | No | | lifecycle-managed deployment | Yes | Yes | Yes | This ownership ladder lets a platform team prove value before handing over traffic or provider lifecycle. Promotion is explicit; connecting an endpoint never silently changes production routing. ## The proof loop ```mermaid theme={"theme":{"light":"github-light-default","dark":"vesper"}} flowchart LR A[Connect or deploy] --> B[Observe requests and operations] B --> C[Doctor explains persisted evidence] C --> D[Create a candidate] D --> E[Benchmark with bounded traffic] E --> F{Release Guard} F -->|ACCEPT| G[Promote safely] F -->|REJECT| H[Keep active revision] G --> B H --> B ``` InferCrane does not use an LLM to decide production promotion. Policy inputs, measurements, reason codes, and revision identities are persisted so the result can be inspected and reproduced. Examples use qualified product surfaces, but infrastructure and runtime combinations have independent evidence states. Check the [capability matrix](/project-status) before relying on a combination in production. ## Run the proof loop locally ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} git clone https://github.com/infercrane/infercrane.git cd infercrane make demo ``` The hermetic demo exercises adoption, a real proxied fixture request, Request Inspector, Doctor, immutable candidate creation, Release Guard rejection, deterministic explanation, and cleanup. It does not provision a GPU and cannot be used as provider or performance evidence. # Reject a bad release before it reaches production Source: https://infercrane.mintlify.app/showcase/safe-rollouts Use bounded validation and deterministic Release Guard evidence to keep an active revision safe. # Make “production remains unchanged” the default failure mode An update creates an immutable candidate revision. It does not mutate the active revision in place. Release Guard compares compatible, persisted active and candidate evidence before promotion. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane plan deployment.yaml infercrane apply deployment.yaml ``` Validate with explicit cost and privacy acknowledgement. Validation traffic is bounded by persisted policy; InferCrane does not shadow or duplicate production requests silently. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane rollout policy set qwen-prod \ --require-compatibility \ --require-synthetic \ --validation-max-requests 100 \ --validation-max-concurrency 4 infercrane rollout validate qwen-prod \ --requests 100 \ --concurrency 4 \ --acknowledge-validation-cost \ --wait infercrane rollout inspect qwen-prod ``` ```text theme={"theme":{"light":"github-light-default","dark":"vesper"}} ACTIVE rev-18 CANDIDATE rev-19 Metric Active Candidate TTFT p95 221ms 317ms Guard: REJECT Reason TTFT regression +43%; maximum allowed +15%. ``` The values above illustrate the output shape; your result comes from persisted measurements. When evidence is missing or incomparable, Release Guard returns `WAIT` instead of inventing a result. ## What the decision proves ```mermaid theme={"theme":{"light":"github-light-default","dark":"vesper"}} flowchart LR ACTIVE[Active revision
still serving] --> COMPARE[Persisted comparison] CANDIDATE[Candidate revision
not in logical route] --> COMPARE POLICY[Snapshotted policy] --> COMPARE COMPARE -->|REJECT| CLEAN[Keep active
clean candidate] COMPARE -->|ACCEPT| PROMOTE[Publish candidate
drain old generation] ``` Every evaluation records: * active and candidate revision identity; * the exact policy snapshot; * compatible benchmark IDs and workload parameters; * measurements that were available; * explicit unavailable measurements; * deterministic reason codes and timestamp. Use the persisted decision during an incident or approval review: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane explain rollout qwen-prod infercrane rollout inspect qwen-prod --output json ``` After an accepted promotion, issue an [Inference Passport](/features/inference-passports) to bind the revision to its release evidence in an independently verifiable artifact. # Product qualification Source: https://infercrane.mintlify.app/testing/product-qualification Run InferCrane's resumable, commit-bound local and real-infrastructure evidence system. # Product qualification InferCrane has one top-level qualification command. It composes the maintained unit, race, PostgreSQL, Docker, Kind, black-box journey, provider-contract, SDK, Terraform, security, documentation, supply-chain, and real-provider suites. It does not replace those suites or hide their logs. Overlapping release work runs once: the black-box gate runs user journeys, while the supply-chain gate owns archive, checksum, SBOM, and Homebrew verification. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} make qualify-product ``` The command is resumable. A passed gate is reused only for the exact Git commit. The worktree must be clean, so uncommitted changes can never inherit release evidence from an earlier source tree. Evidence is written to: ```text theme={"theme":{"light":"github-light-default","dark":"vesper"}} .infercrane/product-qualification// ├── gates/ │ ├── developer-environment.json │ ├── product-journeys.json │ ├── adapter-contracts.json │ └── supply-chain.json ├── report.json └── report.md ``` Inspect the current matrix without running tests: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} make qualify-product-status ``` Longer fuzz, soak, and fleet simulation run separately so pull-request feedback remains fast: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} make qualify-product-nightly ``` See [Reliability test environment](/testing/test-environment) for the evidence ladder, provider simulation boundaries, version matrix, and scheduled workflow. The verdict vocabulary is intentionally strict: | Status | Meaning | | --------------------- | ----------------------------------------------------------------------------- | | `PASSED` | This exact commit passed the named gate. | | `FAILED` | The gate ran and failed. Cleanup cannot change this result. | | `NOT_RUN` | A locally automatable gate has no evidence for this commit. | | `NOT_RUN` (scheduled) | A nightly fuzz, soak, scale, or version gate has no evidence for this commit. | | `REAL_INFRA_REQUIRED` | Fixtures prove the adapter logic, not the external provider semantics. | | `BLOCKED_ACCESS` | The real suite was requested but credentials or configuration were absent. | | `HUMAN_REQUIRED` | Visual, hosted, or operator-comprehension review remains. | ## Real RunPod qualification Paid provider mutation always requires an explicit approval flag. Reuse the run ID after a shell disconnect; durable operations and stage evidence allow the workflow to resume. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} export RUNPOD_KEY_FILE="$HOME/.config/infercrane/runpod-key" export INFERCRANE_RUNPOD_SERVERLESS_TEMPLATE_ID="" export INFERCRANE_V2_QUALIFICATION_RUN_ID="$(date -u +%Y%m%dT%H%M%SZ)-$(git rev-parse --short HEAD)" ./scripts/qualify-product.sh runpod --approve-paid-resources ``` The command records four independent gates: serverless lifecycle, serverless faults, elastic lifecycle, and elastic faults. A provider allocation failure in one gate cannot erase successful evidence from another. Together they cover vLLM protocols, AIPerf, autoscaling, Release Guard, streaming cancellation, lost-response adoption, disruption, deletion, and direct zero-inventory checks. A provider allocation or image-transfer failure remains a failed suite even when guarded cleanup succeeds. ## AWS, GCP, and Kubernetes GPU qualification The portable qualification runner needs an isolated provider environment, immutable workload specs, and one API key shared by the control plane and workers. See [provider setup](/provider-setup) before running any paid gate. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} export INFERCRANE_V1_PROVIDER_ENV_FILE=/private/provider.env export INFERCRANE_V1_SPEC_DIR=/private/qualification-specs export INFERCRANE_V1_API_KEY_FILE=/private/control-and-worker-key ./scripts/qualify-product.sh aws --approve-paid-resources ./scripts/qualify-product.sh gcp --approve-paid-resources ./scripts/qualify-product.sh kubernetes --approve-paid-resources ``` The compatibility-prefixed `INFERCRANE_V1_*` names do not select an old release. A gate remains `REAL_INFRA_REQUIRED` until its exact-commit paid run passes; the existence of the guarded runner is not qualification evidence. ## What the system proves Local qualification proves control-plane behavior against deterministic dependencies, a real PostgreSQL process, Docker process failures, and a real Kind API. It cannot prove GPU availability, provider eventual consistency, customer networking, runtime performance, public package delivery, or human usability. Those boundaries remain separate rows in `report.json` so automation can enforce release policy without turning simulated evidence into a production claim. # Reliability test environment Source: https://infercrane.mintlify.app/testing/test-environment InferCrane's long-term local, scheduled, simulated, and real-infrastructure qualification strategy. # Reliability test environment InferCrane uses an evidence ladder. Every failure is tested at the cheapest boundary that can faithfully reproduce it, while claims that depend on a real provider, GPU, runtime, or customer network remain explicitly unqualified until that boundary runs. ```text theme={"theme":{"light":"github-light-default","dark":"vesper"}} pull request ├─ unit + property + state-machine seeds ├─ race detector + PostgreSQL integration ├─ provider/runtime fault contracts └─ public CLI/API product journeys scheduled ├─ coverage-guided fuzzing ├─ shuffled race/lease/contention soak ├─ PostgreSQL TCP partition + recovery ├─ Kind Kubernetes-version matrix └─ KWOK large-fleet and scheduler disruption release candidate ├─ RunPod elastic + serverless ├─ AWS BYOC ├─ GCP BYOC (runner still required) └─ GPU Kubernetes/KServe ``` ## Test tiers | Tier | Trigger | What it proves | What it cannot prove | | ------------------- | --------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------ | | Fast | Every change | Pure logic, validation, API compatibility, deterministic state transitions | Processes, databases, providers | | Full local | Every pull request | Race behavior, real PostgreSQL, Docker crashes, Kind API, SDKs, Terraform, black-box UX | Real cloud and GPU semantics | | Scheduled | Nightly and on demand | Longer fuzzing, randomized order, repeated leases, fleet scale, Kubernetes version skew | Provider quota, IAM, CUDA, performance | | Real infrastructure | Explicit RC approval | Actual provider identity, networking, capacity, runtime, deletion, billing inventory | Other untested providers or configurations | | Human | RC review | Terminal/browser usability, hosted docs and operator comprehension | Distributed-system correctness | The machine-readable inventory is [`qualification/product-gates.json`](https://github.com/infercrane/infercrane/blob/main/qualification/product-gates.json). Each result is bound to a Git commit and has its own status. Successful cleanup never overwrites a failed suite. ## Provider simulation AWS, GCP, RunPod, Kubernetes, external capacity, vLLM, SGLang, and custom OCI adapters use fault-injectable contracts. Fixtures can return lost create responses, delayed observations, mismatched identities, invalid success bodies, rate limits, malformed/truncated data, eventual deletion, and credential-bearing errors. The same conformance properties apply to every adapter: * stable intent identity and at-most-one owned resource; * restart-safe adoption after ambiguous create; * fail-closed immutable configuration matching; * idempotent deletion and independently verified inventory; * bounded, normalized, secret-free error evidence. Run the complete hermetic cloud boundary directly with: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} make test-simulated-clouds ``` LocalStack is not a required dependency. It can be used as an optional AWS API compatibility probe, but its mock EC2 manager supplies CRUD semantics, Docker-backed EC2 has networking limitations on macOS, and IAM enforcement depends on configuration and plan. InferCrane's deterministic adapter fixtures are faster and more precise for control-plane fault injection; real AWS remains the qualification boundary for IAM propagation, VPC behavior, capacity, quota, and eventual consistency. Google does not ship a Compute Engine emulator. Its official emulators cover data services such as Firestore, Spanner, Pub/Sub, Bigtable, and Datastore. InferCrane therefore keeps a deterministic Compute API/CLI model locally and requires an isolated GCP project for real VM evidence. ## Kubernetes fidelity and scale Kind boots a real Kubernetes API server, controller manager, scheduler, kubelet, and server-side apply implementation. InferCrane tests ownership, RBAC, stale `observedGeneration`, field conflicts, partial owner repair, restart adoption, asynchronous deletion, and clean inventory against the current API. The scheduled matrix repeats this lifecycle against Kubernetes 1.34, 1.35, and 1.36 using digest-pinned Kind images. KWOK adds a different boundary: hundreds of simulated nodes and InferCrane-managed workloads with very low resource usage. The fleet test proves that missing GPU capacity stays provisioning and unroutable, large inventory remains coherent, half-fleet node loss cannot manufacture readiness, and bulk cleanup reaches zero. KWOK does not run containers or GPUs, so it never qualifies runtime startup or performance. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} make test-kubernetes-kind make test-kubernetes-kwok ``` ## Fuzz and soak Go's coverage-guided fuzz engine continuously mutates critical state-machine inputs. A discovered failure is minimized and committed to the corpus so ordinary test runs preserve it as a regression. The soak tier repeatedly shuffles and race-tests operation leasing, async execution, admission, quotas, autoscaling, routing, reconciliation, providers, and workflows. When `INFERCRANE_TEST_DATABASE_URL` is present it also repeats PostgreSQL fencing and contention cases. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} INFERCRANE_FUZZ_TIME=2m make test-fuzz INFERCRANE_SOAK_COUNT=20 make test-reliability-soak make qualify-product-nightly ``` ## Network and process faults InferCrane prefers deterministic HTTP fixtures when an HTTP semantic matters and real process/TCP boundaries when connection behavior matters. The local recovery suite kills workers, routers, control-plane replicas, and PostgreSQL connections; provider fault proxies inject timeouts and lost responses. The scheduled Toxiproxy gate cuts every PostgreSQL connection in a full Docker stack and proves that readiness fails closed, an already-published inference route remains available without a database lookup, and the control plane recovers after connectivity returns. Future latency, reset, bandwidth, partial-transfer, and slow-close cases belong in the same boundary; this complements—not replaces—assertions about durable state and ownership. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} make test-network-chaos ``` ## Evidence retention and release policy The nightly GitHub workflow uploads qualification evidence for 30 days. Release evidence remains under `.infercrane/product-qualification/` locally and should be attached to the RC. A release decision must inspect: 1. all local gates for the exact commit; 2. the most recent scheduled gates on the same lineage; 3. every real-provider/runtime combination advertised as qualified; 4. independent zero-resource inventory after paid suites; 5. human terminal, dashboard, docs, and clean-install review. No aggregate percentage can erase a missing boundary. For example, 100% fixture coverage still does not qualify AWS IAM or CUDA behavior. ## Primary design references * [Go coverage-guided fuzzing](https://go.dev/doc/security/fuzz/) * [Kind local Kubernetes clusters](https://kind.sigs.k8s.io/docs/user/quick-start/) * [KWOK architecture](https://kwok.sigs.k8s.io/docs/design/architecture/) and [lifecycle stages](https://kwok.sigs.k8s.io/docs/user/stages-configuration/) * [Kubernetes large-cluster considerations](https://kubernetes.io/docs/setup/best-practices/cluster-large/) * [AWS idempotent API design](https://aws.amazon.com/builders-library/making-retries-safe-with-idempotent-APIs/) * [LocalStack EC2 behavior and limitations](https://docs.localstack.cloud/aws/services/ec2/) * [Google Cloud emulator scope](https://cloud.google.com/sdk/docs/overview) * [Toxiproxy deterministic network conditions](https://github.com/Shopify/toxiproxy) * [vLLM model and dummy-weight test guidance](https://docs.vllm.ai/en/latest/contributing/model/tests/) # Troubleshooting Source: https://infercrane.mintlify.app/troubleshooting Diagnose configuration, provisioning, readiness, routing, rollout, and cleanup failures. # Troubleshooting Start with `infercrane doctor`, then `status`, `events`, `inspect`, and `explain`. Use `operation ID` when a lifecycle operation is retrying. `inspect` exposes provider request/resource IDs needed to reconcile external inventory. * **Provisioning appears stuck:** read the durable progress message before changing anything. `provider is allocating capacity` and `provider capacity and secure worker bootstrap` mean the runtime is not reachable yet; `model artifact and runtime readiness` means the worker is reachable but its model is still loading. Check `operation ID`, `inspect`, and provider inventory. Do not submit another deployment with a different idempotency key. * **Deployment is degraded:** run the general explanation and verify expected model readiness on each replica. * **Not scaling:** use `explain scaling`; check thresholds, consecutive intervals, bounds, and cooldown. * **Candidate rejected:** use `explain rollout`; compare persisted metrics and policy rather than retrying promotion blindly. * **Slow first request:** use `explain cold-start`; unavailable provider substages are intentionally not inferred. * **Delete interrupted:** reconnect and inspect the same durable operation. Confirm provider inventory is empty before considering cleanup complete. * **AWS deployment is rejected before provisioning:** run `infercrane doctor --aws`; verify the complete `INFERCRANE_AWS_*` set, exact requested region/GPU, immutable image digest, role trust, private subnet reachability, and instance-profile access to the worker secret. Retrying a configuration error does not create capacity. * **Kubernetes deployment is rejected before provisioning:** run `infercrane doctor --kubernetes`; verify the explicit context, namespace RoleBinding, immutable image, GPU label/resource, worker Secret reference, and optional KServe CRD. A server-side field conflict is intentional protection; inspect `managedFields` and resolve ownership instead of forcing the apply. * **External fallback does not activate:** run `infercrane external inspect DEPLOYMENT`, then check primary health, privacy acknowledgement, the injected secret reference, external `/models` inventory, and remaining request/cost reservations. InferCrane fails closed and never replays a possibly transmitted request. * **External fallback returns 429:** the in-memory lease or persisted hard budget is exhausted. Inspect the policy before deliberately increasing its ceilings; InferCrane does not fabricate or refund provider cost. Never paste API keys, prompts, generated content, or unredacted provider responses into a public issue. # Upgrade and compatibility Source: https://infercrane.mintlify.app/upgrade Version guarantees, database migration safety, rolling-upgrade boundaries, and rollback policy. # Upgrade and compatibility InferCrane v1 separates four compatibility surfaces: the control API, DeploymentSpec, integration contracts, and PostgreSQL schema. A passing runtime or provider conformance test does not override the policy for another surface. ## Before upgrading 1. Read the release notes and compatibility matrix. 2. Back up PostgreSQL and verify the dump with `pg_restore --list`. 3. Run `infercrane plan` for representative DeploymentSpecs with the new CLI. 4. Run local qualification against the exact candidate commit. 5. Verify provider credentials and inventory with `infercrane doctor` and `infercrane orphans`. 6. Upgrade the control plane before upgrading generated SDKs or automation clients. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} scripts/backup-postgres.sh /secure/path/infercrane-before-v1.dump make qualify-local ``` ## PostgreSQL migration contract Migrations are embedded, ordered, forward-only, and transactionally applied under a PostgreSQL advisory lock. The migration ledger stores a SHA-256 checksum for every migration. Startup fails if: * a previously applied migration was edited; * the ledger has a gap; * the database contains a migration unknown to the running binary; or * a migration cannot commit atomically. The first v1 startup backfills checksums for a pre-v1 ledger after matching every known migration name. This is a trust-on-first-v1-upgrade bootstrap: a legacy ledger did not retain enough information to prove the bytes originally executed. Back up and inspect that database before the first v1 startup. Every subsequent startup verifies the persisted checksum. Automated qualification upgrades every historical migration prefix to the current schema. Do not delete ledger rows, edit released SQL files, or start an older binary after a newer migration has run. Restore the pre-upgrade backup if application rollback requires schema rollback. ## DeploymentSpec The current file contract is: ```yaml theme={"theme":{"light":"github-light-default","dark":"vesper"}} apiVersion: infercrane.dev/v1 kind: Deployment ``` Pre-v1 files without these two fields are read as v1 for compatibility. New files should include them. Unknown fields, versions, and kinds fail closed. Additive optional v1 fields are compatible; removing or changing a v1 field requires a future versioned conversion path. ## Control API and SDKs `/api/v1` is the stable v1 namespace. Within v1: * new optional response fields are additive; * clients must ignore response fields they do not understand; * existing field meaning and error codes do not change silently; * removal requires deprecation in release notes for at least two minor releases; * generated SDK major versions track the API major version. CLI human output is not a parsing contract. Automation must use `--output json`, the generated SDKs, or Terraform. ## Provider and runtime contracts Provider Contract `infercrane.provider/v1` and Runtime Contract `infercrane.runtime/v1` are versioned separately from the product. Registration exposes an adapter to composition; only the capability and qualification inventory establishes evidence for an exact runtime/provider/mode combination. ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane integrations --output json ``` ## Rolling upgrades Every live replica registers its binary version and control protocol interval. Startup fails before serving when that interval cannot overlap a live member. Inspect the actual window: ```bash theme={"theme":{"light":"github-light-default","dark":"vesper"}} infercrane system instances --output json ``` For an adjacent-version rollout, first confirm the release notes declare overlapping protocol intervals. Add one new replica, verify `/readyz` and the membership list, then remove old replicas one at a time. An expired operation lease is reclaimed by another worker; the old fence token cannot checkpoint or complete work. This is not permission to mix arbitrary schema versions: take a verified backup first and follow the migration compatibility statement for both releases. Rotate server or client certificates by temporarily trusting both CA generations, rolling clients, then servers, and finally removing the old CA. InferCrane reads certificate files at process startup, so each trust change requires a graceful rolling restart. ## Support window Release candidates receive best-effort migration fixes and may still change with release notes. For stable releases, security fixes target the latest minor and the immediately preceding minor; provider/runtime compatibility remains scoped to the published matrix and immutable evidence. # Why InferCrane Source: https://infercrane.mintlify.app/why-infercrane The production inference problems InferCrane solves, the tools it complements, and when it is not the right choice. # The missing operational layer for inference Getting one model to answer one request is straightforward. Keeping a stable endpoint healthy while capacity is scarce, models take minutes to load, traffic changes, and revisions behave differently is the hard part. InferCrane gives teams one durable control plane for that operational gap. It builds or connects inference, preserves application identity, records what happened, and makes risky changes explicit. ## Problems teams repeatedly encounter | Production friction | What usually happens | InferCrane response | | ------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | | A model works locally but deployment needs cloud scripts, a proxy, health checks, and state | Every team builds a fragile one-off platform | One deployment intent and a durable operation | | GPU scaling requires several metrics and controllers | Scale-up arrives late; scale-down interrupts work | Bounded autoscaling, readiness-aware routing, and safe drain | | Model download and startup take minutes | A terminal looks frozen and retries risk duplicate resources | Resumable operations with capacity, artifact, runtime, and readiness stages | | A new model/runtime combination is trial and error | Container, tokenizer, chat template, quantization, or GPU fit fails late | Immutable artifacts, recipes, plans, benchmarks, and explicit qualification evidence | | A candidate is healthy but slower or more expensive | “Ready” is mistaken for “safe to promote” | Release Guard compares persisted active and candidate evidence | | Nobody can explain a latency regression | Operators correlate logs, metrics, provider consoles, and deploy history manually | Request Inspector and deterministic Doctor findings connect requests to revisions and events | | Existing vLLM or LiteLLM works and migration is risky | A new platform demands replacement before showing value | Observe first, then explicitly transfer routing or lifecycle ownership | | External fallback avoids downtime but can leak data or spend | Requests silently leave controlled infrastructure | Explicit privacy consent plus hard request and cost-reservation limits | These patterns appear throughout current vLLM and Kubernetes operator discussions: autoscaling needs multiple signals, cold-start lag dominates scale-out, and newly released models often require exact runtime and configuration combinations. InferCrane does not pretend those constraints disappear; it makes them observable and governable. The product priorities are grounded in upstream behavior and recurring operator reports, including [vLLM's production metrics](https://docs.vllm.ai/en/latest/design/metrics/), [Kubernetes autoscaling behavior](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/), community reports about the [number of moving parts in GPU autoscaling](https://www.reddit.com/r/kubernetes/comments/1sd7zyr/keda_gpu_scaler_autoscale_vllmtriton_inference/), [cold-start lag and queue signals](https://www.reddit.com/r/mlops/comments/1rknjhe/scaling_vllm_inference_queue_depth_as_autoscaling/), and [trial-and-error model/runtime combinations](https://www.reddit.com/r/Vllm/comments/1vap86g/how_many_attempts_does_it_normally_take_you_to/). Community discussions are product-discovery signals, not proof of InferCrane performance. ## What InferCrane replaces—and what it keeps ```mermaid theme={"theme":{"light":"github-light-default","dark":"vesper"}} flowchart LR DEV[Developer
model or endpoint] --> IC[InferCrane
intent · lifecycle · evidence] IC --> P[Provider contract] IC --> R[Runtime contract] IC --> G[Stable OpenAI-compatible endpoint] P --> CLOUD[AWS · GCP · RunPod · Kubernetes] R --> ENGINE[vLLM · SGLang · custom OCI] ``` InferCrane replaces handwritten lifecycle glue, not the infrastructure ecosystem: * SkyPilot or provider APIs continue provisioning infrastructure. * vLLM, SGLang, or custom runtimes continue executing inference. * vLLM Router continues distributing requests among standalone replicas. * AIPerf continues generating benchmark load. * Hugging Face Hub/Xet continues resolving and transferring model artifacts. * OpenTelemetry conventions continue defining portable telemetry. InferCrane owns the stable endpoint, desired and observed state, durable operations, revisions, rollout policy, evidence, explanations, and adapter qualification. ## Choose InferCrane when * You want to operate open-weight or custom inference on infrastructure you control. * You already run vLLM or an OpenAI-compatible gateway and need safer operations without migration. * You need asynchronous deploy/update/delete operations that survive a disconnected CLI. * You need evidence before promoting a runtime, model, GPU, or provider change. * You want provider and runtime portability without adopting a universal lowest-common-denominator API. ## Do not choose InferCrane when * You want a hosted model API with no infrastructure account or control plane to operate. * You need training, fine-tuning orchestration, a generic workflow engine, or an agent framework. * You expect every model/runtime/provider combination to be supported without qualification. * You require InferCrane-managed sandbox execution; sandboxes are currently application-managed. * You need a production claim for an adapter marked experimental or locally qualified only. Start from a model artifact or immutable OCI workload. Gain evidence without transferring lifecycle ownership. See exactly what is implemented, qualified, experimental, or planned.