Carrier
1.3.4 · stability policy · compiled

Build production-grade backends in minutes, not weeks.

Carrier compiles one .carrier source tree into the full stack a real service ships with — REST API, auth, database, workflows, observability, deploy artifacts. No framework wiring. No glue code. No drift between the diagram and the binary.

Source.carrier
CodegenRust → Cargo
RuntimeTokio · Axum
StorePostgres · RLS · pgvector
StreamsWS · SSE · long-poll
TelemetryOTLP · JSON logs

From idea to production. Describe → approve → compile → ship.

33 constructs
incl. runtime · sla · invariant
Rust · Java · Node
3 targets · same migrations
1.3.4
stability policy · 1.x guarantee
compiled · native binary·AI-friendly by construction·fast · ~20k rps on /items·secure · RLS · idempotency · JWT rotation · typed I/O·durable · workflows · sagas · queues · realtime·rag · llm budgets · mcp · pdf · cloud deploy·1.3.4 stability policy
What you get

One source tree. Everything a real backend ships with.

Carrier compiles a .carrier project into the working set below — generated, governed, and reviewable. Nothing here is a stretch goal: every item is implemented in 1.3.4 today and produced from one of the thirty-three top-level constructs.

API9 items
REST API + auth, fully typed
  • Typed REST routes — path params, query, body, response
  • Generated CRUD — list · get · create · update · delete · restore
  • Filters, pagination, sort, full-text search, soft delete
  • Idempotency-key handling at the edge
  • JWT auth — issuer, audience, JWKS, secret rotation
  • Role hierarchy + all_roles / any_roles guards
  • OpenAPI 3.1 spec + /docs explorer + api_explorer Try-it
  • MCP stdio server (action / workflow tools, free)
  • React Native SDK with persisted offline mutation queue
Data9 items
Postgres models + governance
  • Postgres models with @version, @unique, @index, @primary
  • Generated migrations + schema snapshots
  • Row-level security (RLS) compiled from policy declarations
  • Tenant + workspace session context per request
  • pgvector search — HNSW + IVFFlat, cosine / euclidean / inner
  • Hybrid search (text + vector) with weight overrides
  • Materialized views, governed precomputed reads
  • Hash-chained audit log (carrier_audit_log)
  • Tenant-scoped data exports (NDJSON / CSV)
Async9 items
Workflows, jobs, queues, realtime
  • Durable workflows — linear, saga, parallel graph
  • Per-step retry budgets + typed compensation
  • Cron schedules + jobs + durable events
  • Typed Redis queues — consumers · DLQ · retry backoff
  • Tenant lifecycle hooks — on_create / on_suspend / on_delete
  • Realtime streams — WebSocket → SSE → long-poll fallback
  • watch blocks: CRUD changes → typed events post-commit
  • Feature flags — percentage + tenant rules
  • First-class SLAs — attainment, deadline, escalation
AI9 items
LLM tools, RAG, agents, evals
  • llm client with typed tool surface, generated schemas
  • respond_as(TypeName) — structured outputs without JSON glue
  • Per-tenant USD budgets + downgrade-on-overage
  • Routed clients — primary / fallback on outage / 429 / cost
  • rag — retriever + embedder + LLM in one declaration
  • agent declarations bound as chat-thread participants
  • Persisted conversations (carrier_llm_conversations)
  • eval blocks — graded LLM regression checks under carrier test
  • finetune — curated datasets pinned to a model version
Observability9 items
Native OpenTelemetry, no boilerplate
  • OTLP traces, metrics, and logs — HTTP or gRPC export
  • Spans on every route, action, job, workflow, client, LLM call
  • Trace context propagated through jobs and workflows
  • Stable carrier.* span attributes (route_name, tenant_id, …)
  • Structured JSON logs to stdout, mirrored to OTLP
  • trace.annotate({...}) + metrics.counter / gauge
  • Carrier Flight Recorder at /ops/flight
  • Evidence bundles — request id, stack hash, recent probes
  • /health, /ready, /openapi.json, /docs, /ops/runtime
Documents6 items
PDF, blobs, files, templates
  • pdf.render_html — text-first deterministic PDFs
  • pdf.render_svg_template — visual SVG with custom fonts + assets
  • blob.put + blob.signed_url — file storage + signed downloads
  • image.* helpers — resize / crop / thumbnail
  • template.render_html — typed Handlebars-style rendering
  • Generated certificate, invoice, and report flows
