This service is the Kotlin-based Reef platform runtime. It is the core artifact used by the default Reef-only profile; optional products attach through product-neutral route and risk extension ports.
Responsibilities:
- expose HTTP and WebSocket APIs
- handle platform commands
- orchestrate domain workflows
- persist canonical state
- publish domain events
- build read models for UI consumption
- integrate with the matching engine
- expose generic admin/data gateway contracts without importing optional-product implementations
Current state includes:
- Kotlin source and Gradle build scaffold
GET /healthPOST /orders/submit(legacy/internal; requiresPLATFORM_LEGACY_MUTATION_ROUTES_ENABLED=trueandX-Reef-Internal-Route: true)POST /orders/cancel(legacy/internal; requiresPLATFORM_LEGACY_MUTATION_ROUTES_ENABLED=trueandX-Reef-Internal-Route: true)POST /orders/modify(legacy/internal; requiresPLATFORM_LEGACY_MUTATION_ROUTES_ENABLED=trueandX-Reef-Internal-Route: true)POST /api/v1/orders/submit(requiresX-Client-Id+Idempotency-Key)POST /api/v1/orders/cancel(requiresX-Client-Id+Idempotency-Key)POST /api/v1/orders/modify(requiresX-Client-Id+Idempotency-Key)GET /api/v1/commands/{commandId}with provider-neutral command status- participant-scoped own-order/fill reads, public market-data snapshots/depth/trade tape/bars, and data-availability inventory
- scenario-scoped settlement facts, obligation, exception, ledger, proof, and score reads
- reference data endpoints for instruments, participants, and accounts
- query endpoints for orders, trades, events, and trace timelines
- transport path to the Go matching engine over HTTP or gRPC
- unit-testable API and application layers
- runtime-to-engine transport selection (
ENGINE_TRANSPORT=http|grpc|grpc-stream)
Bot Arena is not compiled into this artifact. services/arena-control-plane
provides the optional Arena route/risk extension and compose.arena.yml opts
into its image and datasource. Use make build-reef-core,
make test-reef-core, and make check-reef-arena-boundaries to verify this
dependency direction.
Current persistence caveat:
- durable mode uses explicit domain-schema table names instead of relying on JDBC
currentSchema - migration-owned runtime/auth/boundary table definitions are applied automatically by local dev startup/reset
- Docker/local runtime defaults to
RUNTIME_DB_BOOTSTRAP_MODE=validate;compatremains available only as a local repair fallback - narrowing/removing service-side compatibility bootstrap code is still pending
- the intended direction is split-ready domain schemas (
runtime,boundary,auth,admin) with migration-owned tables and procedure-first critical write paths
Run locally when Gradle is available:
cd services/platform-runtime
GRADLE_USER_HOME=/tmp/reef-gradle ./gradlew test
GRADLE_USER_HOME=/tmp/reef-gradle ./gradlew runOpt-in Calcify finite O2 runtime:
- Set
CALCIFY_FINITE_BINDING_DIGESTonly for separately provisioned finite fixture. Dedicated composition runs canonical submit/modify/cancel API and lifecycle capture in one JVM; startup validates existing binding, topic identities, source generation and managed state. - Provision
boundary/0013andruntime/0076through trusted migration owner. Runtime validates schema and uses restricted function grants. Registrar stages/releases only after fresh engine/capture nonce receipts and exact current SQL/broker cuts. - Supply private DB, ingress-Kafka, capture-Kafka, service and client credential files using
CALCIFY_FINITE_*_PASSWORD_FILE,CALCIFY_FINITE_SERVICE_TOKEN_FILEandCALCIFY_FINITE_CLIENT_TOKEN_FILE. Ingress and capture use separate broker principals; client file pins actor/participant/account scopes. - Pin
CALCIFY_FINITE_OWNER_INSTANCE_ID,CALCIFY_FINITE_STATE_DIRECTORY, authenticated Kafka protocol and canonical binding. Initial start and same-binding restart remain STOPPED until fresh trusted release. Unresolved publication blocks release; stopped capture may drain already known source. 202follows actual typed broker ACK plus durable PUBLISHED/receipt write. Timeout records uncertainty and stops admission; late positive ACK repairs original charge without reopening or resending.- Finite contract, source scope and current O2 status own exact configuration and acceptance. O2 merged (PR488) after independent reviews 2 and 3 ("Ready with non-blocking follow-ups"); G1-G8/G10 live replay remains open. Financial adoption and throughput qualification remain later gates.
Transport config:
PLATFORM_HTTP_SERVER=jdk|nettyselects the runtime HTTP adapter (defaultjdk). Thenettyadapter is currently a measured hot-path adapter for submit/status/internal stats during no-DB ceiling tests.PLATFORM_NETTY_BOSS_THREADS=1,PLATFORM_NETTY_WORKER_THREADS=0,PLATFORM_NETTY_APPLICATION_THREADS, andPLATFORM_NETTY_APPLICATION_MAX_PENDING_TASKS=2048tune the Netty adapter.0worker threads uses Netty's default event-loop sizing; blank application threads use a CPU-aware runtime default.ENGINE_TRANSPORT=grpc(Docker dev default; real gRPC client path to matching-engine)ENGINE_TRANSPORT=grpc-stream(experimental submit-order lane transport using persistent bidirectional gRPC streams; cancel/modify fall back to unary gRPC)ENGINE_TRANSPORT=http(legacy HTTP client path, useful for A/B comparisons)ENGINE_GRPC_STREAM_LANES=16andENGINE_GRPC_STREAM_QUEUE_CAPACITY=100000tune the experimental stream transport lanes and per-lane in-flight capacity.MATCHING_ENGINE_BASE_URLfor HTTP transport (defaulthttp://localhost:8081)MATCHING_ENGINE_GRPC_TARGETfor gRPC transport target (defaultlocalhost:9081)ENGINE_GRPC_DEADLINE_MSfor runtime-to-engine gRPC command deadlines (default2000)
External boundary config:
EXTERNAL_API_AUTH_MODE=allow-all|static-token(defaultallow-all)EXTERNAL_API_TOKENS=client-1:token-1:actors=bot-1:participants=participant-1:accounts=account-1(used bystatic-token; non-local deployments require actor, participant, and account scopes per client)EXTERNAL_API_RATE_LIMIT_MODE=allow-all|fixed-window(defaultallow-all)EXTERNAL_API_RATE_LIMIT_MAX(default120)EXTERNAL_API_RATE_LIMIT_WINDOW_SECONDS(default60)EXTERNAL_API_ABUSE_BREAKER_MODE=off|reject-rate(defaultoff)EXTERNAL_API_ABUSE_BREAKER_ENABLED=true|false(defaulttruewhen mode isreject-rate)EXTERNAL_API_ABUSE_BREAKER_REJECT_RATE_ENABLED=true|false(defaulttrue)EXTERNAL_API_ABUSE_BREAKER_MAX_REJECTS(default50)EXTERNAL_API_ABUSE_BREAKER_WINDOW_SECONDS(default30)EXTERNAL_API_ABUSE_BREAKER_BLOCK_SECONDS(default60)EXTERNAL_API_ABUSE_BREAKER_REJECT_CODEScomma list (defaultINVALID_STATE,NOT_FOUND,REFERENCE_DATA_ERROR,VALIDATION_ERROR)EXTERNAL_API_ABUSE_BREAKER_ROUTEScomma list (default/api/v1/orders/submit,/api/v1/orders/modify,/api/v1/orders/cancel)EXTERNAL_API_ABUSE_BREAKER_ROUTE_POLICIESoptional comma list ofroute:maxRejects/windowSeconds/blockSeconds(example:/api/v1/orders/modify:10/30/120)EXTERNAL_API_ABUSE_BREAKER_WARN_ONLY=true|false(defaultfalse)EXTERNAL_API_AUTHORIZATION_CACHE_TTL_MS(default1000) bounds how long submit/cancel/modify hot paths reuse actor-role and role-permission reads before rechecking persistence.EXTERNAL_API_REFERENCE_DATA_CACHE_TTL_MS(default1000) bounds how long submit hot paths reuse instrument/participant/account validation results before rechecking persistence.EXTERNAL_API_IDEMPOTENCY_STORE=inmemory|postgres(defaultinmemory)EXTERNAL_API_COMMAND_CAPTURE_MODE=postgres|inmemory|disabled(defaultpostgres)EXTERNAL_API_COMMAND_LOG_MODE=disabled|postgres|inmemory(defaultdisabled;postgresappends inbound/api/v1commands tocommand_log.commands)EXTERNAL_API_COMMAND_PROCESSING_MODE=sync-result|captured-sync-engine|captured-ack|stream-ack|accepted-async(defaultsync-result; captured modes require command-log capture,stream-ackrequires the configured JetStream or Kafka-compatible durable provider, andaccepted-asyncis an in-memory no-DB isolation mode)EXTERNAL_API_ACCEPTED_ASYNC_LANES,EXTERNAL_API_ACCEPTED_ASYNC_QUEUE_CAPACITY,EXTERNAL_API_ACCEPTED_ASYNC_IN_FLIGHT_PER_LANE, andEXTERNAL_API_ACCEPTED_ASYNC_OFFER_TIMEOUT_MStune the no-DB accepted-async submit intake. The default in-flight window is32per lane to avoid flooding the engine stream.EXTERNAL_API_ACCEPTED_ASYNC_OFFER_TIMEOUT_MSabove0blocks the calling HTTP application thread waiting for lane capacity;EXTERNAL_API_ACCEPTED_ASYNC_OFFER_WAIT_MAX_CONCURRENCY(default8) bounds how many application threads can be parked in that wait at once, so a backpressure spike fails fast as429instead of exhausting the shared HTTP thread pool.EXTERNAL_API_ACCEPTED_ASYNC_STATUS_RETENTION_MAX_RECORDS(default1000000) andEXTERNAL_API_ACCEPTED_ASYNC_STATUS_RETENTION_TTL_MS(default900000) bound in-memory command status/idempotency retention.RUNTIME_PERSISTENCE=inmemory|postgres|noop(noopis benchmark-only: keeps reference/auth setup data but drops command outcomes, orders, trades, events, canonical facts, and projections)STREAM_ACK_INTAKE_STORE=postgres|inmemoryselects stream-ack idempotency/intake reservation storage. For no-DB long soaks withinmemory, keepSTREAM_ACK_INMEMORY_INTAKE_MAX_ENTRIESpositive to bound replay-window memory and useSTREAM_ACK_INMEMORY_INTAKE_SHARDSto reduce monitor contention.STREAM_ACK_PUBLISHER=stream|log|noopselects the stream-ack publisher override.noopis benchmark-only and must not be used for durable acceptance claims because the response no longer proves broker append.PLATFORM_RUNTIME_ROLE=materializerconsumes durable venue-event batches and persists compact canonical command outcomes. Submit outcome payloads carry theacceptedOrderprojection fact, so no-DB direct-consume projection can rebuild order rows without enablingcommand_log.command_payloads.PLATFORM_LEGACY_MUTATION_ROUTES_ENABLED=true|false(code defaultfalse; local compose defaulttrue; legacy mutation and reference-data POST routes also requireX-Reef-Internal-Route: true)RUNTIME_DB_BOOTSTRAP_MODE=compat|validate(Docker/local defaultvalidate; usecompatonly for local repair/debug)
Command status lookup:
GET /api/v1/commands/{commandId}returns command status when command-log capture is enabled.
Operational stats endpoint:
GET /internal/boundary/abuse/stats(returns breaker mode/config and counters:trips,blocks,releases,activeBlockedClients)
When EXTERNAL_API_IDEMPOTENCY_STORE=postgres, the runtime reuses:
RUNTIME_DB_URLRUNTIME_DB_USERRUNTIME_DB_PASSWORD
The Postgres boundary stores create/read boundary.api_idempotency_records and boundary.api_command_captures by default.
Current limitation:
- local verification in the Codex sandbox may still need elevated execution because Gradle opens local coordination sockets
- CI is configured to run the Kotlin test suite through the checked-in wrapper
Build guidance:
- follow
docs/steering/architecture.md - follow
docs/steering/kotlin.md - start as a modular monolith with clear bounded contexts
Admin CLI:
- entrypoint:
com.reef.platform.admin.AdminMainKt - commands include:
- reference upserts (
instrument-upsert,participant-upsert,account-upsert) - role/permission admin (
role-upsert,role-assign,roles-list,actor-roles) - calendar and override management (
calendar-upsert,calendar-list,override-upsert,override-list) - simulation controls (
sim-start,sim-pause,sim-stop,sim-state) - trace inspection (
events-recent,trace-events)
- reference upserts (
Order command authorization:
- submit/cancel/modify require actor role permissions (
order.submit,order.cancel,order.modify) - local seed scripts can upsert
order_traderthrough internal/auth/rolesand/auth/actor-rolesendpoints - those HTTP seed endpoints are guarded by
X-Reef-Internal-Route: trueand the same legacy mutation route flag as reference-data seed endpoints