Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Platform Map

QAIL is a small platform made of separate crates. The important split is not the crate names; it is which layer owns which safety boundary.

Layers

LayerCrateOwns
AST Kernelqail-coreQuery structure, values, expressions, RLS context, schema AST, migration planning, access-policy checks
Postgres Driverqail-pgPostgreSQL protocol execution, typed value encoding, RLS session setup, pooling, prepared statement cache
Access Gatewayqail-gatewayHTTP/WebSocket surface, JWT/dev auth, REST/RPC mapping, tenant guard, allow-listing, gateway policy checks
SchemaOps CLIqailschema.qail workflows, pull, check, live diff, phased migration apply, typed codegen
Flow Engineqail-workflowWorkflow state machine, waits, resumes, timeouts, branch cursors, side-effect checkpoint hooks
Flow Ledgerqail-workflow-postgresPostgres-backed workflow state, leases, idempotency ledger, side-effect replay, timeout due-row discovery
Vector Bridgeqail-qdrantQdrant vector search and tenant-aware metadata filters

Choose The Smallest Surface

Use qail-core + qail-pg when your app already owns routing, auth, and business logic. This is the normal Rust driver mode:

#![allow(unused)]
fn main() {
use qail_core::prelude::*;
use qail_pg::PgDriver;

let ctx = RlsContext::tenant(tenant_id).with_user(user_id);
let cmd = Qail::get("orders")
    .columns(["id", "status", "total"])
    .eq("status", "paid")
    .with_rls(&ctx)?;

let rows = driver.fetch_all(&cmd).await?;
}

Use qail-gateway when the database schema should become a controlled API surface. The gateway adds HTTP/WebSocket routing, JWT authentication, operation/column access policy, request limits, EXPLAIN guardrails, and tenant-boundary checks around the same AST path.

Use qail when changing schema. The CLI is the state/schema tool: it can pull a live PostgreSQL schema, validate schema.qail, compare drift, and apply explicit expand/backfill/contract migrations.

Use qail-workflow when business flows need durable pause/resume semantics. Use qail-workflow-postgres when those flows need production storage for leases, idempotency, side-effect replay, and timeout due-row discovery.

Use qail-qdrant only for vector workloads. It is not a relational database adapter; it shares the tenant-aware AST model where that maps cleanly to Qdrant filters.

Safety Ownership

QAIL does not claim that one crate magically owns every safety property. The boundaries are explicit:

Safety propertyOwner
No application SQL interpolation on the AST pathqail-core builders + qail-pg execution
Row isolationPostgreSQL RLS policies, with QAIL setting transaction-local context
Operation and column permissionsqail_core::access, optionally loaded by qail-gateway
HTTP auth and request shapingqail-gateway
Schema drift detectionqail CLI and qail-core migration planner
Durable workflow replay protectionqail-workflow hooks + executor implementation
Postgres-backed workflow leases/idempotencyqail-workflow-postgres
External provider exactly-once behaviorThe application/provider via idempotency keys

Supported Backends

PostgreSQL is the primary SQL backend. The AST, migration model, RLS context, gateway, and workflow ledger are designed around PostgreSQL semantics.

Qdrant is supported for vector search through qail-qdrant.

Other database protocols are not part of the supported runtime surface. QAIL does not fake support for engines whose semantics do not map cleanly to its AST model.

Naming

The crate names are intentionally literal. The docs use product names to make the architecture easier to discuss:

  • AST Kernel: qail-core
  • Postgres Driver: qail-pg
  • Access Gateway: qail-gateway
  • SchemaOps CLI: qail
  • Flow Engine: qail-workflow
  • Flow Ledger: qail-workflow-postgres
  • Vector Bridge: qail-qdrant

When debugging production behavior, start from the product name and then inspect the owning crate.