Governance9 items
Verification, compliance, hardening
  • invariant blocks — must_always / must_never / transition
  • Bounded verification with z3 (and deterministic fallback)
  • carrier check --verify --fail-on-unknown as a CI gate
  • Compliance bundles — HIPAA · FERPA · PCI-DSS · SOC 2
  • Audit-chain verification (verify-audit-chain)
  • service.runtime — depth limits, panic policy, ops_routes
  • carrier harden --chaos --run --sandbox-db (Tank harness)
  • carrier tune — local sizing advisor for prod runtime knobs
  • carrier manifest audit — secrets, sizes, drift
Vertical7 items
Healthcare, recipes, modules
  • FHIR helpers — Questionnaire, Observation, Patient, Encounter
  • Generated /fhir/* routes for the phase-1 resource set
  • HL7v2 receive handlers + runtime coverage
  • Module + recipe registry (org/name with semver, SBOM, lock)
  • Recipes — vertical solution bundles + analytics packs
  • carrier audit — provenance + OSV.dev advisories
  • Forms — V3 runtime form promotion to native source
Build & deploy11 items
Three targets, five deploy paths
  • carrier build --target rust — native binary, Tokio + Axum + sqlx
  • carrier build --target java — Spring Boot 3.x service, JDBC + HikariCP
  • carrier build --target node — Fastify dev server, ~200ms restart
  • Same migration SQL across all three targets, byte-identical
  • carrier build --compile-remote=true — SSH build server, rsync round-trip
  • Carrier Cloud — carrier remote login / deploy / status / logs
  • carrier deploy compose — docker-compose + Dockerfile
  • carrier deploy k8s --multi-region — k8s manifests with HPA + PDB
  • carrier deploy edge --target cloudflare | fastly — edge WASM
  • Built-in tests, property tests, in-language eval blocks
  • carrier agent-docs — project-local AGENTS.md + CLAUDE.md
Benchmarks

Fast because it compiles. Tiny because there’s no runtime framework to carry.

Six identical APIs, one Postgres-backed GET /items endpoint, 30 seconds of 64-in-flight traffic. Carrier lands in the Go tier on throughput with a fraction of the memory of the managed-runtime stacks.

GET /items?limit=50 · pool 10 · 30s window
speed-benchmark
StackRPSp99peak RSS
Carrier™ (Rust-compiled)19,8086.3 ms15 MB
Go · Gin21,2596.3 ms38 MB
.NET · Minimal APIs18,3777.0 ms221 MB
Spring Boot13,55911.9 ms334 MB
Node · Fastify10,8638.3 ms277 MB
Python · FastAPI2,80576.6 ms54 MB

Single host. Native processes, no Docker. Same 10k-row Postgres, same pool size, same client. See /benchmarks for methodology, charts for /health and /compute, and all three endpoints in full.

What this actually shows
Carrier sits in the compiled-language tier (Go · .NET · Carrier) on throughput, but uses ~15× less RAM than .NET and ~22× less than Spring Boot — because the runtime is a Rust async binary, not a managed VM + framework.
And on CPU
On GET /compute (1000-iteration SHA-256 chain) Carrier hits 24,980 rps — ~10× Node/Python, ~1.5× Go, and within noise of .NET/Spring native crypto paths.
Why Carrier

Built narrow, so the backend gets out of the way.

Most backend frameworks give you a generic language plus conventions. Carrier inverts that. The backend patterns that actually matter — routes, auth, CRUD, policies, transactions, jobs — are language-level constructs the compiler understands.

Compiled, not configured
One .carrier source tree compiles through lexer, parser, semantic analysis, IR, Rust codegen, and Cargo into a native service binary. Rust is an implementation detail.
Opinionated CRUD
crud generates list, get, create, update, delete, and restore — with filters, sort, pagination, search, soft delete, and explicit scopes.
Actions with real transactions
action blocks open Postgres transactions, lock rows with get_for_update, and call auth, cache, jobs, audit, and typed external clients.
Policies that compile to RLS
policy declarations produce PostgreSQL RLS SQL and runtime session context for carrier.current_roles and carrier.current_tenant.
Idempotency as a keyword
Mark a route idempotent and Carrier stores the JSON response in Postgres, short-circuiting retries with the same Idempotency-Key.
Workflow edges, typed
job, event, and schedule give you durable async work, cron-driven fan-out, and audit-backed event records.
Platform

Durable workflows, typed LLM tools, vector search, realtime streams.

Four language-level platforms sit alongside CRUD and actions. They compile the same way, share auth, policy, telemetry, and audit plumbing — and now feed into the 1.0 surface (RAG, agents, MCP, PDF, recipes, Carrier Cloud) below.

workflow · step · compensatedurable saga with typed rollback
src/workflows/checkout.carrier
CheckoutSaga
workflow CheckoutSaga {
input: CheckoutRequest
output: CheckoutResult
timeout_seconds: 300
max_retries: 2
step reserve_inventory -> ReservationSummary
retry {
max_retries: 3
delay_seconds: 10
} {
return Inventory.reserve(input.sku, input.quantity)
}
compensate reserve_inventory {
Inventory.release(reserve_inventory.reservation_id)
}
step charge_card -> ChargeSummary {
if input.simulate_failure {
fail("checkout_failed", "card authorization declined")
}
return Payments.charge(input.payment_method, input.amount_cents)
}
compensate charge_card {
Payments.refund(charge_card.charge_id)
}
step fulfill -> CheckoutResult after charge_card {
return Fulfillment.ship(
reservation: reserve_inventory.reservation_id,
charge: charge_card.charge_id
)
}
return fulfill
}
llm client · tool · respond_astyped tools, structured output
src/support/agent.carrier
SupportAgent
fn search_help_docs(term: String) -> String[] {
return [term, "billing", "password reset"]
}
action get_support_profile() -> MeResponse {
let actor = auth.current_user()
return { id: actor.id, email: actor.email, name: actor.name }
}
llm client SupportAgent {
provider: env("LLM_PROVIDER", "openai")
wire_format: env("LLM_WIRE_FORMAT", "openai")
model: env("LLM_MODEL", "gpt-4.1-mini")
api_key: env("LLM_API_KEY", "replace-me")
max_turns: env_int("LLM_MAX_TURNS", 8)
temperature: 0.2
system_prompt: "You are a concise support assistant."
tool search_help_docs(term: String) -> String[] = search_help_docs
tool get_support_profile() -> MeResponse = get_support_profile
}
route POST "/support/draft" protect Auth -> SupportTicketDraft {
input: SupportReplyRequest
handler {
return SupportAgent.respond_as(SupportTicketDraft, {
user_prompt: input.message
conversation_id: input.conversation_id
})
}
}
Vector(N) · hybrid_searchpgvector · HNSW · cosine
src/docs/vectors.carrier
Doc · embedding
model Doc {
id: UUID
title: String
body: String
embedding: Vector(1536) @index(hnsw, metric: cosine)
created_at: Time
updated_at: Time
}
crud Doc at "/docs" {
list: public
get: public
searchable { title body }
}
native fn embed_text(value: String) -> Vector(1536) = "embed_text"
route POST "/docs/search" public -> DocHybridMatch[] {
input: SimilarDocRequest
handler {
return Doc.hybrid_search(
query: input.query,
embedding: embed_text(input.query),
limit: 20
)
}
}
telemetry · OTLP · metricsnative OpenTelemetry export
src/main.carrier
service.telemetry
service App {
openapi { title: "App API" version: "0.9.0" }
server { host: env("HOST", "0.0.0.0") port: env_int("PORT", 3000) }
telemetry {
provider: opentelemetry
endpoint: env("OTEL_EXPORTER_OTLP_ENDPOINT", "")
service_name: "app-api"
protocol: otlp_http
sampling: parentbased_ratio(0.1)
}
}
route GET "/checkout" protect Auth -> CheckoutResult {
handler {
let actor = auth.current_user()
trace.annotate({ actor_id: actor.id, tenant_id: actor.tenant_id })
metrics.counter("checkout.requests").increment({ tenant_id: actor.tenant_id })
return Checkout.place(input)
}
}
Workflows
Linear, saga, and graph. Per-step retry, typed compensation, parallel branches, durable leases, operator retry_compensation.
LLM clients
Carrier-typed tools, generated schemas, persisted conversations in carrier_llm_conversations, realtime stream surface per client.
Vectors
Vector(N) columns, HNSW + IVFFlat indexes, generated similar_with_scores and hybrid_search helpers.
Realtime
stream · subscription · watch with WS → SSE → long-poll transport negotiation and tenant/workspace scoping.
What 1.3.4 adds

RAG, agents, api_explorer, native PDF, MCP servers, Carrier Cloud.

The 1.0 line keeps the same compiler-checked envelope and adds the surfaces production AI-friendly backends actually need: typed retrieval, typed agent budgets and routing, a built-in API explorer, native PDF rendering, MCP exposure, and one-command deploy targets.

rag · retriever · llmvector retrieval + LLM, one declaration
src/support/rag.carrier
SupportAnswerer
rag SupportAnswerer {
retriever: Doc.similar_with_scores
embed_with: embed_text
llm: SupportAgent
context_window_tokens: 4000
rerank: score_threshold(0.7)
top_k: 8
}
route POST "/support/answer" public -> String {
input: SimilarDocRequest
handler {
let response = SupportAnswerer.respond(input.query)
return response.text
}
}
llm client routed · budgetper-tenant USD ceiling · downgrade fallback
src/support/agents.carrier
RoutedSupportAgent
llm client SupportAgent {
provider: "openai"
wire_format: "openai"
model: env("LLM_MODEL", "gpt-4.1-mini")
api_key: env("LLM_API_KEY", "")
max_tokens: 600
max_turns: 8
temperature: 0.2
budget_per_tenant_per_day_usd: 5.0
over_budget_behavior: downgrade("SupportAgentFallback")
tool search_help_docs(term: String) -> String[] = search_help_docs
}
llm client SupportAgentFallback {
provider: "openai"
wire_format: "openai"
model: "gpt-4.1-mini"
api_key: env("OPENAI_API_KEY", "")
max_tokens: 600
max_turns: 4
temperature: 0.2
}
llm client routed RoutedSupportAgent {
primary: SupportAgent
fallback: SupportAgentFallback
route_by: cost_vs_latency(target_per_request_usd: 0.05)
on_primary_outage: fallback
on_rate_limit: fallback
on_budget_pressure: fallback
}
api_explorer · collection · capturetyped Try-it surface + replayable checks
src/explorers/hospital.carrier
HospitalApi
api_explorer HospitalApi {
upstream: service
mount_target: full_panel
collection AdmissionFlow {
step admit {
call: action admit_patient
params: { input: { mrn: "TEST001", age: 65 } }
capture {
admission_id: response.id
admitted_at: response.admitted_at
}
}
step record_vitals {
call: route POST "/vitals/{admission_id}"
params: { admission_id: admission_id }
input: { admission_id: admission_id, bp: "130/85", hr: 72 }
assert: status == 200 && response.recorded_at > admitted_at
}
}
safety {
redact_pii: auto
audit_every_request: true
max_environment: dev_or_staging
}
}
pdf.render_svg_template · blobcertificates · invoices · branded reports
src/certificates.carrier
ryt-200 certificate
type CertificateContext {
recipient_name: String
completion_date: String
instructor_name: String
}
route POST "/certificates/{recipient_name}" public -> String {
handler {
let ctx = CertificateContext {
recipient_name: params.recipient_name
completion_date: "April 23, 2026"
instructor_name: "Niko Ma"
}
let pdf = pdf.render_svg_template(
load_template("ryt200.svg"),
ctx,
"/tmp/certs/" + ctx.recipient_name + ".pdf",
font_paths: ["/fonts/PlayfairDisplay.ttf"],
resource_dir: "/tmp/cert-assets",
title: "RYT-200 Certificate"
)
let stored = blob.put(pdf.path, "certs/" + ctx.recipient_name + ".pdf", pdf.content_type)
return blob.signed_url(stored.key, expires_seconds: 300, download_name: pdf.filename)
}
}
rag
One declaration binds a retriever (Model.similar_with_scores), embedder, and llm client. Trim to context budget, optional rerank by score threshold.
agents · routed
llm client routed wraps primaries + fallbacks with cost_vs_latency routing, budget_per_tenant_per_day_usd ceilings, and downgrade behavior on outage / 429 / 5xx.
api_explorer
Typed Try-it surface generated from the same manifest. Federated upstreams via imported manifests. Replayable collection / step / assert / capture checks.
native PDF
pdf.render_html(...) for deterministic text-first PDFs; pdf.render_svg_template(...) for rich visual SVG-driven output with custom fonts and assets.
carrier remote · deploy · k8s · edgeCarrier Cloud + self-hosted targets
zsh
reproducible HTTPS bundle
# log in to Carrier Cloud
$ carrier remote login --base-url https://cloud.carrierlang.com
# reproducible HTTPS upload; poll until terminal state
$ carrier remote deploy --service clinic-app --wait
# live tail + open
$ carrier remote status clinic-app
$ carrier remote logs clinic-app
$ carrier remote open clinic-app
# k8s + edge targets for self-hosted stacks
$ carrier deploy k8s --multi-region
$ carrier deploy edge --target cloudflare
MCP servers
Compiled service binary speaks MCP over stdio: .carrier/build/<svc> mcp. Actions become synchronous tools; workflows enqueue runs and return run_id. Schemas come straight from the Carrier compiler.
Recipes & registry
Modules + recipes share one publish/install path. carrier publish carrier install with locked checksum, signature, provenance, and SBOM. Recipes ship vertical analytics packs.
Compliance bundles
carrier compliance generate --standard hipaa writes evidence bundles backed by Carrier metadata and observed audit data. Hash-chain verification via verify-audit-chain.
What 1.3 adds

Node target, remote build, Tank hardening, SLAs, formal invariants, RN SDK.

The 1.x line keeps the same compiler-checked envelope and adds the surfaces production AI-friendly backends actually need: three codegen targets (Rust, Spring Boot, Node), SSH remote build, runtime depth limits + Flight Recorder, first-class SLAs, deterministic invariant verification, and a React Native SDK generator.

--target rust | java | nodeone source, three runtimes, identical migrations
zsh
dual-target compile
# production native Rust binary Tokio + Axum + sqlx
$ carrier build --target rust --release
$ ./.carrier/build/clinic-app
# Spring Boot service Java 21, JDBC + HikariCP
$ carrier build --target java --release
$ java -jar .carrier/generated-java/target/clinic-app.jar
# dev iteration target Fastify + pg, ~200ms restart
$ carrier build --target node
$ node .carrier/generated-node/main.mjs
# the migration SQL is byte-identical across all three targets
# develop with node, ship to Rust or Spring Boot from the same source
--compile-remote=trueSSH build server · rsync round trip
zsh
remote build
# rsync project up, run carrier on the build server, fetch artifacts
$ carrier build --target rust --release --compile-remote=true
# upload + remote build streams progress live; nothing is silent
# the remote command always runs with --compile-remote=false (no recursion)
# default rsync excludes: target/, .carrier/, node_modules/, .git/,
# .env, .env.*, secrets/, credentials/, service-account*.json
# Carrier never ships your .env files
runtime · Tank limitsdepth guards, panic capture, ops_routes
src/main.carrier
service.runtime
service App {
openapi { title: "Tank-Hardened API" version: "1.0.0" }
runtime {
request_depth_limit: 32
action_depth_limit: 16
workflow_depth_limit: 16
expression_depth_limit: 64
json_body_depth_limit: 16
schema_expansion_depth: 16
body_size_limit: 2_megabytes
artifact_size_limit: 50_megabytes
request_timeout_ms: 5_000
panic_policy: catch
evidence: emit_when_explicitly_enabled
ops_routes: local_only
}
}
harden · tune · verifylocal attack harness with sandbox DB
zsh
Carrier Tank
# 1. local sizing advisor
$ carrier tune --profile production
# writes .carrier/tune.json + .carrier/tune.runtime.carrier (copy-ready)
# 2. budgets + verification + invariant proofs + tests
$ carrier check --verify --profile production --fail-on-unknown
# 3. attack harness health/auth/depth/oversize/concurrency probes
$ carrier harden --chaos --run --sandbox-db
# spawns the binary on loopback, mints tenant A/B JWTs,
# probes isolation, drops the owned database after probes
# 4. live evidence + Flight Recorder
$ curl -s http://127.0.0.1:4000/ops/flight?request_id=... | jq
invariant · verificationz3 + bounded fallback, deterministic
src/invariants.carrier
must_always · must_never · transition
verification {
solver: z3
mode: bounded
max_records: 1
max_workflow_depth: 10
timeout: 30_seconds
}
invariant InventoryNeverNegative {
subject: InventoryItem
must_always: quantity_on_hand >= 0
}
invariant LabResultRequiresReviewer {
subject: LabResult
transition: status -> "reviewed"
requires: reviewed_by != ""
}
invariant NoProviderOverlap {
subject: Appointment
must_never:
exists other Appointment where
other.provider_id == provider_id &&
overlaps(other.start_slot, other.end_slot, start_slot, end_slot)
}
assume StripeDoesNotOverRefund {
external: stripe.refund
guarantees: refund.amount <= charge.remaining_refundable_amount
}
sla · attainment · escalationsource-controlled service-level contracts
src/slas/sepsis.carrier
SepsisBundle
sla SepsisBundle {
workflow: AdmitSuspectedSepsis
starts_when: step_started("RecordVitals")
ends_when: step_completed("CompleteBundle")
attainment: 95%
deadline: 4_hours
warning_at: 80%
breach_at: 100%
scope: tenant
measure_by: calendar_month
escalation: notify(role: "charge_nurse") on breach_imminent
compliance_evidence: attach_to_audit
report: include_in("ClinicalQualityDashboard")
exclude_when: field("comfort_care_only") == true
}
role hierarchy · JWKS · all_rolesroles include other roles, AND-gating
src/auth.carrier
auth jwt · roles { ... }
auth jwt AdminAuth {
issuer: env("JWT_ISSUER", "carrier")
audience: env("JWT_AUDIENCE", "carrier-users")
secret: env("JWT_SECRET", "local-dev-secret")
jwks_url: env("JWT_JWKS_URL", "")
roles_claim: "roles"
roles {
super_admin includes [admin]
admin includes [editor, viewer]
editor includes [viewer]
}
}
route POST "/orgs/{id}/archive"
protect AdminAuth all_roles [admin, compliance_officer]
-> Org
{
params { id: UUID }
handler { return Org.archive(params.id) }
}
carrier sdk react-nativemanifest-driven mobile SDK
zsh
offline mutation queue
# manifest-driven React Native SDK no recompile needed
$ carrier check
$ carrier sdk react-native --output mobile/carrier-sdk
# generated package exposes:
# createCarrierSdk(...) low-level fetch client
# createTokenSession(...) JWT/session hook
# CarrierMutationQueue persisted offline queue (idempotency keys)
# useCarrierQuery(...) React hooks layered on top
# useCarrierMutation(...)
# useCarrierSubscription(...) typed realtime helpers
# offline queue guarantees:
# queued writes survive restart (with a storage adapter)
# deterministic replay ordering
# stable Idempotency-Key per write
# bounded retry backoff
# conflicts + poison items stay visible to the app
Rust · Java · Node
All three targets share lex/parse/semantic/IR — they diverge only at codegen. Migration SQL is byte-identical across the trio. Develop against Node (~200ms restart), ship to a Rust binary or Spring Boot service from the same source tree.
Remote build
[remote_build] in carrier.toml + an SSH host. Carrier rsyncs up, builds, fetches artifacts back. Excludes .env, target/, node_modules/ by default.
Tank hardening
harden --chaos --run --sandbox-db spawns the binary on loopback, mints tenant A/B JWTs, runs health/auth/depth/oversize/concurrency probes, drops the owned DB.
Verification
invariant + verification + assume compile to deterministic bounded checks. z3 when on PATH, else a deterministic fallback.
Compiler pipeline

A real compiler, not a macro wrapper over a web framework.

Each stage has a clean responsibility and lives in its own crate. Carrier separates language surface from runtime, so the generated Rust service stays boring and reviewable.

01
.carrier
source
02
lexer
tokens
03
parser
AST
04
semantic
types · validation
05
IR
lowering
06
codegen
rust
07
cargo / rustc
build
08
service
native binary
crates/carrier-*.carrier/build/<binary>
Source
.carrier files under src/. Every file compiles together, sorted by path.
Generated
.carrier/generated/ holds the Rust service, migrations, and the machine-readable manifest.
Binary
.carrier/build/<binary> is a native service. Tokio async server, /health, /ready, /openapi.json, /docs.
Language primitives

Thirty-three top-level constructs. That’s the whole surface.

Carrier’s entire declaration surface fits on one screen. Every one of these is implemented in the 1.3.4 release candidate. Scope is the feature.

service
API surface · telemetry
runtime
Tank limits · ops_routes · panic
auth jwt
JWT · JWKS · role hierarchy
import
modules · registry refs
enum
named variants
type
records & projections
model
persisted records · Vector(N)
crud
generated resource endpoints
fn
pure helpers · native fn
action
business logic · transactions
policy
role · tenant · RLS SQL
route
HTTP · idempotent · telemetry
client
typed JSON · gRPC unary
llm client
typed tools · budgets · routed
agent
typed LLM agents · chat threads
rag
retriever + LLM, one declaration
workflow
steps · sagas · graph · retry
sla
attainment · deadline · escalation
invariant
z3 + bounded verification
event
durable events
job
async work
schedule
cron-driven jobs
queue
Redis · consumers · DLQ
tenant
lifecycle · retain N days
flag
percentage · tenant rules
ui
compiler-mounted Yew shells
api_explorer
typed Try-it surface
federated service
imported manifests · cross-svc
materialized_view
governed precomputed reads
analytics.report
typed analytics outputs
data_export
tenant-scoped exports
eval
graded LLM regression checks
finetune
curated training datasets
action · transaction · idempotent
api/src/main.carrier
row locking
/// Transaction-safe admin action with row locking
action audit_locked_doctor(id: UUID) -> Doctor {
let actor = auth.current_user()
transaction {
let locked = Doctor.get_for_update(id: id, scope: "all")
logs.info("doctor lock audit", {
action_name: "audit_locked_doctor"
doctor_id: locked.id
actor_email: actor.email
})
}
return Doctor.get(id: id, scope: "all")
}
/// Idempotent admin route; retries return the stored response
route POST "/admin/doctors/{id}/lock"
protect AdminAuth roles [admin] idempotent -> Doctor
{
params { id: UUID }
handler { return audit_locked_doctor(params.id) }
}
policy · tenant RLS · @version
src/00_models/slots.carrier
booking-service
policy AppointmentSlot {
tenant_field: org_id
read: roles [viewer, scheduler]
write: roles [scheduler]
deleted: roles [scheduler]
}
model AppointmentSlot {
id: UUID
org_id: String @index
clinician_name: String @length(min: 3, max: 120)
starts_at: Time
status: SlotStatus = open
version: Int @version
deleted_at: Time?
created_at: Time
updated_at: Time
}
Runtime · platform

Postgres-first. Jobs, cache, idempotency, RLS — built in.

Generated services depend on the Carrier runtime for the boring, load-bearing parts you’d otherwise rebuild per project.

Postgres models & migrations
Generated migrations, schema snapshots, row locking via get_for_update, optimistic @version, and explicit scopes for soft-deleted records.
Policies & RLS SQL
policy compiles to PostgreSQL ENABLE ROW LEVEL SECURITY. Per request, the runtime sets carrier.current_roles and carrier.current_tenant.
Jobs · schedules · events
Durable jobs backed by Postgres. Cron-style schedules polled by the runtime. Emitted events recorded in a first-class events table.
Cache with graceful fallback
cache.get_as, cache.set, redis.publish. Uses Redis when REDIS_URL is healthy, otherwise an in-memory fallback.
Idempotent routes
Mark routes idempotent. Replays with the same Idempotency-Key return the stored response body without re-running the handler.
OpenAPI & manifest
Every build emits /openapi.json, /docs, and a first-class .carrier/manifest.json of declarations — AI-friendly, tooling-friendly.
search · cache · emitpublic search with 120s cache and event emission
api/src/main.carrier
GET /search/doctors
route GET "/search/doctors" public -> DoctorListResponse {
query {
q: String? specialty: String? city: String? country: String?
page: Int = 1 per_page: Int = 20
sort: String = "rating" direction: String = "desc"
scope: String = "active"
}
handler {
let key = "doctor-search:" + json.stringify({
q: query.q, city: query.city, page: query.page
})
if cache.exists(key) {
return cache.get_as("DoctorListResponse", key)
}
let result = Doctor.search(
q: query.q, city: query.city,
page: query.page, per_page: query.per_page,
sort: query.sort, direction: query.direction,
scope: query.scope
)
cache.set(key, result, ttl_seconds: 120)
emit DoctorSearchCached { cache_key: key, scope: query.scope }
return result
}
}
job · schedule · idempotent
src/15_async/jobs.carrier
booking-service
event SlotReminderQueued {
slot_id: UUID
trigger: String
}
job send_slot_reminder(payload: Json) -> Void {
logs.info("slot reminder job", { job_name: "send_slot_reminder", payload: payload })
audit.record("send_slot_reminder", "AppointmentSlot", "scheduled", payload)
}
schedule "*/15 * * * *" run send_slot_reminder
route POST "/slots/{id}/notify"
protect StaffAuth roles [scheduler] idempotent -> Json
{
params { id: UUID }
handler {
let job_id = jobs.enqueue("send_slot_reminder", { slot_id: params.id }, delay_seconds: 5)
emit SlotReminderQueued { slot_id: params.id, trigger: "manual" }
return { job_id: job_id }
}
}
Declarations
33
top-level constructs
Built-ins
auth · logs · cache · redis · audit · sql · db · jobs · flags · workflows · trace · metrics · pdf · blob · template · rag · math · finance · time · crypto · http
typed namespaces
Artifacts
manifest · OpenAPI · migrations · OTLP · MCP · k8s · edge · binary
Targets
Carrier Cloud · Compose · k8s · Cloudflare · Fastly
carrier deploy / remote
Stability

