CRI Format
Overview
A CRI (Kinotic Resource Identifier) is used by Kinotic to route requests to the appropriate service, method, or event stream. It is a URI-like format with parts named for clarity within the Kinotic platform.
Format
scheme://[scope@][zone~]resourceName[/path][#version]
Everything in brackets ([]) is optional.
Case
Every part keeps the case it was written with, and addresses match by exact string comparison — OrderService and OrderService are two different addresses. Service names carry the case of the class that published them, so a typical address looks like:
srv://management-api~org.kinotic.management.api.services.ProjectService/findByRepoFullName
Components
Scheme
Identifies the type of resource being addressed.
| Scheme | Description |
|---|---|
srv | Published services and their methods |
stream | Event streams (not yet routable through the gateway) |
Scope
An optional qualifier that narrows the CRI to a specific context, such as a tenant ID, user ID, or device ID. When present, it appears before the @ symbol.
If a scope needs sub-scopes, use the format scope:sub-scope.
srv://tenant-123@app.acme-org.orders-app~OrderService
stream://device-42@app.acme-org.orders-app~temperature/sensor-1
Zone
The optional zone places the resource in the isolation boundary the gateway validates on every send and subscribe. It precedes the resourceName, separated by ~. A zone is one or more dot-separated labels of lowercase letters, digits, and interior dashes.
| Zone | Description |
|---|---|
app.<organizationId>.<applicationId> | One application's services. Only that application's participants and the owning organization's runtimes can call them, through the app server, the one server that reaches these zones; they are hosted by the owning organization's runtime, which authenticates as an organization participant. Applications may nest their own sub-zones, e.g. app.acme-org.orders-app.billing. |
app-api | The platform's data plane for applications, such as entity persistence and named query execution. Hosted in-process by the platform only. |
management-api | The platform services organizations manage the system through, such as member, application, and entity definition management. Hosted in-process by the platform only. |
system-api | Platform-internal services. Only system participants can call or host them. |
A cluster member outside the platform's servers can host its services in management-api, where organizations' users call them through the management server as they call the platform's own; such a service checks the caller's organization itself.
Organization and application ids become zone labels, but only ever after the app prefix, so they cannot collide with the platform's own zones. The one exception is guarded explicitly: creating an organization or application whose name slugifies to system-api is rejected.
Which zones a connection may address is determined by the authenticated participant. A participant may also address any sub-zone of a zone it is allowed, so app.acme-org.orders-app.billing is reachable by whoever may reach app.acme-org.orders-app. An address without a ~ carries no zone at all and is only reachable by system participants.
| Participant | May send to | May subscribe to |
|---|---|---|
| APPLICATION (org, app) | app-api, app.<org>.<app> | reply destinations only |
| ORGANIZATION (org) | management-api, app-api, app.<org>.* | app.<org>.* — its applications' zones |
| SYSTEM | everything | system-api |
Each server also has a zone partitioning, the zones it hosts and the zones it reaches. A node advertises a service to the cluster only in a zone its server hosts, and sends only to zones its server reaches: an address in any other zone has no handlers there. An address without a zone passes both.
| Server | Hosts | Reaches |
|---|---|---|
| org | management-api | management-api, system-api, app-api |
| system | system-api, management-api | system-api, management-api |
| app | app-api, app.* | app-api, app.* |
The gateway applies the partitioning before a frame reaches the event bus: a send to a zone the server does not reach, or a subscription in a zone it does not host, is refused whatever the participant may address. The service directory and listener monitors still see every registration in the cluster, so a service hosted by one server shows as online from any other, while each server's MCP listing shows only the tools in zones it reaches.
Resource Name
The name of the resource being addressed, excluding the zone. For services, this is the fully qualified service name. For streams, this is the event type name.
srv://management-api~com.example.UserService
stream://app.acme-org.orders-app~temperature
Path
An optional path that identifies a specific part of the resource, such as a method name on a service. The path's case is preserved.
srv://management-api~com.example.UserService/findById
stream://app.acme-org.orders-app~temperature/sensor-1
Version
An optional semantic version for the resource. Enables versioned service routing so multiple versions of a service can coexist.
srv://management-api~com.example.UserService/findById#1.0.0
srv://management-api~com.example.UserService#2.0.0
Factory Function
The createCRI function provides several overloads for constructing CRI instances:
import { createCRI } from '@kinotic-ai/core'
// From a raw string
const cri1 = createCRI('srv://management-api~com.example.UserService/findById#1.0.0')
// From scheme and resource name (which may carry a zone)
const cri2 = createCRI('srv', 'management-api~com.example.UserService')
// From scheme, scope, and resource name
const cri3 = createCRI('stream', 'tenant-123', 'app.acme-org.orders-app~orders')
// From all components
const cri4 = createCRI('srv', null, 'management-api~com.example.UserService', 'findById', '1.0.0')
CRI Interface
The CRI interface provides methods to access each component:
const cri = createCRI('srv://tenant-123@app.acme-org.orders-app~OrderService/placeOrder#2.0.0')
cri.scheme() // 'srv'
cri.scope() // 'tenant-123'
cri.hasScope() // true
cri.zone() // 'app.acme-org.orders-app'
cri.hasZone() // true
cri.resourceName() // 'OrderService'
cri.path() // 'placeOrder'
cri.hasPath() // true
cri.version() // '2.0.0'
cri.hasVersion() // true
cri.baseResource() // 'srv://tenant-123@app.acme-org.orders-app~OrderService'
cri.raw() // 'srv://tenant-123@app.acme-org.orders-app~OrderService/placeOrder#2.0.0'
Examples
| CRI | Description |
|---|---|
srv://management-api~org.kinotic.management.api.services.security.MemberService | A platform service in the management-api zone |
srv://app-api~org.kinotic.persistence.api.services.JsonEntitiesRepository/save | A specific method on a platform service |
srv://app.acme-org.orders-app~OrderService/create#1.0.0 | A versioned method on an application's own service |
srv://app.acme-org.orders-app.billing~InvoiceService | A service in an application-declared sub-zone |
srv://system-api~org.kinotic.system.api.services.workload.WorkloadOrchestrationService | A platform-internal service |
stream://app.acme-org.orders-app~temperature | An application's event stream |
srv://node1@system-api~kinotic-ai.vm-manager.VmManager | A scoped system service targeting one node |