PLAN.md
Single source of truth for project status. Update at the start and end of
every work session. If this file is stale, nothing else in the repo can
be trusted to reflect reality.
Current status
- Active phase: 2.0.8 pre-release hardening β β all items complete. Wheel built, demo_shop 29/29 passes, pytest 159/159, cargo workspace 493+ passes.
- Status: All post-2.0.7 gaps closed (2026-07-25). AI / inference / LLM work FROZEN until release 2.0.8 (ADR-067). Focus from 2026-07-25 session:
- Generator dependencies (FastAPI-style
yieldin Depends) β β complete._resolve_kwargs/_resolve_dependencies_listdetectinspect.isasyncgenfunction/isgeneratorfunction, advance generator once, registergen.aclose()/gen.close()inrequest["_dep_cleanup"]. Handler wrappers run cleanup infinallyblock (LIFO order). 6 tests (async gen, sync gen, cleanup on error, nested, cached, no-cache). - ORJSON as optional Rust-level serializer β β
complete.
orjsonfeature injustapi-core/justapi-pyhard-requires Pythonorjsonmodule when enabled (panics with clear message if missing).orjson>=3.10added to pyproject.toml as[orjson]extra and included in[full]. 7 tests. - Production panic hotspot audit β β
complete. Fixed 6 categories of
unwrap()panics on request hot path: CORSOriginparse (user-triggerable crash, highest risk),Bound::newconstruction, multipart formset_item,conn_semaphoreacquire,json_value_to_requestprimitive conversions. - PyPI wheel β built (
manylinux_2_34_x86_64, 32 MB). Unpublished β blocked onMATURIN_PYPI_TOKEN.
- Generator dependencies (FastAPI-style
- Demo_shop stress test (2026-07-18) β all D1βD4 defects fixed. All 23 endpoints pass; 29-assertion e2e test passes. Framework gotchas documented in demo_shop/README.md (both resolved in framework).
- Gates (2026-07-25):
cargo test --workspace(493+ all pass) β ,cargo clippy --workspace --tests -- -D warningsβ ,cargo fmt --checkβ , pytest 159 passed / 1 skipped β , demo_shoptest_app.py29/29 β . - Blocker: none. Outstanding: PyPI publish (needs
MATURIN_PYPI_TOKENenv var).
Mission
Build JustAPI β a production-grade Python web framework that beats FastAPI
on every benchmark while matching or exceeding it on DX, security, and
cloud-native readiness.
Phase table
| # | Phase | Status | Notes |
|---|---|---|---|---|
| 0 | Foundations | β
complete | Skeleton, CI, skills, baselines |
| 1 | Minimal Viable Runtime | β
complete | HTTP/1.1, routing, PyO3, CLI |
| 2 | Native Router | β
complete | matchit radix trie, route params |
| 3 | Memory & Zero-Copy Pipeline | β
complete | arena+pool, 752k req/s |
| 4 | Execution Model & GIL Strategy | β
complete | ADR-008: dedicated Python worker thread |
| 5 | Middleware Engine + Auth | β
complete | CORS, SecurityHeaders, JWT, RateLimiter, 0.18% overhead |
| 6 | Serialization | β
complete | serde_json (89ns), simd-json feature |
| 7 | TLS + HTTP/2 | β
complete | rustls, ALPN, 10.7% overhead |
| 8 | WebSocket + SSE | β
complete | tokio-tungstenite, SSE streaming |
| 9 | Static Assets, Caching, Observability | β
complete | StaticDir, Prometheus, compression, OTel |
| 10 | ASGI Shim + Native API | β
complete | Tier A+B, graceful shutdown, 81 tests |
| 11 | Request Validation & Serialization | β
complete | JSON Schema validation, Pydantic bridge, 97 tests |
| 12 | Database ORM Integration | β
complete | Pool, migrations, query builders, Python bridge |
| 13 | Testing Utilities | β
complete | TestClient, async fixtures, snapshot testing |
| 14 | Production Observability | β
complete | Metrics histograms, structured logging, health checks, alerting, audit, panic recovery |
| 15 | Graceful Degradation & Circuit Breakers | β
complete | 44 resilience tests, generic B support |
| 19 | Plugin System & Extensibility | β
complete | third-party plugin API |
| 20 | Benchmark & Optimization (Beat FastAPI) | β
complete | final gate, prove superiority |
| 21 | Advanced DX: Signature Parsing & DI | β
complete | Depends(), auto-extract args |
| 22 | True Async & Advanced Web Features | β
complete | No-block async, WS/SSE, BackgroundTasks |
| 23 | Templating Engine Integration | β
complete | Jinja2/MiniJinja support |
| 24 | gRPC & Protobuf Support | β
complete | Native gRPC via Tonic |
| 25 | Ultimate Scale (1M RPS tuning) | β
complete | Hyper-optimization for 1M RPS |
| 26 | Zero-Copy AI Data Boundary | β
complete | Arrow/DLPack via PyO3 buffer protocol |
| 27 | Adaptive Batching Router | β
complete | ML model serving |
| 28 | WASM Middleware Engine | β
complete | wasmtime embedded |
| 29 | High-Throughput LLM Streaming (SSE 2.0) | β
complete | TokenStreamResponse |
| 30 | Layered Dependency Injection | β
complete | Litestar-style DI |
| 31 | Class-Based Controllers & Route Composition | β
complete | @controller classes |
| 32 | Native Enterprise Rate Limiting | β
complete | GCRA + Redis |
| 33 | Circuit Breakers & Graceful Degradation | β
complete | 44 resilience tests |
| 34 | Dynamic Configuration (Hot Reloading) | β
complete | file watcher + admin API |
| 35 | GraphQL & Federation Gateway | β
complete | async-graphql, Apollo Federation |
| 36 | Agentic Workflow DAG Engine | β
complete | DAG orchestration in Rust |
| 37 | OTel Distributed Tracing | β
complete | OTLP, contextvars, 225 tests |
| 38 | Hardware-Accelerated JWT & Security | β
complete | RS256/ES256, CORS builder, IpRateLimiter, 236 tests |
| 39 | SAST, Fuzzing & Memory Safety | β
complete | 6 fuzz targets, miri, SAFETY comments, 236 tests |
| 40 | The JustAPI 2.0 "Singularity" Release | π‘ in progress | Consolidated Py package, OpenAPI, README, Docker (155MB), abi3 wheel, ARCHITECTURE.md, CONTRIBUTING.md. PyPI upload pending token + manylinux_2_28 build |
| 41 | Native Inference Engine Foundation | β
complete | justapi-inference crate on Candle (CPU default; cuda feature-gated), Engine/Model trait, streaming, 24 tests pass |
| 42 | KV-Cache Manager (PagedAttention, Rust) | β
complete | KvBlockPool paged allocator + clock eviction, PrefixCache hash-based prefix reuse, Sequence handles. 16 tests, 260 workspace total |
| 43 | Continuous-Batching Scheduler | β
complete | Scheduler with prefill/decode interleave, chunked prefill, back-pressure, prefix-cache integration. 9 tests, 269 workspace total |
| 44 | OpenAI-Compatible API Server | β
complete | /v1/chat/completions, /v1/completions, /v1/embeddings, /v1/models wired to justapi-inference (GIL-free); streaming SSE; feature-gated inference |
| 45 | Quantization + Multi-LoRA | β
complete | AWQ/GPTQ/FP8 GGUF quant + LoRA adapter registry + RealModel forward pass (all feature-gated real) |
| 46 | LLM Control Plane | β
complete | model registry/versioning, KV-aware routing, LLM autoscaling (KV-pressure/TTFT), multi-replica supervisor |
| 47 | FastAPI Parity (model-deploy essentials) | β
complete | ApiKeyAuth + OAuth2Password + multipart + Form/Cookie/Header + JsonResponse
| 48 | Production Hardening for AI | β
complete | speculative decoding + disaggregated P/D + structural benchmark vs vLLM/SGLang + K8s AI inference gateway plugin (97 inference tests) |
| 49 | Tree-based Speculative Decoding | β
complete | Medusa/EAGLE-style tree verification wired into serving path. Acceptance rate up to 3Γ higher than draft-target. |
| 50 | RadixAttention Prefix Caching | β
complete | RadixPrefixCache wired into Scheduler: O(1) prefix lookup on admission, LRU eviction, finished-seq block promotion. |
| 51 | Scheduler Serving Integration | β
complete | SchedulerEngine bridges Engine+Scheduler; prefix cache metrics in /metrics; sampling params plumbed; real throughput benchmark. 151 inference tests. |
| 52 | GPU Benchmark Gate | π΄ frozen β AI deferred to 2.0.8 | Run SchedulerEngine vs naive vs vLLM on real GPU with real weights. Measure tokens/sec, TTFT, ITL. DEFERRED: no CUDA driver upgrade, no real-weight run (ADR-067). MockModel CPU run only as plumbing check. |
Phase 0 β Foundations (completed 2026-07-03)
- Repository skeleton (workspace Cargo.toml, 4 crates, python/ package)
-
PLAN.md,AGENTS.md,DECISIONS.md,BENCHMARKS.mdcreated - Seed skills:
rust-ffi-safety,benchmark-harness - CI green on skeleton, baseline benchmarks recorded vs Uvicorn/FastAPI + Granian
Phase 1 β Minimal Viable Runtime (completed 2026-07-03)
- tokio+hyper HTTP/1.1 server, PyO3 embedding,
/hello+/echoroutes -
justapi serveCLI, unit + integration tests, proptest fuzz corpus - Benchmark: 766k req/s vs Granian 314k β 2.4x faster
Phase 2 β Native Router (completed 2026-07-03)
-
matchitradix trie,Router<Handler>with route params + catch-all - 9 router tests, 51ns avg lookup on 500-route table
Phase 3 β Memory & Zero-Copy Pipeline (completed 2026-07-03)
-
RequestArenabump allocator,SharedArena,BufferPool(4 buckets) - 7 memory tests, 752k req/s (no regression)
Phase 4 β Execution Model & GIL Strategy (completed 2026-07-03)
- ADR-008: dedicated Python worker thread (zero GIL contention)
-
py-nogilfeature flag for PEP 703 free-threaded CPython
Phase 5 β Middleware Engine + Auth (completed 2026-07-03)
-
Middleware<B>trait,MiddlewareChain, Cors, SecurityHeaders, JwtAuth, RateLimiter - 12 middleware tests, 0.18% overhead
Phase 6 β Serialization (completed 2026-07-03)
-
serialize.rsβto_json_string/to_json_vec, serde_json default, simd-json feature - serde_json: 89ns/op, 11.2M ops/sec
Phase 7 β TLS + HTTP/2 (completed 2026-07-03)
- rustls 0.23, ALPN h2+http/1.1,
Server::with_tls(TlsConfig) - TLS overhead: 10.7% (under 15% target)
Phase 8 β WebSocket + SSE (completed 2026-07-03)
- tokio-tungstenite echo WS, SSE
/events, TCP-peek WS upgrade - 37 tests, clippy + fmt clean
Phase 9 β Static Assets, Caching, Observability (completed 2026-07-05)
- Compression (Gzip/Deflate/Brotli/Zstd), StaticDir (ETag, 304, 206), Metrics (Prometheus), OTel tracing, health endpoints
- 82 tests (70 unit + 12 integration), 5 feature combos tested
Phase 10 β ASGI Shim + Native API (completed 2026-07-05)
Tier A β ASGI Shim
-
Server::with_handler(),MiddlewareChain::set_handler() - ASGI worker thread with persistent asyncio event loop,
serve_with_app() - Lifespan protocol, streaming response via
ResponseEventbridge
Tier B β Native API
-
JustAPIApppyclass:Router<usize>,get/post/put/deleteregistration - Dedicated Python worker thread (ADR-008),
NativeJobβoneshotdispatch -
JustAPIApp.run(addr):py.detach()+ tokio runtime - Python helper: auto async detection, JSON-wrapping
- Graceful shutdown:
Server::with_shutdown(CancellationToken), Ctrl+C handler - 5/5 Python integration tests passing
Exit criteria
- 81 tests (70 unit + 11 integration), clippy + fmt clean
- Python end-to-end test: path params, POST echo, 404 routing
Phase 11 β Request Validation & Serialization (completed 2026-07-05)
Goal: Match FastAPI's Pydantic experience β type-safe request/response contracts with automatic validation, serialization, and error messages.
Actual implementation: Rust-native JSON Schema validation via jsonschema crate (fast path, zero Python GIL), with Python Schema class and Pydantic bridge for schema definition. Error format RFC 9457.
Deliverables
- JSON Schema validation β
validate_json_schema()validates JSON bytes against JSON Schema entirely in Rust, zero GIL round-trips - Python
Schemaclass β__init_subclass__generates JSON Schema from type annotations (str,int,float,bool,bytes,list[T],dict[str, V],Optional[X]) - Pydantic bridge β
pydantic_schema()extractsmodel_json_schema()(v2) orschema()(v1); Rust-sideresolve_schema_json()auto-detects type - Native API integration β
post()/put()acceptschemaparameter; validation runs in Rust before Python dispatch; 422 for invalid requests with zero Python context switch -
formatkeyword enforced on the live HTTP path βjustapi_core::validatebuild_validatorregisters email/uri/uuid/date-time/date/hostname/ipv4 checkers +should_validate_formats(true), so both one-shot and precompiled (CompiledValidator) validators assertformat. Previously only the in-processvalidate_valuepath enforcedformat; the server path silently accepted violations. Regression test:test_schema_hardened.py::test_server_path_enforces_format. - Error format β RFC 9457 β structured
ValidationErrorresponses matching Problem Details for HTTP APIs
Tests
- 4 Rust unit tests for
validate_json_schema(valid, missing field, wrong type, invalid JSON body) - 9 Python integration tests (Schema class valid/missing/wrong-type, Pydantic bridge, raw JSON Schema string, invalid JSON body)
- Backward-compatible: existing
body_schemaPython-callable path preserved
Exit criteria
- 97 tests (86 unit + 11 integration), clippy + fmt clean
- JSON Schema validation in Rust with zero Python GIL round-trips
Phase 12 β Database ORM Integration (completed 2026-07-05)
Goal: Built-in async database integration β SQL migrations, connection pooling, query building β without the cognitive load of SQLAlchemy.
Deliverables
- Connection pool manager β
AnyPoolenum (Pg/Sqlite/MySql),DatabaseConfig,PoolManagerwithinit()/get()/default()/health_check_all(),DbKind::from_url()auto-detection; 2 unit tests - Migration system β
Migrationstruct withparse_filename()/parse_content()/from_file(),Migratorwithdiscover()/run()/rollback_one()/ensure_tracking_table()/get_applied_versions()/record_migration();_justapi_migrationstracking table with per-DB SQL; 5 unit tests - Query builder β
Select/Insert/Update/Deletebuilders withbuild()methods;Select::build_count(); 9 unit tests - Model trait β
Modeltrait withtable_name()/pk_column()/count()defaults; 16 total db unit tests - Python
Databaseclass β stores URL/max_connections,set_database()onJustAPIAppaccepts Database or URL string - Pool initialization in
run()β pool auto-initialized inside tokio runtime before server start - CLI migration commands β
justapi db migrate,justapi db rollback,justapi db init - Transaction middleware β auto-begin for POST/PUT/DELETE, commit on 2xx, rollback on error;
db_urlpassed to Python handlers via request dict
Design decisions
sqlxv0.8 withruntime-tokio+postgres+sqlite+mysql+migratefeaturesAnyPoolenum over trait objects β match dispatch avoids dynamic dispatch overhead- Feature-gated behind
dbflag injustapi-core - Migrations as plain SQL in
migrations/directory (no DSL lock-in)
Exit criteria
- Full CRUD app running with PostgreSQL. Migrations up/down working.
justapi dbCLI subcommands functional. 30+ tests.
Phase 13 β Testing Utilities (completed 2026-07-05)
Goal: Developer experience parity with FastAPI's TestClient β write tests the same way, but they run faster.
Deliverables
-
TestClient: Rust test client using tokio duplex + hyper HTTP/1.1 parser (no TCP socket, sub-ms test latency),TestResponsewith status/headers/body - JustAPITestClient pyclass: wraps Rust
TestClientβ GIL-free, no dedicated worker thread,OnceLock<HelperFunctions>for helper module caching - AsyncTestClient: async context manager wrapping
JustAPITestClientwithasync get/post/put/deletemethods, sync/async setup/teardown hooks - Assertion helpers:
assert_ok,assert_status,assert_json,assert_headerβ composable response assertions - Database test helpers:
ManagedDbasync context manager,test_db()factory,db_client()helper with seed SQL,transaction_test_db()for transactional rollback - Snapshot testing:
Snapshotclass withassert_match/assert_response/assert_body,.snapfiles in__snapshots__/,SNAPSHOT_UPDATE=1for auto-accept, unified diff on mismatch - Transaction middleware in test client: auto-begin for POST/PUT/DELETE, commit on 2xx, rollback on error
- Coverage: 43 Python integration tests, 114 Rust tests, clippy + fmt clean
Design decisions
- Test client calls handler directly (no TCP stack) for sub-millisecond test latency β tokio duplex + hyper HTTP/1.1 parser
- Full middleware chain runs β same behavior as production
- Python
JustAPITestClientwraps Rust test client via PyO3 β no worker thread, GIL acquired viaPython::try_attach - Snapshot testing custom implementation (not
insta) β tighter Python integration, caller detection via stack frame walk
Exit criteria
- Test client usable from both Rust and Python. 43 integration tests for test utilities. Benchmark shows 5x+ vs FastAPI TestClient.
Phase 14 β Production Observability (completed 2026-07-05)
Goal: Production-grade observability β structured logging, enhanced metrics, health checks, alerting, audit logging, panic recovery β with observability overhead < 5% p99 latency.
Deliverables
- Enhanced Metrics: Bucket-based latency histograms (Prometheus-compatible: 1msβ10s, 13 buckets), status-code tracking (2xx/3xx/4xx/5xx),
record_status(),record_latency(),percentiles()(p50/p95/p99/p999),snapshot(),RequestTimer. Backward-compatible with existingMetricsAPI. - Structured Logging:
LoggingConfigwithLogFormat::Text/Json,FileRotation::Daily/Hourly/Never, configurable log level via env-filter.init_logging(),init_json_logging(),init_file_logging(). Usestracing-subscriberjson feature +tracing-appenderfor rolling file output. - Health Check System:
HealthChecktrait,HealthRegistrywithregister()/register_fn()/check_all()/health_response().HealthStatus::Healthy/Degraded/Unhealthy. Returns 200 (all healthy) or 503 (any unhealthy).DbHealthCheck(feature-gated ondb). Per-component JSON output. - Alerting:
AlertingConfigwith webhook URL, severity filter, channel type (Slack/PagerDuty/Generic). Payload builders for Slack attachments, PagerDuty Events API v2, and generic JSON. HTTP-only POST dispatcher viatokio::net::TcpStream. Severity filtering (Info/Warning/Critical). Logs locally when webhook not configured. - Audit Logging:
AuditLoggingmiddleware withAuditRule(filter by method + path prefix).wrap_handler()returns wrappedHandlerFnemittingtracing::info!withaudit=true, method, path, status, duration_us. Default rule captures POST/PUT/DELETE/PATCH on all paths. - Panic Recovery:
with_panic_recovery()wrapsHandlerFnwithstd::panic::catch_unwind+FutureExt::catch_unwind. Custom panic hook logs panic message + location viatracing::error!(panic=true). Returns 500 JSON response on panic; convertsanyhow::Errorto 500. - Server wiring: Both HTTP and TLS service functions call
metrics.record_status(status)andmetrics.record_latency(ms)on every request. - 121 Rust unit tests, 43 Python integration tests, clippy + fmt clean.
Design decisions
tracingas the foundation β structured, async-aware, ecosystem compatible. JSON output viatracing-subscriberjson feature, file rotation viatracing-appender.- Bucket-based latency histograms over HDR Histogram β avoids new crate dependency, 13 Prometheus-compatible buckets with
AtomicU64, zero-allocation record path. Percentiles computed from bucket distribution. - Health checks as a composable system β
HealthRegistryaggregates per-component checks,health_response()generates HTTP response. Backward-compatible with existing static/healthendpoint. - HTTP-only webhook dispatcher over
tokio::net::TcpStreamβ avoidsreqwestdependency. HTTPS not supported; users can proxy through local HTTP gateway. std::panic::catch_unwindover tokio task abort for panic recovery β wrapsBoxFuturedirectly viaFutureExt::catch_unwind, avoiding tokio task lifecycle complexity.- Audit logging as a
HandlerFnwrapper (not Middleware trait) β designed to be the last wrapper before the middleware chain, ensuring it captures final status after all middleware processes the request.
Exit criteria
- Full observability stack: enhanced metrics, structured logging, health checks, alerting, audit logging, panic recovery. 121 Rust tests, 43 Python integration tests. Overhead < 5%.
Phase 15 β Graceful Degradation & Circuit Breakers (completed 2026-07-05)
Goal: Resilience patterns β when dependencies fail, JustAPI degrades gracefully instead of crashing.
Deliverables
- Circuit breaker middleware: wraps external calls with configurable thresholds,
Closed/Open/HalfOpenstate machine,try_acquire()/record_success()/record_failure(), returns 503 withRetry-Afterwhen open - Bulkhead pattern:
tokio::sync::Semaphore-based concurrent request limiter, configurablemax_concurrent+max_wait, returns 503 when limit exceeded - Retry with backoff:
RetryPolicyutility struct with exponential backoff, configurablemax_retries/base_delay/max_delay/jitter,retryable()for idempotent operations. Not middleware (blocked byIncomingbody consumption) - Timeout middleware: per-route request timeouts via
tokio::time::timeout, returns 504GATEWAY_TIMEOUTwith descriptive JSON - Rate-limit backpressure:
RateLimiter(Phase 5) improved with governorDefaultClock::now()for correctRetry-Afterheader computation - Graceful degradation strategies:
FallbackPolicywith path-prefix matching + default fallback,FallbackMiddlewarereturns cached response on 5xx or handler error - Startup dependency check:
HealthRegistrypassed toServer,/readyendpoint checks registered health probes (falls back to simple{"ready":true}when no checks registered) - Chaos testing harness:
ChaosMiddlewarewith configurable latency injection, error injection, and enable/disable toggle - Generic body type support: all resilience middleware now
impl<B: Send + 'static> Middleware<B>(not tied toIncoming), enabling direct unit testing withFull<Bytes>body.MiddlewareChainimplementsClonefor test ergonomics
Design decisions
- Circuit breaker is custom (3 states,
Arc<Mutex<BreakerInner>>, 24 lines) β no new dependency (failsafeavoided) - Bulkhead via
tokio::sync::Semaphoreβ already in dependency tree - RetryPolicy as utility (not middleware) β
Incomingbody can't be cloned/replayed - Resilience middleware generic over
Bβ enablesTestBodyin unit tests without duplicateimpl Middleware<TestBody>blocks /readyusesHealthRegistryonly when checks are registered β backward-compatible with existing deployment expectations- ChaosMiddleware gated by
ChaosConfig::enabledflag β zero overhead when disabled
Exit criteria
- Circuit breaker opens on failures, recovers to half-open, reopens on half-open failure
- Timeout middleware returns 504 on deadline, passes fast requests
- Bulkhead limits concurrent requests, returns 503 when full
- Fallback returns cached response on 5xx and handler errors
- Chaos middleware injects configurable latency spikes and error responses
- Startup dependency check integrated with Server + HealthRegistry
- 44 resilience unit tests (41 middleware tests + 3 config default tests)
- All 167 workspace tests pass
-
cargo clippy --workspace -- -D warningsandcargo fmt --checkclean
Phase 16 β Multi-Cloud / Kubernetes Support (completed 2026-07-05)
Goal: Deploy JustAPI apps to any cloud β GKE, EKS, AKS, DigitalOcean, Railway, Fly.io β with first-class Kubernetes support.
Deliverables
- Dockerfile: multi-stage build (rust:slim β python:slim),
< 200MB(PyO3 embeds Python),HEALTHCHECKconfigured, stripped binary, non-root user - Docker Compose:
docker-compose.ymlwith services:justapi(build),db(postgres:16-alpine),redis(7-alpine),jaeger(all-in-one). Health checks, volumes, env vars - Helm chart: full chart at
helm/justapi/βChart.yaml,values.yaml,templates/(deployment, service, ingress, hpa, configmap, secret, serviceaccount, helpers) - Health check probes: K8s
livenessProbe(/live),readinessProbe(/ready),startupProbe(/live) β configurable thresholds and delays - Graceful shutdown: already implemented (SIGTERM β drain connections β stop)
- Horizontal Pod Autoscaler: HPA template with CPU (70%) and memory (80%) utilization targets, configurable min/max replicas
- K8s ingress config: NGINX Ingress template with TLS (cert-manager + Let's Encrypt),
ssl-redirectannotation - Environment-based config:
.env.examplewith all config vars, ConfigMap + Secret K8s templates, env var injection in deployment - CI/CD pipeline: GitHub Actions
dockerjob β Buildx + GHCR push, multi-tag (branch, semver, SHA), GHA cache layer. Runs on main push andv*tags - Cloud-specific examples: deploy guides for GKE, EKS, AKS, Fly.io, Railway in
deploy/clouds/ - Benchmark: K8s overhead vs bare metal documented in
BENCHMARKS.md(8.4% throughput overhead)
Design decisions
python:3.12-slim-bookwormas runtime base (PyO3 embeds CPython β can't use distroless)- Two-stage build: Rust builder stage β Python runtime stage (keeps final image under 200MB)
- Helm as primary deployment mechanism β NGINX ingress with cert-manager for TLS
- Config via environment variables with env var injection from ConfigMap + Secrets
- Health probes use existing
/live,/ready,/healthendpoints (already implemented) - GitHub Actions
docker/build-push-actionwith Buildx + GHCR + GHA cache layer
Exit criteria
- Dockerfile builds and produces a functional image
- Docker Compose starts all services (justapi, postgres, redis, jaeger)
- Helm chart installable with
helm install justapi helm/justapi - CI pipeline builds and pushes Docker image on main/tag pushes
- Cloud-specific deployment guides for GKE, EKS, AKS, Fly.io, Railway
- Benchmark: K8s overhead vs bare metal documented
Phase 17 β Zero-Day / SAST / Security Hardening (completed 2026-07-05)
Goal: Security-first by default β SAST scanning, dependency auditing, fuzz testing, and proactive vulnerability management.
Deliverables
- SAST (Static Application Security Testing):
cargo-audit+cargo-denyjobs in CI (blocking gate),.github/dependabot.ymlfor weekly dependency updates - Fuzz targets: 5
cargo-fuzztargets infuzz/βfuzz_jwt(malformed tokens, algorithm confusion),fuzz_headers(header name/value parsing, URI, method),fuzz_query_params(url-encoded query strings),fuzz_body(JSON + JSON Schema validation, deeply nested payloads),fuzz_file_paths(path traversal, percent-decoding, MIME guessing),fuzz_router(matchit path matching with edge-case paths) - Dependency vulnerability scanning:
cargo auditjob in CI (blocks on advisories), Dependabot for weekly cargo + GHA updates - Supply chain security:
deny.tomlconfigured with allowed license list (MIT/Apache/BSD/ISC/Zlib/Unicode-DFS/CC0-1.0/OpenSSL), vulnerability denial, multiple-versions warn, unknown-registry deny - Security middleware audit:
SecurityHeadersenhanced with builder pattern (with_hsts_preload(),with_csp_directive(),without_xfo(),without_csp()), CSP nonce-compatible directive model, configurable HSTS preload, configurable X-Frame-Options and CSP on/off - Rate limiting enhancement:
IpRateLimiterβ per-IP rate limiter using governor's keyed rate limiter withHashMapStateStore, extracts client IP fromreq.extensions().get::<SocketAddr>();per_second()convenience constructor - Input sanitization: SQL injection prevention via parameterized queries in
sqlx(Phase 12), XSS prevention viaX-XSS-Protection: 0+ CSP, MIME sniffing prevention viaX-Content-Type-Options: nosniff - Secrets management:
secrets.rsmodule βSecret(Env/File/Inline sources),SecretsRegistrywithregister()/resolve()/resolve_all(), no-logging of resolved values, lazy resolution (not at startup), eager validation viaresolve_all() - HTTP security hardening: HSTS preload flag, CSP directive builder (nonce-compatible
CSPserves multiple directives separated by;), X-Frame-Options: DENY, X-Content-Type-Options: nosniff - Security documentation:
.well-known/security.txt(canonical security policy endpoint),SECURITY.md(root-level pointer),docs/security/policy.md(full disclosure policy with response timeline, scope, hall of fame),docs/security/owasp-checklist.md(OWASP Top 10 2021 β 27/35 controls checked, 8 planned) - Penetration test guidelines:
docs/security/pentest-guide.mdβ attack surface map, 9 test scenario categories (auth, input validation, session mgmt, rate limiting, TLS, info disclosure, security headers, fuzzing, supply chain), tool reference (cargo-fuzz, cargo-audit, cargo-deny, curl, oha, nmap, testssl.sh, jwt_tool, sqlmap, nikto), CVSS 3.1 report template
Design decisions
- SAST in CI as gating check (not optional) β
cargo-auditandcargo-denyare blocking jobs - Fuzz targets use
cargo-fuzz/libfuzzerfor Rust paths (5 targets covering JWT, headers, query params, body/JSON Schema, file paths, router) - JWT parsing fuzzed with edge cases (malformed, algorithm confusion, arbitrary key bytes)
- Secrets management uses synchronous reads (no tokio dependency for file I/O) β
std::fs::read_to_stringwithtrim()for trailing newlines - OWASP Top 10 2021 as the security requirements baseline; checklist tracks implemented vs. planned controls
secrets.rsusesArc<RwLock<HashMap>>for concurrent access β not performance-critical (resolved at startup or on config reload)
Exit criteria
-
cargo-auditjob added to CI (blocks on vulnerabilities) -
cargo-denyjob added to CI (blocks on license/advisory violations) - 5 fuzz targets created (JWT, headers, query params, body, file paths, router)
- Security documentation complete (security.txt, policy, OWASP checklist, pentest guide)
- Per-IP rate limiter implemented (
IpRateLimiter) - SecurityHeaders enhanced with builder pattern (CSP nonce support, HSTS preload)
- 7 secrets module tests passing
- 175 total workspace tests passing (158 unit + 11 integration + 6 secrets)
-
cargo clippy --workspace -- -D warningsandcargo fmt --checkclean
Phase 18 β DX Tooling
Goal: Developer experience that rivals or exceeds FastAPI β automatic OpenAPI docs, hot reload, CLI productivity.
Deliverables
- OpenAPI generation: auto-generate OpenAPI 3.1 spec from route handler signatures (types, docstrings, validation schemas) β
openapi.rswith full spec types, builder, registry - Swagger UI + ReDoc: serve interactive API docs at
/docsand/redocβ registered inServer::new()andserve() - Hot reload: file watcher + graceful restart on code changes (via
notifycrate +JustAPIApp.reload()) -
justapi routes: CLI command to list registered routes with methods and paths β reads OpenAPI spec via--spec-fileor lists built-in routes -
justapi doctor: diagnostic command checking environment, dependencies, config validity -
justapi profile: performance profiling command with flamegraph generation -
justapi new: project scaffolding βjustapi new myappcreates a complete project structure -
justapi check: type-check and validate all routes without running server -
justapi gen openapi: generate and save OpenAPI spec to file viaOpenApiBuilder -
justapi gen client: generate a typed Python or TypeScript client from any OpenAPI 3.1 spec (justapi gen client -s spec.json -o out/ [--language python|typescript]). ParsesOpenApiDocument(nowDeserialize), emits arequests-based PythonClientand afetch-based TSClientwith one method per path+verb. Path/query/header params are typed from the spec, header/param names are sanitized to valid identifiers while preserving original wire names, and path templating uses the spec's{param}placeholders. Verified end-to-end against a mock server; unit tests ingen_client.rs. - Error messages: rich, colored error output with suggestions (like Rust compiler or Elm)
- Benchmark: time from
justapi newβcurl localhost:8080< 5 seconds
Design decisions
- OpenAPI spec generated from TypeScript-style type system on Rust types
- Hot reload via
notify+ SIGTERM to existing process + delayed restart - CLI built with
clap(already in workspace) β subcommands with completions - Project scaffolding via built-in templates (not external cookiecutter)
Exit criteria
Full OpenAPI 3.1 generation working end-to-end. Swagger UI at /docs. Hot reload working for Python file changes. justapi new, justapi routes, justapi doctor functional. 40+ tests.
Phase 19 β Plugin System & Extensibility (completed 2026-07-05)
Goal: Third-party plugin ecosystem β anyone can extend JustAPI with custom middleware, serializers, database backends, and deployment targets.
Deliverables
- Plugin trait:
Plugintrait withbuild()lifecycle hook for modifying the server pipeline - Plugin registry: compile-time plugin registration via
inventorycrate or link-time - Python plugin API: Python-declared plugins that register middleware, routes, or startup/shutdown hooks
- Plugin configuration: typed config per plugin, merged into app config
- Plugin marketplace documentation: documented process for publishing plugins
- Example plugins: caching (Redis), auth (OAuth2), rate limiting (advanced), compression (custom)
- Plugin isolation: plugin failures don't crash the server (panic boundaries)
- Benchmark: plugin overhead < 1% with no active plugins
Design decisions
- Plugin trait with hook points:
pre_route,post_route,on_startup,on_shutdown - Python plugins via
JustAPIApp.use(plugin)method - Plugins run in the Rust middleware chain for performance
- Plugin config as serde-deserializable structs
Exit criteria
- 3 example plugins working. Plugin overhead benchmarked. Plugin documentation published. 30+ tests.
Phase 20 β Benchmark & Optimization (Beat FastAPI) (completed 2026-07-05)
Goal: Prove JustAPI beats FastAPI on every measurable dimension β throughput, latency, memory, startup time, test speed, and deployment size.
Deliverables
- Comprehensive benchmark suite: automated benchmarking against FastAPI + Uvicorn, FastAPI + Granian, and Starlette on:
- Hello world throughput (req/s)
- JSON echo throughput with varying payload sizes
- Route lookup latency (100, 500, 1000 routes)
- Middleware chain overhead
- Memory usage under load
- Startup time (cold + warm)
- Test suite execution time (JustAPITestClient vs TestClient)
- Docker image size
- Tail latency (p99, p999 under load)
- Profile-guided optimizations: use
perf+flamegraphto identify bottlenecks - Custom allocator evaluation:
mimallocvsjemallocvs default allocator - Zero-copy request path audit: identify remaining copies in the pipeline
- Tokio tuning: thread count, event loop strategy, IO vs CPU balance
- Serialization optimization: evaluate
rkyv/flatbuffersfor internal serialization - Connection pooling optimization: benchmark keep-alive vs per-request connection
- Static file throughput: optimize
sendfile/spliceusage - Benchmark documentation: repeatable, hardware-documented, time-series results in BENCHMARKS.md
- Targets:
- Throughput: 2x FastAPI on hello-world, 3x on JSON echo
- Latency p99: < 0.5ms on hello-world (FastAPI ~2ms)
- Memory: 2x more requests per MB than FastAPI
- Startup: < 10ms cold start (FastAPI ~300ms)
- Docker image: < 50MB (FastAPI ~200MB with Python)
- Test speed: 5x faster than FastAPI TestClient
Design decisions
All benchmarks run on the same hardware fixture (documented in BENCHMARKS.md)
Benchmark harness in
justapi-benchcrate (already exists)ohafor load generation (already baseline tooling)Results versioned and appended β never overwritten
Re-architected native integration using
tokio::task::spawn_blockingand PyO3 0.29Python::attach()to ensure worker threads do not starve while waiting for Python execution.Beat FastAPI on every benchmark. If any benchmark shows FastAPI faster, that's a blocking bug that must be fixed before Phase 20 is complete. All results published in BENCHMARKS.md with hardware fixture, tool versions, and raw data.
Phase 21 β Advanced DX: Signature Parsing & DI
Goal: Provide the exact same developer experience as FastAPI with automatic signature parsing and Dependency Injection (Depends()).
Deliverables
- Auto-extract
path_params,query_params, headers, and request body directly into function arguments based on type hints. - Implement
Depends()for Dependency Injection (supporting both sync and async dependencies). - Support complex return types (Pydantic models, custom Schema objects) natively serialized by the framework.
Phase 22 β True Async & Advanced Web Features
Goal: Achieve true non-blocking async execution in Tier B and expose advanced web features (WebSockets, SSE, BackgroundTasks).
Deliverables
- Evaluated PyO3 native futures: decided to retain
tokio::task::spawn_blockingcombined withloop.run_until_complete()as it maximizes Tokio scalability while easily bypassing the GIL for asyncio execution. - Implement
@app.websocket()and@app.sse()decorators in the Python API. - Implement
BackgroundTasksfor deferred execution after response. - Python-level custom exception handlers and middleware.
- Implement
@app.websocket()and@app.sse()decorators in the Python API.
Phase 23 β Templating Engine Integration (completed 2026-07-05)
Goal: Built-in template rendering.
Deliverables
- Integration with a fast templating engine (
Jinja2Templatesintegration). -
TemplateResponsehelper for returning rendered HTML.
Phase 24 β gRPC & Protobuf Support (completed 2026-07-05)
Goal: Expose high-performance gRPC endpoints natively in JustAPI.
Deliverables
- Rust-backed gRPC server (using
tonic) running alongside the HTTP server. - Python decorators for defining gRPC services seamlessly.
- Auto-generate Python stubs/types from protobuf schemas.
Phase 25 β Ultimate Scale (1M RPS Tuning) (completed 2026-07-05)
Goal: Hyper-optimize the framework to handle 1 Million RPS on modest hardware.
Deliverables
- Extreme tuning of Tokio event loop,
io_uringadoption (if beneficial). - Lock-free data structures across the board.
- Network offloading and bypassing Python overhead for static/cached responses.
- Native async bridging using
.call_method0("result")and concurrency scaling (tested seamlessly up to 1000 concurrent Python futures).
Summary: JustAPI vs FastAPI feature matrix
| Feature | FastAPI | JustAPI (target) |
|---|---|---|
| Routing | β Starlette | β matchit (51ns lookup) |
| Request validation | β Pydantic | β Phase 11 (Rust-native, 10x faster) |
| OpenAPI docs | β auto | β Phase 18 (auto-generate) |
| Async support | β asyncio | β tokio + Rust async |
| WebSocket | β | β Phase 8 |
| SSE | β | β Phase 8 |
| Background tasks | β | β¬ Phase 15 |
| Dependency injection | β | β¬ Phase 11 |
| Database ORM | β (third-party) | β Phase 12 (built-in) |
| Testing utilities | β TestClient | β Phase 13 (5x faster) |
| TLS | β (uvicorn) | β Phase 7 (rustls) |
| Kubernetes support | β (third-party) | β Phase 16 (Helm + docs) |
| Hot reload | β (uvicorn) | β Phase 18 |
| Metrics | β (third-party) | β Phase 14 (built-in Prometheus) |
| Distributed tracing | β (third-party) | β Phase 14 (OTel) |
| Circuit breakers | β | β Phase 15 |
| Security scanning | β | β Phase 17 (SAST + fuzzing) |
| Plugin system | β | β Phase 19 |
| Performance | baseline | target: 2-5x faster on every benchmark |
Decision log pointer
See DECISIONS.md for the reasoning behind any deviation from plan.
Don't duplicate that reasoning here β just reference the entry.
Next actions
Framework Release:
- Package all crates and Python distributions for PyPI/crates.io.
- Publish documentation and guides.
- Finalize any ongoing community feedback.
Rebuild wheel with maturin and run Python integration tests after each phase.
Production-readiness plan (2.0.8 pre-release hardening)
Full plan in PRODUCTION_PLAN.md (written 2026-07-20 from the audit + live
reproductions). Blockers tracked there; summary:
- P0.1 BUG-2a (CRITICAL, availability):
normalize_db_urlβ FIXED (2026-07-20, ADR-075).sqlite:///x.dbβsqlite:/x.db(root) andsqlite:////absβsqlite://abs(mangled)
were both fixed by the existingnormalize_db_urlimplementation;test_normalize_db_url_sqlite_paths
andtest_sqlite_connect_relative_and_absolute_filepass. - P0.2 BUG-2b/D3 (CRITICAL, perf): SQLite pragmas β
FIXED (2026-07-20, ADR-075).
Unconditionalbusy_timeout=5000+journal_mode=WAL+synchronous=NORMALapplied
for SQLite inpool.rs:342-369; caller pragmas are appended after and may override. - P0.3 BUG-1 (CRITICAL, correctness): response dict envelope detection β
FIXED (2026-07-24).
Envelope detection requires ALL recognized keys ({status,headers,body,__response__}),
not just"status". Both Rusthandlers.rs:373-391and Python_native_helper.py:86-95updated. - P1.1 BUG-3:
body_schema=delivers rawbytesto the Python handler, not
a parsed Schema/dict (demo_shop workaround). [FIXED 2026-07-20, ADR-073] βjustapi.Schemaroutes now receive the parsed/validated object viarequest.json()/request["body"]; legacy callable schemas unchanged. - P1.3: pytest gate 5 failed/115 passed (missing
pydantic/jinja2/websockets).
[RESOLVED 2026-07-20] β addedtestextra topyproject.toml, installed
deps, fixedtest_schedulerflake (poll instead of fixed sleep) and thetest_scheduler/route conflict with the builtin/. Full suite now 122
passed / 1 skipped; onlytest_circuit_breakerflakes under cross-testmultiprocessingfork contamination (passes in isolation). - P2.1: no real DB-backed CRUD benchmark vs FastAPI/Robyn exists β the only
fair "real life" number is missing. - P3.1: portable
manylinux_2_28wheel built +twine checkPASSED (installs/imports in a fresh venv); unpublished β blocked onMATURIN_PYPI_TOKEN(no token in env). Addmusllinux/aarch64wheels before release.
Open issues / follow-ups (2026-07-11)
Python test gate fixed. The suite had regressed to 8 failures (root causes: request-param names
r/_requestnot recognized inapp.py;wrap_resultstringifiedTokenStreamResponse; 3 tests wrongly expected 404 for wrong-method routes that correctly return 405). All 57 pass / 1 skipped now.[P1.4 β RESOLVED 2026-07-24] rustfmt.toml standardized. Cleaned up nightly-only formatting options;
cargo fmt --checkandcargo clippy --workspace --tests -- -D warningspass clean.[P1.3 β RESOLVED 2026-07-24] Pytest suite 100% green. Added route overriding support in
_JustAPIAppto cleanly allow user routes to override built-in routes withoutInsertError::Conflict. Full test suite runs 137 passed / 1 skipped with zero errors.[P1.2 β RESOLVED 2026-07-24] GraphQL Python API. Added
app.graphql()and_builtin_graphqlroute handlers wrappingjustapi_core::graphql.test_graphql.pypasses 200 OK for GraphiQL UI and GraphQL query executions.Python test deps pinned. Added a
testextra tocrates/justapi-py/pyproject.toml
(pydantic,jinja2,websockets,pytest,pytest-asyncio) and installed
them into the dev venv. The suite is now reproducible (122 passed / 1 skipped;test_circuit_breakeronly flakes undermultiprocessingfork contamination
in the full-suite run β it passes in isolation).[P2.2 β RESOLVED] Python-handler DB write path now awaits/commits durably under concurrency. Root cause was a blocking-runtime re-entrancy:
py.detach+rt.block_onfrom the server's dispatch thread deadlocked the DB runtime, exhausting the connection pool (busy_timeouthit) so writes silently dropped (1β2 of ~50 INSERTs persisted at-c 50). Fixed indatabase.rs::run_blockingβ release the GIL withpy.detach, thenrt.spawn(fut)and wait on anmpscchannel (no re-entrantblock_on). Verified: 100 concurrent INSERTs via the test client persist 100/100; a 100-thread directapp.db.executeburst persists 200/200 with zero errors. Durability test added intest_db_concurrent.py. See ADR-074 (revised) + BENCHMARKS.md P2.2. The Rust-native CRUD path remains the fastest write route.Phase 52 real run unverified.
cargo run -p justapi-bench --bin justapi-gpu-bench --features "cuda,real"still needs a real-weight pass; thecandle+CUDA build is heavy and unconfirmed in this env.Prometheus
/metrics+ Swagger/docshave no auth guard. FIXED 2026-07-24 βJustAPIApp(admin_token='...')guards/metrics,/docs,/redoc,/openapi.json,/scalarviaAuthorization: Bearer <token>. K8s probes (/health,/live,/ready) and home page/remain unprotected. Backward compatible: no token = no auth check.JWT
aud/issvalidation not default. FIXED 2026-07-24 β one-timetracing::warn!whenJwtAuthprocesses its first request without bothaudandissconfigured. Users calling.with_audience()/.with_issuer()never see the warning.Untracked artifacts (resolved 2026-07-17).
test_routing.pynow tracked (2 pass);test_gateway.jsonmoved into the package test dir and covered by newtest_gateway.py(1 pass). Also fixed a latentpanic = "abort"injustapi-core/src/testing.rsthat killed pytest on any streamed-body error (e.g.stream_jsonrejecting an invalid item). pytest suite now 120 passed / 1 skipped. See ADR-058.
Key architecture invariants
- Rust owns I/O, Python owns application logic (ADR-008)
- Dedicated Python worker thread (zero GIL contention)
- Tier B (native) for performance, Tier A (ASGI) for compatibility
- All new features must have benchmark gates β if it doesn't beat FastAPI, it doesn't ship
JustAPI: The Singularity Master Plan (Phases 26 - 40)
Based on a massive deep-dive into the modern Python ecosystem (Litestar, Robyn), Enterprise API Gateways (Kong, Envoy), and Cutting-Edge AI Serving engines (Ray Serve, vLLM, BentoML), we have designed the ultimate roadmap to make JustAPI the most advanced web framework in existence.
Part 1: The AI Inference Engine
These phases transform JustAPI from a standard web framework into a high-performance AI deployment engine.
Phase 26: Zero-Copy AI Data Boundary (Status: DONE)
Phase 27: Adaptive Batching Router (Status: DONE)
Phase 28: WASM Middleware Engine (Status: DONE)
Phase 29: High-Throughput LLM Streaming (SSE 2.0) (Status: DONE)
Phase 34: Dynamic Configuration (Hot Reloading) (Status: DONE)
Phase 35: GraphQL & Federation Gateway (Status: DONE)
π Next Phase to Execute: Phase 40: The JustAPI 2.0 "Singularity" Release
Phase 26: Zero-Copy AI Data Boundary (Arrow & DLPack)
- Objective: Eliminate serialization overhead for ML models.
- Action: Implement PyO3 buffer protocols and Apache Arrow/DLPack integration. Allow Python handlers to receive raw C-memory pointers for image bytes or float arrays directly from the Rust HTTP layer, entirely bypassing JSON parsing.
Phase 27: Adaptive Batching Router (Status: DONE)
- Objective: Native ML model serving efficiency.
- Action: Introduce a
@justapi.adaptive_batch(max_size=32, window_ms=10)decorator. The Rust core will hold incoming requests, batch their payloads into a single tensor, invoke the Python ML model once, and automatically scatter the results back to the respective HTTP clients.
Phase 29: High-Throughput LLM Streaming (SSE 2.0) (Status: DONE)
- Objective: Dominate LLM token generation workloads (like vLLM).
- Action: Implement a specialized
TokenStreamResponsein Rust that reads from a Python asynchronous generator via lock-free queues. Optimized specifically for continuous, ultra-fast token delivery without blocking Tokio worker threads.
Phase 36: Agentic Workflow DAG Engine (Status: DONE)
- Objective: Natively support AI Agent pipelines (like Ray Serve graphs).
- Action: Allow defining Directed Acyclic Graphs (DAGs) of tasks in Python. The Rust core orchestrates the execution, parallelizing independent nodes and managing intermediate states entirely in Rust memory.
Part 2: Enterprise API Gateway Features
These phases bring Envoy/Kong level features directly into the web framework.
Phase 28: WASM Middleware Engine (Status: DONE)
- Objective: Run custom middleware without the Python GIL.
- Action: Embed
wasmtimeinjustapi-core. Enable compiling auth, header mutation, and routing logic to.wasmplugins that execute directly on the Tokio event loop at near-native speeds.
Phase 32: Native Enterprise Rate Limiting (Status: DONE)
- Objective: Gateway-level traffic control.
- Action: Build multi-tenant Generic Cell Rate Algorithm (GCRA) into the Rust core. Support grouping by JWT claims, IP, or custom headers, backed by an async Redis connection pool.
Phase 34: Dynamic Configuration (Hot Reloading) (Status: DONE)
- Objective: Zero-downtime Gateway updates.
- Action: Implement an admin API and file-watcher to dynamically update routing tables, WASM plugins, and rate limit rules in the Rust core without restarting the JustAPI process.
Phase 35: GraphQL & Federation Gateway (Status: DONE)
- Objective: Consolidate API architectures.
- Action: Integrate
async-graphqlnatively into the Rust core. Allow Rust to serve as an Apollo Federation supergraph, querying downstream Python or Rust subgraphs at peak efficiency.
Part 3: Advanced Developer Experience (DX)
Stealing the best ideas from Litestar, FastAPI, and Django.
Phase 30: Layered Dependency Injection (Status: DONE)
- Objective: Ergonomic, Litestar-style DI.
- Action: Build a tiered DI container. Cache singletons at the Rust level. Allow injecting dependencies at the App, Router, Controller, and Handler levels.
Phase 31: Class-Based Controllers & Route Composition (Status: DONE)
- Objective: Enterprise codebase organization.
- Action: Implement
@controllerclasses that group routes. Sync these structures at startup with the Rustmatchitrouter to maintain sub-microsecond routing speeds.
Part 4: Unbreakable Security & Observability
Phase 33: Circuit Breakers & Graceful Degradation (Status: DONE)
- Objective: System resilience under load.
- Action: Add Rust-level circuit breakers that automatically short-circuit requests (returning 503) if a specific Python handler's failure rate or latency exceeds configured thresholds.
Phase 37: OTel Distributed Tracing & Observability (β COMPLETE)
- Objective: Out-of-the-box enterprise monitoring.
- Action: Embed OpenTelemetry into
justapi-core. Automatically trace requests from TCP accept, through Rust middleware, across the PyO3 boundary, and into Pythoncontextvars. - OTLP gRPC exporter via
opentelemetry-otlp -
trace_context.rsβ OTel span context extraction -
tracing_setup.rsβ OtelExporter, service_name, init_otlp_tracing, shutdown_tracing - PyO3 boundary tracing with
contextvars(Pythonjustapi.tracingmodule) - Request-span instrumentation (
http.request) inserver.rs - Debug spans for middleware chain, WASM middleware, handler dispatch
- All 225 tests pass, clippy/fmt clean
Phase 38: Hardware-Accelerated JWT & Security (β COMPLETE)
- Objective: Push security to the edge.
- Action: Move all JWT validation, signature checking, and CORS preflight handling to Rust. Use SIMD-accelerated crypto (ring via jsonwebtoken) to reject invalid requests before they ever wake up Python.
-
JwtAuth::from_rsa_pem(),from_ec_pem(),from_rsa_der(),from_ec_der()β RS256/ES256 key support -
JwtRequirementenum:None,Required,Roles(Vec<String>),Scopes(Vec<String>) - Per-route JWT configuration:
require_for(path, requirement)+default_requirement() -
check_claims()β validates roles and scopes claims after JWT decode -
Server::add_jwt()builder method -
Cors::new()builder:allow_origin(),allow_methods(),allow_headers(),expose_headers(),allow_credentials(),max_age() - Origin whitelist (specific origins, rejected if not in list)
-
Vary: Originheader when specific origins configured -
Access-Control-Allow-Credentials,Access-Control-Expose-Headerssupport -
IpRateLimiterfix:SocketAddrplumbed into request extensions (both plain + TLS accept loops) - ASGI mode:
client_addrextracted from request extensions, passed toAsgiServer::handle() - 11 new tests (236 total), all gates green
Phase 39: SAST, Fuzzing & Memory Safety Verification (β COMPLETE)
- Objective: Unbreakable runtime guarantees.
- Action: Implement
cargo fuzztargets for all PyO3 boundary parsers. Add rigorousmiritesting for the WASM and memory-view boundary layers. -
// SAFETY:comments on all 3 unsafe blocks (memory.rs:39, buffer_test.rs:17, buffer_test.rs:42) - 6 fuzz targets compile and build with
cargo fuzz buildon nightly: fuzz_router, fuzz_file_paths, fuzz_body, fuzz_query_params, fuzz_headers, fuzz_jwt - Fuzz targets updated for current APIs (matchit v0.8, refactored Router, etc.)
- miri installed (
rustup component add miri --toolchain nightly) -
.cargo/config.tomlcreated with-Zmiri-strict-provenance -Zmiri-symbolic-alignment-check -Zmiri-track-raw-pointers - miri-gated tests for arena allocator (unsafe
from_utf8_unchecked, bump-allocator arithmetic) -
cargo miri test -p justapi-core -- miriβ 2 passed, 0 failed - All gates green:
cargo test --workspace(236 tests),clippy -- -D warningsclean,cargo fmt --checkclean
Phase 40: The JustAPI 2.0 "Singularity" Release (in progress)
- Objective: Final polish and ecosystem launch.
- Action: Complete documentation, stabilize the Python native API, and publish comprehensive
BENCHMARKS.mdproving JustAPI outperforms FastAPI for REST, Kong for routing, and Ray Serve for AI batching. - Python native API package (
crates/justapi-py/python/justapi/) βapp.py(JustAPIApp,Depends,APIRouter,Controller,adaptive_batch),Schema/pydantic_schema,Jinja2Templates,BackgroundTasks, fulltestingmodule. Consolidated the stray duplicate at repo-rootpython/justapi/into this single source of truth (maturin builds from here; the duplicate broke test imports). - OpenAPI wiring:
Server::with_openapi_spec(spec)replaces the static built-in spec;JustAPIApp.run()auto-generates OpenAPI 3.1 spec from registered routes and serves it at/openapi.json,/docs(Swagger UI),/redoc(ReDoc) - README.md fully rewritten β accurate project status (Phase 40), Python API quick start, feature table, updated architecture (no ASGI shim), project structure
- Version bumped to
2.0.0across workspace (Cargo.toml,pyproject.toml) - Bug fix:
CompressionMiddlewarewas unimported under#[cfg(feature = "compression")]inserver.rs(only failed with--features compression); added the gateduseso the Docker/tls,compressionbuild compiles. All gates re-verified. - Docker: fixed
rust:1.84(too old foredition2024) βrust:1.96-bookwormbuilder +debian:bookworm-slimruntime (resolves the GLIBC mismatch that made the image unrunnable). Added.dockerignore(was shipping a 3.5 GB context). Image builds, runs (/hello,/echoverified), 155 MB (< 200 MB target). - PyPI packaging:
pyproject.tomlgiven full metadata (description, classifiers, URLs, optionalpydantic/jinja/fullextras, MITLICENSE). Built as a single abi3 wheel (cp311-abi3, covers CPython 3.11β3.14) β required addingabi3-py311to pyo3 features.twine checkPASSED; wheel installs + imports in a clean venv. PyPI namejustapiconfirmed available. - Benchmarks (BENCHMARKS.md): startup latency (CLI ~5 ms to first response; Python native ~165 ms), Docker image size (155 MB), and the full test-suite gate table recorded.
- All gates green:
cargo test --workspace(~444),clippy -- -D warningsclean,cargo fmt --checkclean,cargo miri test(2), Pythonpytest(57 passed / 1 skipped as of 2026-07-11; suite had regressed to 8 failures and was fixed β see Next actions),twine checkPASSED. - Publish to PyPI β packaging ready; upload must run inside a
manylinux_2_28container (local Arch host tagsmanylinux_2_34, which PyPI rejects) and needs a PyPI API token. See BENCHMARKS.md publish notes. - Full
ARCHITECTURE.mdandCONTRIBUTING.md
Part 5: AI / Model Serving β "Best for Model Deploying" (Phases 41-48)
Strategy (see ADR-030 / ADR-031). FastAPI is only HTTP glue; the GPU
work is delegated totorchunder the GIL β a bottleneck it can never
remove. JustAPI's edge is to own the GPU execution path in Rust. We build
two layers, both inside JustAPI (no external engine dependency):
- Engine (Phases 41-45): a Rust-native inference runtime on Candle
(CUDA/ROCm/Metal/CPU) β load, generate, paged KV cache, continuous
batching, quantization, multi-LoRA.- Control plane (Phases 44, 46): OpenAI-compatible API, model registry,
KV-aware/LoRA-aware routing, LLM-specific autoscaling, multi-replica.Python handlers keep their ergonomics and call the engine through the existing
zero-copy (Arrow/DLPack) PyO3 boundary β heavy compute runs in Rust, GIL-free.
2026 landscape baseline (what we must match/beat)
From vLLM / SGLang / TGI / TensorRT-LLM / Ray Serve / NVIDIA Dynamo / AIBrix /
Ouranos research (2026-07-10):
| Capability | vLLM/SGLang/TGI | JustAPI today | Phase |
|---|---|---|---|
| Continuous (token-level) batching | β | β HTTP-only batch | 43 |
| PagedAttention / KV-cache mgmt | β | β | 42 |
| Prefix caching / RadixAttention | β | β scheduler (GPU-gated validation) | 50 |
| Chunked prefill | β | β | 43 |
| Tensor/Pipeline parallelism (multi-GPU) | β | β | 41 |
| Quantization (AWQ/GPTQ/FP8/GGUF) | β | β | 45 |
| Speculative decoding | β | β | 48 |
| Multi-LoRA / adapter hot-load | β | β | 45 |
| OpenAI-compatible API | β | β | 44 |
| KV-aware / LoRA-aware routing | β | β | 46 |
| Distributed KV cache | β | β | 46 |
| LLM-specific autoscaling (KV-pressure/TTFT) | β | β generic only | 46 |
| Multi-replica orchestration | β | β single process | 46 |
| Model registry + versioning | β | β | 46 |
JustAPI already has (reuse, don't rebuild): Arrow/DLPack zero-copy boundary,adaptive_batch (HTTP layer), TokenStreamResponse/SSE, DAG engine,
rate-limit/circuit-breaker/bulkhead, health checks, OTel tracing, Docker +
k8s guides, OpenAPI.
Phase 41: Native Inference Engine Foundation (Status: π‘ in progress)
- Objective: Own GPU inference in Rust β the core differentiator vs FastAPI.
- Action: New crate
justapi-inference. Integrate Candle (ADR-030).- Device management: discover + select CUDA/Metal/CPU; single-device handles
(multi-GPU orchestration is Phase 46). ROCm is enabled via Candle'scuda
feature on a ROCm toolchain (no separaterocmfeature in candle 0.11). - Model loading: safetensors + GGUF; weight streaming from object store
(S3/GCS) for fast cold-start (mirrors Dynamo ModelExpress). - Expose
Engine::generate(requests, sampling)returning a token stream. - Bind to PyO3 via the existing Arrow/DLPack zero-copy boundary.
- Device management: discover + select CUDA/Metal/CPU; single-device handles
- Success metric: load a 7B-class model on GPU and stream tokens through a
JustAPI handler with zero Python GIL contention on the hot path. -
justapi-inferencecrate + Candle (CPU default;cudafeature-gated) -
EngineDevicediscovery/selection API (discover(),to_candle()) -
Modeltrait +MockModel(CPU-runnable, no weights) β exercises the
full pipeline; 8 tests pass, clippy/fmt clean -
Enginewith in-memoryModelRegistry+generate()streaming tokens
over a tokiompsc(GIL-free dedicated thread) β the hot-path design - Real weight loading (safetensors/GGUF) + forward pass β deferred to
Phase 42 (load()returnsFeatureRequired("real")/NotImplemented
today so the gap is explicit, not silent) - PyO3 bindings to Python
JustAPIAppmodel handlers β Phase 44 (OpenAI API)
Phase 42: KV-Cache Manager β PagedAttention in Rust (Status: β complete)
- Objective: Eliminate GPU memory fragmentation; allow far larger batches.
- Action: Blocked KV-cache allocator reusing the
memorycrate arena/pool.- Fixed-size KV blocks (16 tokens) allocated anywhere in GPU memory.
- Radix/prefix tree for prefix caching (SGLang-style reuse across requests).
- Eviction policy under memory pressure (scan-resistant).
-
KvBlockPoolpaged block allocator with clock-sweep eviction -
PrefixCacheβ hash-based prefix index (supports full + partial prefix reuse) -
Sequencehandles β token tracking, grow, set_num_tokens for prefix restore -
PoolStats/PrefixCacheStatsβ pressure reporting (feeds Phase 46 autoscaler) - 16 unit tests, 260 workspace tests, clippy + fmt clean
Phase 43: Continuous-Batching Scheduler (Status: β complete)
- Objective: Maximize GPU utilization by interleaving prefill/decode.
- Action: Token-level scheduler (not HTTP-list batching).
- Interleave prefill and decode across dozens of concurrent sequences.
- Chunked prefill (split long prompts to avoid blocking decode).
- Bridge to existing
adaptive_batch+ DAG for higher-level request graphs.
-
Schedulerthat owns the running batch + KV handles (KvBlockPool integration) - Chunked prefill β configurable chunk size, partial chunks when budget runs out
- Back-pressure via
Schedule::back_pressureandSchedulerStats::back_pressure - Prefix-cache restoration:
Sequence::restore_from_cache+KvBlockPool::reclaim - 9 unit tests (idle, single/multi/chunked prefill, interleaved, back-pressure, finished removal, cancellation, budget limits, prefix cache)
- 269 workspace tests, clippy + fmt clean
Phase 44: OpenAI-Compatible API Server (Status: β complete)
- Objective: Drop-in replacement for OpenAI SDKs.
- Action: Routes on the existing
Server+justapi-inference:POST /v1/chat/completions,/v1/completions,/v1/embeddings,GET /v1/models.- Streaming via
streaming_response(SSE) for chat/completions β tokens
flow from the engine's GIL-free generation thread with zero Python GIL
involvement on the hot path. - Request/response schema compatible with OpenAI client SDKs.
-
justapi-inference/src/openai.rsβ OpenAI request/response types
(ChatCompletionRequest,ChatCompletionResponse, chunks,EmbeddingRequest/Response,ModelList,ErrorResponse) + streaming
& non-streaming drivers (chat_completion_stream,chat_completion,completion_stream,completion,embeddings,model_list). -
justapi-core/src/openai.rs(featureinference) βHandlerFnbuilders
+Server::with_openai(engine)mounting the four routes. Theinference
feature addsjustapi-inferenceas an optional dep so the default build
stays lean. - 8 protocol unit tests + 5 HTTP handler tests (via
TestClient, full
pipeline) covering chat (stream + non-stream), completions, embeddings,
and/v1/models. - Gates:
cargo test(default +--features inference),clippy -D warnings,cargo fmt --checkall clean.
Phase 45: Quantization + Multi-LoRA (Status: done)
- Objective: Cheap, dense serving of many fine-tunes.
- Delivered:
real/quant.rsβQuantMethod,QuantConfig,LayerQuantConfig, GGUF k-quant
type mapping with bits-per-weight heuristics (always compiled, 7 unit tests).real/lora.rsβLoraAdapter,LoraConfig,LoraRegistry(thread-safe
Arc) with routing key, activate/deactivate, resolve by name or routing
key, active_for_module (always compiled, 10 unit tests).real/model.rsβRealModelenum (GGUF + Safetensors) implementingModel
trait,detect_format()heuristic,RawLlamaConfigβLlamaConfigmapping,
tokenizer loading viatokenizerscrate (feature-gatedreal).real/tokenizer.rsβ thinTokenizerwrapper for encode/decode (feature-gated).Engine::load()wired toRealModel::load()under#[cfg(feature="real")].RealModel::generate()now runs the real autoregressive forward pass:
GGUF (ModelWeights::from_gguf+ internal KV cache) and Safetensors
(Llama::load+Cache::new+VarBuilder::from_mmaped_safetensors),
with temperature/top_p/top_k sampling viaLogitsProcessor. State held
behind aMutex<ForwardState>so the&selfModeltrait works.- Top-level re-exports:
QuantMethod,QuantConfig,LoraAdapter,LoraRegistry.
- Quantized config layer in
justapi-inference(always compiled) - LoRA adapter registry + routing (always compiled)
- RealModel + Engine::load wired (feature-gated
real) - Real forward pass + sampling wired into
RealModel::generate() - LoRA-aware router extending the HTTP layer (Phase 46)
Phase 46: LLM Control Plane (Status: in-progress)
- Objective: Production orchestration (the Ray Serve / Dynamo / AIBrix layer).
- Delivered (registry foundation, always compiled, 11 unit tests):
control_plane.rsβWeightLocation(Local/S3/HF/Remote),RuntimeProfile
(device, max concurrency/batch-tokens, gpu memory, quant method, adapters),ModelVersion(version + aliases + created_at),ModelRecord(versions +
default + LoRA adapter routing map), and the thread-safeControlPlane
(Arc) registry. ControlPlane::resolve(model, version_or_alias, routing_key):
strict on explicit version miss (None), lenient fallback to defaultβlatest
when no version requested; LoRA-aware adapter resolution from routing key.
- Model registry + versioning (pure-data, always compiled)
- LoRA-aware + KV-pressure-aware router (
router.rs, always compiled, 8 tests):Replica(load + kv_pressure + loaded_adapters),RouterwithLeastLoaded/LowestKvPressure/RoundRobinstrategies. Selection is
LoRA-aware (only replicas holding the resolved adapter) and KV-aware
(lowest pressure / fewest active), falls back toNoneon no capacity. - LLM-specific autoscaler (
autoscaler.rs, always compiled, 8 tests):LlmMetrics(tokens/sec, TTFT, queue depth, KV pressure) +AutoscalerConfig+AutoscalerwithScaleUp/ScaleDown/Hold
decisions. Watches TTFT / KV pressure / queue depth (not QPS) and uses a
cooldown window to prevent flapping; clamps to[min, max]replicas. - HTTP wiring in
justapi-core(feature-gatedinference):Server:: with_openai_routed(engine, control_plane, router)mounts/v1/chat/completions,/v1/completions,/v1/embeddings,/v1/models.
Routed handlers admit each request viaControlPlane::resolve+Router::route; on no capacity they return 503, otherwise they
overridereq.modelwith the resolved target and delegate to the existing
generation drivers. 2 HTTP handler tests (admitβ200, no-capacityβ503). - Multi-replica supervisor (
supervisor.rs, always compiled, 6 tests):Supervisorowns anAutoscaler+Routerand drives a live replica set
toward the desired count. EmitsSupervisorAction::StartReplica/StopReplicaintents (scale-down prefers stuck/unhealthy replicas),
syncs the router's replica view each reconcile, and tracks replica health
viaon_replica_started/on_replica_report/on_replica_stopped.
Clamps to[min,max]and inherits the autoscaler's cooldown (no flapping). - Phase 46 complete: registry + versioning + LoRA-aware/KV-aware router +
LLM autoscaler + HTTP wiring + multi-replica supervisor (all pure, tested,
always-compiled except the weight-loading forward pass gated onreal).
Phase 47: FastAPI Parity β model-deploy essentials (Status: β complete)
- Objective: "Like FastAPI" for the remaining DX gaps.
- Delivered:
ApiKeyAuthβ header/query API-key validation, 6 testsOAuth2Passwordβ RFC 6749 Β§4.3 token issuance, 7 tests- Multipart file upload β
multipartmodule viamulter3.1, 7 tests, ADR-034 - Typed Form/Cookie/Header extraction β
extractmodule, 17 tests - Response-model serialization β
JsonResponse<T: Serialize>inserialize.rs
with builder API (with_status,with_header,into_response), serde-based
(10x faster than Pydantic v2, zero GIL), 5 tests. 248 tests total.
-
ApiKeyAuthβ API-key security scheme -
OAuth2Passwordβ OAuth2 password-flow - Multipart file upload
- Typed Form/Cookie/Header extraction
- Response-model serialization (serde-based
JsonResponse<T>) - ADR-034:
multerfor multipart parsing
Phase 48: Production Hardening for AI (Status: π‘ in progress)
- Objective: Match vLLM/SGLang on the benchmarks that matter.
- Delivered (speculative decoding):
spec_decode.rsβ draft-target speculative decoding (Chen et al. 2023),
pure-Rust seeded sampler (sample_token: temperature/top_p/top_k),speculative_generate()(correctness-preserving: draft==target yields an
identical token stream to plain decode),AcceptanceStats(acceptance
rate + bonus tokens = speedup driver),SpeculativeConfig,SpeculativeModel.Model::forward_logits()added to the trait (default impl +MockModel
degenerate dist +RealModelsingle forward). This is the single-step
primitive the scheduler can later drive per-step.Engine::register_speculative()β wraps(target, draft, gamma, seed)in aSpeculativeModelserved transparently throughEngine::generate.- 8 unit tests + 2 Engine integration tests (lossless vs plain decode, perfect
draft β acc=1.0 / gamma+1 tokens per step, imperfect draft β low acc, stop
tokens, greedy sampler).rand0.8 added (ADR-035). 87 inference tests.
- Speculative decoding (draft-target) β
spec_decodemodule - Disaggregated prefill/decode β
pd.rsmodule withPdScheduler(independent prefill/decode pools,schedule_prefill/transfer_completed/schedule_decodeloop).TransferableSequencemoved from inner struct to module scope,SchedulerStatsderivesDebug + Clone. 5 tests: idle, single-request flow, independent pool sizing,total_transferred_tokensaccounting, block allocation/release verification. 92 inference lib tests + 10 integration. - Benchmark suite vs vLLM/SGLang (structural) β
justapi-bench-inferencebinary drives realPdScheduler/Schedulerover a synthetic GPU-cost model with parallel vs shared virtual clocks. Shows disaggregated P/D: ITL p99 5.80x tighter, 2.04x throughput vs collocated. Recorded in BENCHMARKS.md. ADR-037. - K8s AI inference gateway plugin β
gateway.rsmodule:InferenceGatewaycomposingControlPlane+Routerwith KV-pressure default strategy, readiness-gated routing (not-Ready pods excluded), and Kubernetes service-DNS endpoint resolution ({replica}.{namespace}.svc.cluster.local). 5 tests: endpoint resolution, namespace scoping, readiness gating, KV-pressure default, LoRA-aware routing. 97 inference lib tests + 10 integration. ADR-038.
Phase 52: GPU Benchmark Gate (Status: π΄ blocked)
- Objective: Measure SchedulerEngine throughput on real GPU hardware and
compare against naive Engine::generate and vLLM/SGLang baselines. - Deliverables:
justapi-gpu-benchbinary (injustapi-bench) that loads a real model
(GGUF/safetensors) on CUDA device and measures tokens/sec, TTFT (p50/p99),
ITL (p50/p99) for both naive and scheduler-backed generation paths.- Comparison of continuous batching throughput gain (amortising kernel launch
overhead acrossmax_num_seqsconcurrent requests). - Results documented in BENCHMARKS.md with full hardware fixture details.
- Install CUDA toolkit (
sudo pacman -S cuda) β installed 13.3.1 - Download TinyLlama-1.1B Q4_K_M GGUF (~807 MB) to
~/models/tinyllama/ - Real-model tokenizer extraction from GGUF metadata (no separate
tokenizer.jsonrequired) βTokenizer::from_gguf_metadata - GGUF magic validation (
is_valid_gguf) so stray/invalid.gguffiles
in the model dir don't break loading - Run on CUDA and record tokens/sec, TTFT, ITL for both paths
- Compare against vLLM baseline (if vLLM is available on the same GPU)
- Update BENCHMARKS.md with GPU results
- BLOCKER (CUDA PTX version mismatch): System has NVIDIA driver 580.173.02
which exposes CUDA 13.0 at runtime, butpacman -S cudainstalled the 13.3.1
toolkit. cudarc/candle-kernels are JIT-compiled by nvcc 13.3 and emit PTX
13.3, which the CUDA 13.0 driver rejects withCUDA_ERROR_UNSUPPORTED_PTX_VERSION. The driver must be updated to >= 13.3
(or the toolkit pinned to <= 13.0) before GPU runs succeed. No code change
needed β this is an environment/driver issue. User opted to skip this for now. - Workaround to unblock later: update NVIDIA driver to a release that
supports CUDA >= 13.3, OR install CUDA toolkit 13.0. SettingCUDARC_CUDA_VERSION=13000alone is insufficient because nvcc still emits
13.3 PTX. - 2026-07-18 update: A
nvidia-utils 610.43.03+linux-cachyos-nvidia-open 7.1.3-2
driver (CUDA 13.3 runtime) is available in the repos and matches the running
kernel7.1.3-2-cachyos. User chose not to perform the driver upgrade
(system change + reboot). Separately, the Needle 26M encoder-decoder weights
were downloaded to~/needle-bucket(safetensors/pkl) but are NOT loadable byjustapi-inference(which only supports Llama-family GGUF/safetensors), so
they do not unblock this gate. As a non-gate validation,justapi-gpu-bench
was run withMockModel(CPU, no--model-path) β both naive and
SchedulerEngine paths execute; the 813k tok/s "naive" figure is mock-only and
does NOT satisfy the real-GPU acceptance criteria. Phase 52 remains π΄ blocked
on the CUDA driver fix + a Llama-family GGUF (real file is~/models/tinyllama/llama-3.2-1b-q4_k_m.gguf; thetinyllama-1.1b.q4_k_m.gguf
is a 29-byte placeholder).
Phase 53: HTTP/3 (QUIC) Transport (Status: β οΈ reverted β dead code removed 2026-07-15)
- Objective: Serve the same Python routes over HTTP/3 (QUIC) in addition to
the existing HTTP/1.1 transport, sharing the Rust request-handling core. - Deliverables:
justapi-corehttp3feature:quinn0.11 +h30.0.8 +h3-quinn
0.0.10.server::http3::serve_http3(addr, cert_pem, key_pem, chain, wasm_middleware, shutdown)
binds a QUICEndpoint(TLS ALPNh3), accepts connections, and dispatches
each request through aMiddlewareChain<Full<Bytes>>(the same chain shape as
HTTP/1.1) β request body fully buffered intoBytesbefore the chain runs.
An optionalWasmEngineapplies the same WASM preprocessing as the H1 path.- Core integration test
server::http3::tests::http3_roundtripβ a self-signed
cert (rcgen) +h3-quinnclient performs a full GET roundtrip and asserts the
response body. justapi-pyhttp3feature forwarding tojustapi-core/http3.make_native_handler/make_test_handlerare now generic over the request
body typeB: http_body::Body<Data = Bytes> + Send + Sync + Unpin + 'static
(so the same closure servesIncomingfor HTTP/1.1 andFull<Bytes>for
HTTP/3).JustAPIApp.runspawnsserve_http3in parallel whenenable_http3(cert_pem, key_pem)was called; the QUIC server shares theCancellationTokenfor graceful shutdown.- Python-facing
JustAPIApp.enable_http3(cert_pem, key_pem)(delegates to the
Rust method; raises a helpfulRuntimeErrorif built without thehttp3
feature).JustAPIApp.runbuilds an H3MiddlewareChain<Full<Bytes>>from the
same config (circuit breaker, request coalescing, gateway) as the H1 path and
passes it toserve_http3, so H3 applies identical middleware policy.test_http3.pyverifies wiring: server starts, routes answer over
HTTP/1.1, and the QUIC UDP port is bound.
- Limitation resolved: Middleware was made generic over the request body type
B(impl<B: Send + 'static> Middleware<B>forAccessLogger,Cors,SecurityHeaders,JwtAuth,RateLimiter,IpRateLimiter,ApiKeyAuth,RequestCoalescer,CompressionMiddleware,GatewayMiddleware; resilience
middleware was already generic).MiddlewareChainis therefore reusable for any
body type, andserve_http3now runs the full chain (plus WASM preprocessing) on
the H3 path β not the rawHandlerFn. Routing, Python dispatch, validation, DB,
batching and WebSockets still work on H3 (they live in the handler). -
cargo test -p justapi-core --features http3βhttp3_roundtripandhttp3_middleware_applied(assertsx-content-type-options: nosnifffromSecurityHeadersarrives over H3) pass -
cargo clippy --workspace --tests --features justapi-py/http3 -D warnings
clean -
cargo fmt --checkclean - Python
pytestunder GIL (3.12) and no-GIL (3.14t): 78 passed, 1 skipped
(no regression from the generic-middleware refactor)
2026-07-15 update β removed as dead code. The
http3transport was never
compiled (theserver/http3.rsmodule was untracked and never declared viamod http3;), so enabling the feature failed to build, andserve_http3was
never called. As part of the production-readiness cleanup it was deleted: thehttp3feature +quinn/h3/h3-quinndeps injustapi-core, thehttp3
feature injustapi-py, the Rustenable_http3method, the PythonJustAPIApp.enable_http3wrapper +.pyistub,test_http3.py, and all#[cfg(feature = "http3")]wiring inapp.rswere removed. The middleware
body-type genericity work (Phase 53 deliverable) remains and is still exercised
by the HTTP/1.1 path. If HTTP/3 is wanted later, re-add it as a fully-wired
module (ADR-046 should be revisited).
Phase gate (Part 5 exit criteria)
-
justapi serve --model <id> --gpu 0serves an OpenAI-compatible endpoint
with continuous batching + paged KV cache, GIL-free hot path. Done:justapi-cligained aninferencefeature +--model/--gpuflags that
build ajustapi_inference::Engineand mount/v1/chat/completions,/v1/completions,/v1/embeddings,/v1/modelsviaServer::with_openai. Smoke-tested end-to-end (non-stream + SSE stream
both return 200 with engine-generated tokens). Real weight loading is
gated on--features real. - Throughput within 2x of vLLM on a hello-world/echo-equivalent LLM workload
(no regression vs our REST numbers). Structural proof: the speculative-
decoding and disaggregated-P/D benchmarks (BENCHMARKS.md) show the scheduler
mechanisms (5.80x tighter ITL, 2.04x throughput for P/D; up to 8.8x tok/step
for speculation). Wall-clock GPU tokens/sec is a gate TODO (needs--features real+ CUDA); our REST numbers already beat FastAPI ~9x, so the serving
layer adds no regression. - All gates green:
cargo test --workspace(248+17+12+97+10),clippy -D warnings,cargo fmt --check, Pythonpytest(Phase 40),twine check
(Phase 40).cargo miri testnot required β the defaultjustapi-inference
path has nounsafeblocks (candle'sunsafeis gated behindreal);
miri still runs onjustapi-core(2 tests, Phase 39). - BENCHMARKS.md updated with LLM-serving numbers (speculative decoding,
disaggregated P/D structural benchmark).
Production-readiness hardening (post-audit, 2026-07-15)
Status of the P0 sprint driven by the MED#9 audit verdict (see BENCHMARKS.md
"Production-readiness verdict").
- Security defaults (ADR-050): CORS secure-by-default (empty origins),
*+credentials bug fixed;SecurityHeadersopt-in viaenable_secure_headers()(non-HSTS default; HSTS onwith_hsts=True). - Observability (ADR-051): Python
/metricsexports real Prometheus
data;/readyreflects theHealthRegistry(503 on unhealthy dep);register_health_check(name, callable)wires Python probes. - API footguns (prior session, in save-point):
with_default_routes/with_handlerclobber is a hard panic; OpenAPI UI (/openapi.json,/docs,/redoc) served for Python apps. - Dead code / CI (prior session): HTTP/3 removed (ADR-049); fuzz CI
fixed to run all 7 real targets; orphan root.rsremoved;rustfmt.toml
stable-only socargo fmt --checkpasses. - Error-contract unification (P1): single
{"detail": ...}envelope
across core + Python (ADR-052); Rust validation RFC-7807 +{"error":...}
collapsed;application/jsoneverywhere.error_response/validation_responsehelpers added injustapi_core::lib.rs. - Panic model (ADR-053): kept
panic = "abort"+ supervisor restart
(catch_unwind at the GIL FFI boundary is UB + ~3x regression pergil_pool.rs); fixed the per-requestrouter.fallback().unwrap()abort
and audited remaining hot-path unwraps.
Framework bug fixes (post-audit, 2026-07-16)
Two pre-existing test failures (test_websocket.py::test_websocket_scope_and_json
and test_openapi_parity.py::test_openapi_parity) were production-grade bugs,
not test issues:
- WebSocket scope query/headers/client (ADR-054): the Rust WS upgrade
path only passed the requestpathto handlers β query string, headers,
and peer address were dropped, so a Starlette-stylescopehad an emptyquery.WsHandlernow receives aWsConnInfo { path, query_string, headers, client }built from the upgrade request beforehyper::upgrade::onconsumes it. PythonWebSocketscope now reflects the
real query/headers/client. - OpenAPI parity (ADR-054):
build_openapiemittedoperation_id
(wrong key; OpenAPI requiresoperationId), droppedopenapi_extra
extensions, and omitted the default success response whenresponseswas
supplied. Fixed to emitoperationId, mergeopenapi_extra, and always
include the success code (200/status_code). - Frontend SPA mounts (ADR-054):
app.frontend()stored per-mountStaticMount { prefix, dir, fallback }butrun()discarded the prefix
and fallback (only mounted the dir root), so/static/returned 404. CoreServernow honorswith_static_mounts(prefix + SPA fallback) viatry_serve_static. Addedrun_on(listener)to avoid an ephemeral-port
bind race in tests; added Rust integration + unit tests.