1.3.4 is the release candidate. 1.0 is a promise, not a rewrite.

The 1.0 surface is anchored by a written stability policy, fixture-based manifest/OpenAPI drift tests in CI, and a documented 1.x upgrade guarantee.

Stable surfaces
Language grammar, CLI commands, manifest keys, system-table column contracts, OpenAPI x-carrier-* extensions, OTLP attribute names, fail(code, message) shape.
Experimental surfaces
Generated Rust layout, vendored runtime internals, llm client grammar and runtime helpers, benchmark harness internals.
1.x upgrade path
Upgrade compiler → carrier check carrier migrate generate / up. No hand-edits to .carrier source or checked-in migrations.
Deprecation window
No silent removal in patch releases. Minimum 90-day deprecation notice, overlap for at least one later minor release before any stable surface is removed.
For AI generation

Precise enough for humans. Constrained enough for agents.

Carrier’s advantage isn’t maximal language power. It’s that the backend surface is small, explicit, and compiler-checked — exactly the shape that lets code generators stay consistent across a project.

Narrow syntax. Thirty-three declarations cover services, runtime, auth, CRUD, actions, policies, routes, clients, workflows, SLAs, LLM clients, agents, RAG, queues, tenants, flags, realtime, UI, api_explorer, evals, finetune, analytics, and bounded invariants. Fewer ways to be wrong.
Authoring tiers. The docs grade constructs: Tier 1 for first-pass-safe, Tier 2 for most services, Tier 3 for advanced runtime work. Start at the smallest tier that fits.
First-class manifest. Every project emits .carrier/manifest.json with models, routes, policies, jobs, schedules, and clients. Tools read it instead of scraping source.
Compiler feedback loop. carrier check runs the full semantic pass: type errors, CRUD misuse, auth/policy validation, invalid idempotency scope, and more.
Predictable layout. The multi-file convention (00_models, 10_types, 20_actions, 30_routes) keeps generation order stable across agents.
docs/ai-authoring.md
Generation recipe
// docs/ai-authoring.md — fast generation recipe
1. write carrier.toml
2. declare one service
3. add auth jwt if any route is protected
4. create enum used by models or query defaults
5. create model declarations
6. create type declarations for I/O and pagination
7. add crud for resource-like models
8. add policy for role or tenant visibility
9. add action for real business writes
10. add custom route
11. add job / event / schedule only when needed
12. add client for outbound integrations
13. add pure fn helpers last
Examples

