> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ilyama.golain.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Omega nodes

> Extend an Omega device with a signed shared library that adds a domain of operations the Console, OTA plans, and the scheduler can invoke.

A **node** is a shared library that Omega loads to give a device a new **domain** of operations: `.dylib` on macOS, `.so` on Linux, `.dll` on Windows. Once a node is registered, each of its ops appears as a button in the Console, can be a step in an OTA plan, and can run on a schedule.

Omega ships three built-in domains this way (`sbom`, `hbom`, `pbom` inventory). Your node uses the same model.

## One contract, two calling conventions

Every node answers the same five questions. Only the mechanism differs by platform.

| | macOS and Linux | Windows |
| - | - | - |
| Artifact | `.dylib` / `.so` with five C exports | `.dll` registered as a COM server |
| Loaded by | `dlopen` in an ephemeral `omega __invoke-node` child, once per invoke | `CoCreateInstance` out-of-process in `dllhost.exe` |
| Isolation | a crashing node kills its child, never the agent | a crashing node kills `dllhost.exe`, never the agent |
| Integrity | signature re-verified before every load | verified once at install |
| Registration | none, symbols are resolved by name | `regsvr32` |

The five questions, in call order:

| Export | Returns |
| - | - |
| `node_abi_version` | the ABI major version, currently `1` |
| `node_domain` | your domain name, for example `hello` |
| `node_capabilities` | JSON listing your ops, their idempotency, schedule, and input schema |
| `node_health` | JSON `healthy`, `degraded`, or `unavailable` with a detail line |
| `node_invoke` | runs one op, returns a code and a human-readable message |

The JSON that crosses those calls is byte-identical on every platform. See [Node contract](/edge/nodes/contract) for the exact shapes and the return-code rules.

## The contract lives with Omega, not in your node

The interface has exactly one home, and it is the Omega repository. A node **imports** the contract and never redeclares it.

| Platform | Where the contract lives | How a node consumes it |
| - | - | - |
| macOS and Linux, Rust | [`node-abi`](https://github.com/golain-io/omega-rs/tree/main/node-abi) crate | depend on `node-abi`, implement the `Node` trait, call `export_node!` |
| macOS and Linux, C or C++ | [`node-abi/include/omega_node.h`](https://github.com/golain-io/omega-rs/blob/main/node-abi/include/omega_node.h) | `#include "omega_node.h"` and define the five functions |
| Windows | [`windows-com-common/omega_node.idl`](https://github.com/golain-io/omega-rs/blob/main/windows-com-common/omega_node.idl) | `importlib("omega_node.tlb")` and declare only your coclass |

> [!WARNING]
>
> This split is deliberate and load-bearing. On Windows, nodes that each carried their own copy of the interface type library fought over one registry key, and uninstalling any one of them broke every other node with `E_NOINTERFACE`. Omega now embeds and registers the interface itself, and a node's type library only references it. On macOS and Linux the same rule keeps every node's five exports and JSON shapes identical to what Omega was built against, so an ABI bump is one change in one place.

Do not copy `omega_node.h`, `omega_node.idl`, or the `node-abi` source into your node. Reference them from a pinned Omega revision.

## Lifecycle

**1. Build**

Compile your node for each target platform and architecture. [Build a node](/edge/nodes/build) walks through the hello node in Rust and C, and cross-compiling a Linux `.so` from a Mac.

**2. Upload as a release artifact**

Add the library to an OTA release. The platform signs the artifact's SHA-256 with its role key.

**3. Ship with a `place_file` step**

Mark the step **Register in node registry**. Omega verifies the signature, lands the file under `dll/{domain}/`, introspects it in a child process, and writes the node to its local registry. See [Ship a node](/edge/nodes/ship).

**4. Operate**

The device publishes its node catalog on `node/report/registry`. The Console's **Node Registry** view lists the domain, version, health, and ops, with **Run** per op and **Enable** / **Disable** per node.

## Reference nodes

| | |
| - | - |
| [`hello-node`](https://github.com/golain-io/omega-rs/tree/main/hello-node) | macOS and Linux, Rust. Copy it, change the domain and ops, ship it. |
| [`windows-com-node`](https://github.com/golain-io/omega-rs/tree/main/windows-com-node) | Windows, C++ COM server. Its README covers the surrogate and marshalling details that every first COM node gets wrong. |

Both implement the same `hello` domain with two ops, `greet` and `ping`, so the platform sees them identically.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.