The Module System
A module is a unit — binary, asset, or both — defined by a module descriptor. The Backend Kernel composes and hot-swaps them at runtime. Descriptors are written in a TOML-inspired DSL that adds support for expressions; they are designed to be human-readable, machine-generable, and AI-friendly through the Model Context Protocol (MCP).
Why modules, not scripts
Scripts are black boxes. You don’t know what is happening inside a script until you read its code, and even then you have to trust the runtime to behave the way the script intended. Modules invert this. Every parameter, every command line, every dependency, every capability is declared in the descriptor. The black box becomes transparent: you can audit, monitor, and operate the system at the module boundary — and, as Studio ↔ kernel integration lands, do it from Shinro Studio without leaving the GUI. The same descriptor that the kernel uses to compose the module is the descriptor an engineer reads to understand it, and the descriptor an AI agent consumes through MCP to reason about it. There is one source of truth.
Descriptor example
The descriptor is the only formal definition of a module. Everything the kernel needs to acquire, build, and compose it lives there.
# Illustrative only. Descriptors are written in a TOML-inspired DSL with expressions support.# Canonical schema is being finalized.[module]name = "arduino-toolchain"version = "0.1.0"type = "toolchain"
[capabilities]provides = ["cpp:avr-gcc", "flash:avrdude"]
[requirements]host = ["linux", "macos", "windows"]
[dependencies]"shinro/toolchain-core" = "^0.2"
[acquisition]source = "<vendor download URL>"
[build]steps = ["<build invocation>"]The schema above shows the shape of a descriptor, not its final field set.
Module types
- Toolchain modules — compilers, flashers, simulators-as-toolchains. Provide build steps for other modules.
- Library modules — reusable code units (perception primitives, SLAM, motion planning).
- Hardware modules — abstractions over a physical board, sensor, or actuator family. Tie into the Hardware abstraction layer (HAL) and Hardware discovery.
- Resource modules — source files, images, datasets, model weights, calibration data, recordings — any kind of asset that participates in the module graph but is not itself executable.
- Capability modules — higher-level features composed of other modules (e.g., a “follow-me” capability built on perception + control libraries).
Capabilities and requirements
Modules declare what they provide and what they require from the environment. The kernel refuses to compose incompatible modules at install time, not at runtime. A capability mismatch surfaces as a kernel error before any code runs, not as a crash in the middle of a deployment.
Versioning
Per-module version constraints, similar in spirit to Cargo (caret, tilde, exact). A module declares its dependency versions explicitly, the kernel resolves the graph, and ambiguity surfaces at the descriptor level rather than the binary level.
Wrapping reusable code as a library module
A library module can wrap a reusable code unit — including the Python control framework described in Python Modules — behind a descriptor, so the kernel can acquire, build, and compose it like any other dependency. That wrapping is a future integration path, not something that exists today: right now, using the Python modules architecture means writing Python directly against its ABCs, not authoring a descriptor for it. See Terminology for how “module” is used consistently between this kernel-descriptor system and Shinro’s Python-side composition pattern — the two are related but distinct.
Registries and stores
A registry is a descriptor index: a git repository of module descriptors the kernel can pull from. The official Shinro catalog is the default registry; teams can also run their own, self-hosted or shared. A store is different: it is the on-disk location where a module’s acquired or built content lives, shared across every project that resolves the same store. See The Module Catalog and Creating a Module for both in practice.
Working folders
Modules install into per-session working folders rather than mutating the host OS. The working folder is the only writable surface. A clean session is one folder deletion away.
Hot-swap module deployment
Hot-swap is atomic at the module boundary: a running module is replaced as a unit, and the new version is composed with the rest of the graph through the same capability / requirement interface. The kernel guarantees that the swap either completes coherently or is rejected before any state moves.
Shared-RAM inter-module communication
Modules communicate via shared memory, not serialized message passing. This removes the serialization cost — no serialize/deserialize step between modules — while a module’s declared inputs and outputs still define what it may read. Zero-copy IPC, not unscoped aliasing.
MCP integration
The descriptor is the contract between the kernel, the engineer, and the AI. Through the Model Context Protocol, an AI agent can read the descriptor of every loaded module — its capabilities, its requirements, its current state, its dependencies — and reason about the system as a whole rather than guessing from logs. This is what makes agentic engineering on top of Shinro tractable: the agent operates on the same source of truth the kernel does.
Kernel API
The Backend Kernel exposes a small surface for module load, swap, and capability lookup. The full API reference is not yet published.
CLI
The Shinro CLI (invoked as cake) manages kernel initialization, module installation, composition, and deployment. For a hands-on introduction, see Creating a Module. The full command reference is not yet published.