Kernel Services Checklist
Complete inventory of ObjectStack kernel services with protocol methods, implementation status, and development requirements.
Kernel Services Checklist
The ObjectStack protocol defines 17 kernel services registered via the CoreServiceName enum. Each service maps to a set of protocol methods (57 total), governed by the ObjectStackProtocol interface.
Key architecture principle: The kernel itself only provides data and metadata (framework). Everything else — including auth and automation — is delivered by plugins. The current @objectstack/objectql package is an example kernel implementation to get the basic API running; production kernels will be rebuilt as new plugins.
Last Updated: February 2026
- ✅ Implemented — 18 protocol methods (kernel-provided)
- ⚠️ Framework — metadata (in-memory registry, DB persistence pending)
- 🟡 In Development — auth (plugin structure complete, logic planned)
- ❌ Plugin Required — 38 protocol methods (to be delivered by plugins)
Architecture Overview
┌─────────────────────────────────────────────────────────┐
│ Kernel Layer │
│ ┌──────────────────┐ ┌──────────────────────────────┐ │
│ │ metadata (⚠️) │ │ data + analytics (✅) │ │
│ │ In-memory only │ │ ObjectQL example kernel │ │
│ │ DB persistence │ │ Will be rebuilt as plugins │ │
│ │ pending │ │ │ │
│ └──────────────────┘ └──────────────────────────────┘ │
├─────────────────────────────────────────────────────────┤
│ Plugin Layer │
│ All other services: auth, automation, workflow, ui, │
│ realtime, notification, ai, i18n, graphql, search, │
│ file-storage, cache, queue, job │
│ │
│ Discovery API reports: enabled/unavailable/degraded │
│ per service so clients adapt their UI accordingly │
└─────────────────────────────────────────────────────────┘Service Overview
| # | Service Name | Criticality | Methods | Status | Provider |
|---|---|---|---|---|---|
| 1 | metadata | required | 7 | ⚠️ Framework | Kernel (in-memory) |
| 2 | data | required | 9 | ✅ Implemented | @objectstack/objectql |
| 3 | analytics | optional | 2 | ✅ Implemented | @objectstack/objectql |
| 4 | auth | required | — | 🟡 In Development | @objectstack/plugin-auth |
| 5 | ui | optional | 5 | ❌ Plugin Required | TBD plugin |
| 6 | workflow | optional | 5 | ❌ Plugin Required | TBD plugin |
| 7 | automation | optional | 1 | ❌ Plugin Required | TBD plugin |
| 8 | realtime | optional | 6 | ❌ Plugin Required | TBD plugin |
| 9 | notification | optional | 7 | ❌ Plugin Required | TBD plugin |
| 10 | ai | optional | 4 | ❌ Plugin Required | TBD plugin |
| 11 | i18n | core | 3 | ✅ Built-in (in-memory fallback) | @objectstack/service-i18n |
| 12 | file-storage | optional | — | ❌ Plugin Required | TBD plugin |
| 13 | search | optional | — | ❌ Plugin Required | TBD plugin |
| 14 | cache | core | — | ❌ Plugin Required | TBD plugin |
| 15 | queue | core | — | ❌ Plugin Required | TBD plugin |
| 16 | job | core | — | ❌ Plugin Required | TBD plugin |
| 17 | graphql | optional | — | ❌ Plugin Required | TBD plugin |
Criticality Levels
- required: System cannot start without this service
- core: Falls back to in-memory implementation with a warning if missing
- optional: Feature disabled; API returns
501 Not Implementedif missing
1. metadata Service ⚠️ Framework
Service Name: metadata · Criticality: required
Implementation: Kernel — SchemaRegistry (in-memory)
Route Mounts: /api/v1/meta, /api/v1, /api/v1/packages
Protocol Methods
| Method | Signature | Status |
|---|---|---|
getDiscovery | GetDiscoveryRequest → GetDiscoveryResponse | ✅ |
getMetaTypes | GetMetaTypesRequest → GetMetaTypesResponse | ✅ |
getMetaItems | GetMetaItemsRequest → GetMetaItemsResponse | ✅ |
getMetaItem | GetMetaItemRequest → GetMetaItemResponse | ✅ |
saveMetaItem | SaveMetaItemRequest → SaveMetaItemResponse | ✅ |
getMetaItemCached | GetMetaItemCachedRequest → GetMetaItemCachedResponse | ✅ |
getUiView | GetUiViewRequest → GetUiViewResponse | ✅ |
Current Limitations
The metadata service is a framework — it works with an in-memory SchemaRegistry loaded from YAML/TS config files at startup.
| Gap | Description | Priority |
|---|---|---|
| DB Persistence | Metadata is only in memory; no save-to-database path exists | P0 |
| Multi-instance Sync | No mechanism to share metadata changes across instances | P1 |
| Migration / Versioning | No schema diff or migration tooling | P1 |
| Hot Reload | Metadata changes require restart | P2 |
Discovery: Per-Service Status
The discovery endpoint returns a services map so clients know what is available:
{
"services": {
"metadata": {
"enabled": true, "status": "degraded",
"route": "/api/v1/meta", "provider": "kernel",
"message": "In-memory registry; DB persistence pending"
},
"data": {
"enabled": true, "status": "available",
"route": "/api/v1/data", "provider": "kernel"
},
"auth": {
"enabled": false, "status": "unavailable",
"message": "Install an auth plugin to enable"
}
}
}2. data Service ✅ Implemented
Service Name: data · Criticality: required
Implementation: @objectstack/objectql → ObjectQL (IDataEngine)
Route Mount: /api/v1/data
@objectstack/objectql is an example kernel implementation to get the basic data API running. Future production kernels will be developed as separate plugins.
Protocol Methods
| Method | Signature | Status |
|---|---|---|
findData | FindDataRequest → FindDataResponse | ✅ |
getData | GetDataRequest → GetDataResponse | ✅ |
createData | CreateDataRequest → CreateDataResponse | ✅ |
updateData | UpdateDataRequest → UpdateDataResponse | ✅ |
deleteData | DeleteDataRequest → DeleteDataResponse | ✅ |
batchData | BatchDataRequest → BatchDataResponse | ✅ |
createManyData | CreateManyDataRequest → CreateManyDataResponse | ✅ |
updateManyData | UpdateManyDataRequest → UpdateManyDataResponse | ✅ |
deleteManyData | DeleteManyDataRequest → DeleteManyDataResponse | ✅ |
Driver Support
| Driver | Package | CRUD | Aggregation | Ready |
|---|---|---|---|---|
| InMemory | @objectstack/driver-memory | ✅ | ✅ | Dev/Test |
| PostgreSQL | TBD | — | — | — |
| MySQL | TBD | — | — | — |
| MongoDB | TBD | — | — | — |
| SQLite | TBD | — | — | — |
3. analytics Service ✅ Implemented
Service Name: analytics · Criticality: optional
Implementation: @objectstack/objectql (driver-level capability)
Route Mount: /api/v1/analytics
Protocol Methods
| Method | Signature | Status |
|---|---|---|
analyticsQuery | AnalyticsQueryRequest → AnalyticsResultResponse | ✅ |
getAnalyticsMeta | GetAnalyticsMetaRequest → AnalyticsMetadataResponse | ✅ |
Features
- Cube semantic queries: measures / dimensions / filters → ObjectQL aggregation
- Auto-generated metadata from SchemaRegistry (numeric → sum/avg, date → time dimensions)
4. auth Service ❌ Plugin Required
Service Name: auth · Criticality: required
Route Mount: /api/v1/auth — only exposed when a plugin registers the auth service
The kernel does NOT handle auth. Install an auth plugin to enable authentication. Without it, the discovery response shows auth: { enabled: false, status: "unavailable" }.
Plugin Requirements
The auth service covers both authentication (identity) and authorization (permissions). There is no separate permission service in CoreServiceName.
| Module | Area | Description | Priority |
|---|---|---|---|
| Identity Provider | Authentication | JWT issuance/verification, session management | P0 |
| User CRUD | Authentication | Create / read / update / delete users | P0 |
| Role Management | Authentication | Role definitions, role-user associations | P0 |
| Permission Engine | Authorization | Object-level and field-level permissions | P0 |
| OAuth2 / OIDC | Authentication | Third-party login (Google, GitHub, etc.) | P1 |
| Sharing Rules | Authorization | Record-level sharing and visibility | P1 |
| Row-Level Security | Authorization | Automatic query filtering by user context | P1 |
| Multi-tenancy | Authentication | Space / Tenant isolation | P1 |
| Territory Management | Authorization | Data territory assignment and access | P2 |
| SCIM | Authentication | Enterprise user provisioning protocol | P2 |
Spec Files: identity.zod.ts, role.zod.ts, organization.zod.ts, auth-config.zod.ts, tenant.zod.ts
5–7. Business Services ❌ Plugin Required
5. ui Service — 5 methods
listViews, getView, createView, updateView, deleteView
View CRUD, layout engine, action registry, permission filtering.
6. workflow Service — 5 methods
getWorkflowConfig, getWorkflowState, workflowTransition, workflowApprove, workflowReject
State machine engine, approval processes, audit trail.
7. automation Service — 1 method
triggerAutomation
Trigger engine, event triggers from ObjectQL hooks, flow executor, scheduled triggers.
8–11. Communication Services ❌ Plugin Required
8. realtime — 6 methods
realtimeConnect, realtimeDisconnect, realtimeSubscribe, realtimeUnsubscribe, setPresence, getPresence
9. notification — 7 methods
registerDevice, unregisterDevice, getNotificationPreferences, updateNotificationPreferences, listNotifications, markNotificationsRead, markAllNotificationsRead
10. ai — 4 methods
aiNlq, aiChat, aiSuggest, aiInsights
11. i18n — 3 methods
getLocales, getTranslations, getFieldLabels
Service Name: i18n · Criticality: core
Implementations: @objectstack/service-i18n (production — file-based) · Built-in in-memory fallback · Dev Plugin (in-memory stub)
Route Mount: /api/v1/i18n
Contract: II18nService in @objectstack/spec/contracts
Service Registration
The i18n service is a core built-in service with automatic in-memory fallback. If no plugin registers the service, the kernel automatically injects an in-memory implementation during startup:
| Environment | Provider | Registration |
|---|---|---|
| Production | I18nServicePlugin | File-based FileI18nAdapter loads JSON locale files from disk |
| Built-in Fallback | Kernel | In-memory Map-backed stub, auto-injected when no plugin provides i18n |
| Development | DevPlugin | In-memory Map-backed stub, supports loadTranslations() |
| Mock / MSW | MswPlugin | Routes via HttpDispatcher.dispatch() catch-all — requires one of the above |
// Production (overrides built-in fallback)
kernel.use(new I18nServicePlugin({ defaultLocale: 'en', localesDir: './i18n' }));
// Development (automatic — DevPlugin registers i18n stub for all 17 core services)
kernel.use(new DevPlugin());
// No plugin required — kernel auto-injects in-memory fallback if none registered
const kernel = new ObjectKernel();
await kernel.bootstrap(); // i18n service available via built-in fallbackDiscovery & Handler Consistency
The Discovery API (/api/v1 or /.well-known/objectstack) and the i18n route handler (/api/v1/i18n/*) both use the same async resolution chain to detect i18n availability:
getServiceAsync() → getService() → context.getService() → services MapThis ensures that discovery.services.i18n.status always matches the actual runtime behavior — a service registered via any mechanism (sync Map, async factory, or context) will be reported correctly in both places.
The locale field in the discovery response is populated from the actual i18n service:
locale.default— fromi18nService.getDefaultLocale()(falls back to'en')locale.supported— fromi18nService.getLocales()(falls back to[default])
AppPlugin Auto-Loading
When an app bundle includes an i18n config and translations array, AppPlugin automatically loads the translation data into the i18n service during the start phase:
export default defineStack({
manifest: { id: 'com.example.crm', namespace: 'crm' },
i18n: { defaultLocale: 'en', supportedLocales: ['en', 'zh-CN'] },
translations: [CrmTranslations], // TranslationBundle[]
});AppPlugin will:
- Set the default locale via
i18nService.setDefaultLocale() - Call
i18nService.loadTranslations(locale, data)for each locale in every bundle - Skip gracefully if no i18n service is registered (no errors, just a debug log)
REST API Endpoints
| Method | Path | Description |
|---|---|---|
GET | /api/v1/i18n/locales | List available locales |
GET | /api/v1/i18n/translations/:locale | Get all translations for a locale |
GET | /api/v1/i18n/labels/:object/:locale | Get translated field labels for an object |
12–17. Infrastructure Services ❌ Plugin Required
| Service | Description |
|---|---|
| file-storage | Unified upload/download/delete. Drivers: local FS, S3, MinIO. |
| search | Full-text search. Drivers: in-memory, Elasticsearch, Meilisearch. |
| cache | General-purpose cache. Drivers: in-memory LRU, Redis. |
| queue | Message queue. Drivers: in-memory, BullMQ / Redis Streams. |
| job | Scheduled task execution. Cron-based, concurrency control. |
| graphql | Auto-generate GraphQL schema from Object metadata. |
Recommended Development Phases
Phase 1: Foundation (P0)
| Plugin | Description |
|---|---|
| plugin-auth | Identity engine — JWT, sessions, user CRUD, roles |
| plugin-ui | View CRUD — core low-code capability |
| plugin-cache | General-purpose cache — performance infrastructure |
| Metadata DB | Solve metadata persistence (SchemaRegistry → database) |
Phase 2: Business Engine (P1)
| Plugin | Description |
|---|---|
| plugin-workflow | State machine + approval process |
| plugin-automation | Triggers + flow orchestration |
| plugin-i18n | Internationalization |
| plugin-storage | File storage (local + S3) |
| DB drivers | PostgreSQL, MySQL, MongoDB, SQLite |
Phase 3: Advanced Capabilities (P2)
| Plugin | Description |
|---|---|
| plugin-realtime | WebSocket / SSE real-time push |
| plugin-notification | Notification engine |
| plugin-ai | NLQ, chat, suggestions, insights |
| plugin-graphql | GraphQL API endpoint |
| plugin-search | Full-text search |
| plugin-job | Scheduled tasks |
| plugin-queue | Message queue |
Plugin Implementation Pattern
import type { Plugin } from '@objectstack/core';
export const authPlugin: Plugin = {
name: 'plugin-auth',
provides: ['auth'], // CoreServiceName value
async init(ctx) {
const engine = ctx.getService<IDataEngine>('data');
const authService = new AuthServiceImpl(engine);
ctx.registerService('auth', authService);
},
async start(ctx) {
const auth = ctx.getService<IAuthService>('auth');
await auth.onReady();
},
async stop(ctx) {
const auth = ctx.getService<IAuthService>('auth');
await auth.shutdown();
},
};When a plugin registers a service, the discovery endpoint automatically updates:
services.auth.enabled→true,status→"available",route→"/api/v1/auth"routes.auth→"/api/v1/auth"appears in routesfeaturescapability flags update accordingly