Architecture
The ScaiCore language and its standalone runtime are documented separately at /docs/scaicore. They are not part of this module. This page is about the ScaiGrid wrapper that hosts a compiled ScaiCore program inside ScaiGrid — what it adds and where the seam is.
Two ScaiCores, one diagram#
ScaiCore-the-library is invoked, not deployed. The wrapper holds the IR bundle, manages the row, calls CoreEngine.ainvoke() / aresume() on behalf of API or event callers, and threads ScaiGrid services into the HostEnvironment so the program can use real Redis, real MariaDB, real model inference, real S3, and real event bus instead of in-process stubs.
What the wrapper owns#
- Persistence. The
mod_scaicore_corestable holds the IR source, the runtime config, the identity mode, the plugins list, the (encrypted) environment, the avatar URL, and the lifecycle status. - Lifecycle state machine.
created → starting → running → stopping → stopped;running → paused → running;running → error;crashed → restarting → running. The wrapper enforces the legal transitions. - HostEnvironment backends. Production backends for memory (Redis), checkpoints (S3 + MariaDB), models (
InferenceService), events (EventBus), plugins (HTTP bridge), entity placement (Redis Grain Directory). - Checkpoints. Captured into
mod_scaicore_checkpoints, routed by assignee, expired or escalated by a 5-minute cron, resolved via the API or the admin UI's checkpoint queue. - Identity. Service-account by default. Delegation lets a Core run as a specific human user, with explicit scopes and an optional expiry; the delegated user is resolved on
start()exactly like JWT auth. - Plugins. Plugin definitions live on the Core row as a JSON list; the HTTP bridge in the HostEnvironment calls the registered endpoints when the program asks for them.
- Publishing. A Core can be published as a
FrontendModel(slugscaicore/{tenant_slug}/{core_slug}); after publication the Core is callable through any model-aware ScaiGrid API. - Admin UI pages. Dashboard, editor, console, logs, debugger, identity, checkpoint queue, checkpoint history, plugin marketplace, event monitor (mounted by the module registry).
What the language owns#
- The DSL, the compiler, the IR format, semantic versioning of IR schema.
CoreEngine.ainvoke()/aresume()— interpreting the IR, calling models, materialising checkpoints, scheduling resume.- The
HostEnvironmentprotocol — what the wrapper has to implement to host a Core. - Standalone-runtime concerns (CLI tooling, local dev, package layout).
If something feels like "how does the program execute?", that's the language. If something feels like "how do I run the program in ScaiGrid and let humans interact with it?", that's this module.
Request flow for one event#
- Caller posts
POST /v1/modules/scaicore/cores/{id}/eventswith{event_name, data}. - Auth. Standard ScaiGrid bearer-token auth; tenant scoping enforced on every row read.
- Routing. The wrapper resolves the Core, validates it is
running, and dispatches toCoreEngine.ainvoke()withtrigger_type=EVENT. (Eventing currently records the dispatch asaccepted— runtime invocation is wired through the HostEnvironment.) - Execution. The CoreEngine interprets the relevant flow; tool calls / inference go out through the InferenceService and back; events fire over the EventBus.
- Checkpoint (if any). Execution suspends; a row is written to
mod_scaicore_checkpoints; a notifier emails the resolved assignee. - Resolution. A human posts
POST /checkpoints/{id}/resolve; the row is updated; the runtime resumes from the captured state.
State#
- Cores, checkpoints, delegations, plugin configs — MariaDB tables under the
mod_scaicore_*prefix. - Encrypted env vars —
environment_encryptedblob on the Core row, with a wrapped DEK + IV. - Avatars — Garage S3 under
scaicore/{tenant_id}/{core_id}/avatar, served back through an internal proxy path. - Checkpoint state blob — S3, keyed by
state_s3_keyon the row. - Engine instances — in-process
EngineRegistrykeyed bycore_id; cleaned up onstop/delete.
How it differs from the standalone runtime#
The standalone runtime (documented at /docs/scaicore) runs a Core in-process with stub backends. The wrapper differs in five places:
| Concern | Standalone | ScaiGrid wrapper |
|---|---|---|
| Storage | In-memory / local files | MariaDB + S3, tenant-scoped |
| Identity | Whatever you pass in | Service-account or delegated human |
| Checkpoints | Block until resolved in-process | Persisted, routed to assignees, surfaced in admin UI |
| Models | You wire them | Resolved through ScaiGrid's inference router (accounted) |
| Multi-tenancy | None | Every row tenant-scoped, RBAC-gated, audit-logged |
For everything else — the IR, the compiler, semantic versioning, language reference — see /docs/scaicore.