Four checked-in examples. Ladder from minimal to platform.

Every example in the repository compiles today. They’re ordered so you can learn the language by walking up the ladder.

sql.list_as · typed rows
api/src/main.carrier
GET /reports/doctors/by-city
/// Admin reporting endpoint using raw SQL mapped into a typed result list
route GET "/reports/doctors/by-city" protect AdminAuth roles [admin]
-> DoctorCityReportRow[]
{
handler {
return sql.list_as(
"DoctorCityReportRow",
"select city, count(*)::bigint as total from doctors where deleted_at is null group by city order by total desc, city asc"
)
}
}
client · typed JSON
api/src/main.carrier
WeatherApi
client WeatherApi {
base_url: env("WEATHER_API_URL", "https://api.example.com")
header "x-api-key": env("WEATHER_API_KEY", "")
timeout_ms: 3000
}
type WeatherResponse {
city: String
temperature_c: Float
condition: String
}
route GET "/weather/{city}" public -> WeatherResponse {
handler {
return WeatherApi.get("/forecast", query: { city: params.city })
}
}
Quickstart

From zero to a native binary in three commands.

The compiler workspace is a Rust project; Carrier services compile through it.

compiler workspace
$ cargo test
$ cargo run -p carrierc -- --help

Build and test the compiler. The carrierc CLI scaffolds projects, type-checks .carrier sources, generates Rust + OpenAPI + migrations, and drives build, run, and dev.

a service
# new project, then in the project root:
$ carrier check
$ carrier build
$ carrier run # or ./.carrier/build/<binary>
$ carrier openapi > openapi.json
$ carrier migrate generate

Works identically across every example in the repo — hello-carrier, inventory-control, booking-service, and the flagship api/.

Current limits
Imports are validated metadata, not selective loaders. Migration diffing is structural and does not infer renames automatically.
Observability
JSON logs to stdout with structured metadata. Audit records, events, jobs, and schedules are durable. Full tracing/metrics backends are external integrations.
Transactions
transaction { } opens a real DB transaction. return inside the block is not supported yet — return after the block closes.

Fast, secure APIs with less code.
Compiled, not configured.

Read the language reference, review the benchmark numbers, walk the examples, and ship a native service binary.