From the beginning, Sancho connectors were loaded at startup by scanning a hardcoded directory path for Python packages that matched an expected interface. This worked. But it meant adding a new vendor connector required modifying the startup configuration, restarting the runtime, and in some cases patching the loader logic when a connector had slightly non-standard initialization requirements. In practice, adding a new vendor type was a code change, not a configuration change.
Version 0.3 replaces this with a registry model. Here is how it works and why the distinction matters for how Sancho deploys on a real factory floor.
The Problem With the Old Loader
The original connector loader used Python's importlib to dynamically import any module in the connectors/ directory that exported a class inheriting from BaseConnector. The connector class was responsible for declaring its own vendor ID and capability flags. This was fine for the first few connectors we built, where we were the only authors and we could keep the interface contract in our heads.
As the connector count grew, several problems emerged. First, connector versioning was implicit. If a plant was running Sancho with a cell map that referenced fanuc-cns-v1, and we shipped an updated FANUC connector that changed a signal name in the output interface, the old cell map would break silently on the next startup. The runtime would load the new connector, fail to find the expected signal, and the cell would report a configuration error that was difficult to trace back to a connector API change.
Second, there was no way to express connector dependencies. The FANUC CNC connector we added in our 48-hour build sprint (described in a previous post) requires the FOCAS2 DLL to be present on the host machine. The old loader had no mechanism to declare this or to fail gracefully when it was missing, so the first indication that the dependency was absent was a cryptic ImportError at runtime.
Third, and most practically, adding a connector from a third-party developer had no structured path. If a system integrator wanted to add support for a less-common robot model not in our standard library, they had to drop a Python file into the connectors directory with no validation that it actually implemented the interface correctly.
What the Registry Adds
The v0.3 registry is a JSON manifest file (connector-registry.json) that lives in the Sancho configuration directory. Each connector is an entry in this manifest, declaring: connector ID, version, vendor category (robot, plc, protocol-bridge), minimum Sancho runtime version, declared capabilities (what state fields and commands it provides), optional system dependencies, and the module path to load.
At startup, the runtime reads the registry before loading any connector code. It validates each connector entry against the declared interface contract before importing the module. If a cell map references fanuc-cns-v2 but the registry only has fanuc-cns-v1, the runtime reports a clear version mismatch error at startup rather than a silent failure at the first signal read.
Connector versioning is now explicit and forward-declared. When we ship a new connector version that changes any part of the output interface, the version number increments and the old version remains registered until all cell maps referencing it have been updated. This makes connector updates safe to ship without coordinating with every plant running the previous version.
The Capability Declaration Model
The capabilities section of a registry entry is the part that makes the most practical difference for cell map authors. Each connector declares its output capabilities as a typed schema: what state fields it provides, what types they are, what their units are, and whether they are always present or conditionally available based on hardware model.
For the KUKA RSI connector, the capability schema declares: axis positions (6-axis float array, millimeters and degrees), TCP position (float array, millimeters and degrees), cycle state (enum: idle/running/paused/fault), active program number (string), and RSI external axis override values (float, if external axis configuration is present). A cell map author writing a sequence rule that depends on the KUKA TCP position can now query the registry to confirm that data is available before writing the rule, rather than discovering at runtime that the connector does not provide it.
This is most useful for the conditional capabilities, the ones that say "this field is present on model X but not model Y." Previously, a cell map author had to either know the specific robot model at the target plant or write defensive logic that handled the missing field. With the capability schema, the runtime validates the cell map against the capabilities of the connectors it references, and reports which capabilities the map assumes that the connectors do not provide. Validation fails explicitly at configuration time rather than at runtime during production.
Third-Party Connector Support
The registry model also defines a structured path for third-party connector development. A system integrator writing a connector for a Mitsubishi MELFA robot (which is on our beta list but not yet in the standard library) can write a connector that declares itself in a separate registry file, and the v0.3 runtime supports merging multiple registry files at startup. This means a custom connector can be shipped alongside the standard Sancho install without modifying any of the core files, and the custom registry file can be version-controlled independently of the core registry.
We are not saying this fully solves the third-party connector quality problem. A third-party connector that declares capabilities it does not actually implement will still cause runtime failures. The registry does not execute the connector code at validation time, only checks structural conformance of the declaration. But it does give third-party authors a clear specification of what they need to implement, and it gives plant operators a way to understand what a custom connector provides before loading it.
What Does Not Change
The connector runtime interface itself has not changed in v0.3. Connectors still implement the same lifecycle methods (init, poll, command, disconnect) and output state updates via the same event bus. Existing connectors continue to work with the new loader; they just need a registry entry added for them, which we have done for all connectors in the standard library as part of the v0.3 release.
Cell maps from v0.2 that reference connectors by their v0.2 IDs will need a one-time update to reference the registered IDs, which in most cases are the same name with a version suffix added. We have published a migration guide and a script that audits an existing cell map against the v0.3 registry and reports any references that need updating.
Read next: Adding FANUC CNC Support to Sancho in 48 Hours: A Connector Build Log