Product groups & plugins
Passport obligations arrive one product group at a time, each under its own act and with its own date, and each group’s rules change as the acts are finalised. The core expects this: every product group’s compliance logic is added through the same extension point.
The product groups
Section titled “The product groups”The software models eleven product groups: batteries, textiles, iron and steel, aluminium, tyres, furniture, mattresses, phones and tablets, toys, detergents and construction products. The unsold-goods disclosure is modelled too, but it is not a product group and carries no passport; see The unsold-goods disclosure.
Each group has a versioned schema, a list of the product categories it distinguishes, and a map of which fields are restricted to credential holders. A node can tell you, for each group, whether a passport is required, from when and under which acts:
odal product-group list # every group, whether a passport is required and from whenodal product-group show battery # one group in full, with the acts behind itodal schema list # the schema version this node serves for each groupodal template battery # the CSV header row an import expectsOne interface for every product group
Section titled “One interface for every product group”Each group’s rules sit behind a single shared interface. Adding a group, or updating one when the regulation changes, means supplying new logic through that interface without changing the rest of the system. The core repository has ten plugins, covering every group except mattresses.
A group with no plugin loaded still works: its passports are checked against the schema, but no group-specific rules run and no findings are produced. The node reports this at start-up, so “no findings” is not mistaken for “checked and clean”. A node started with the production profile refuses to run without a plugin for every group whose passport obligation is live.
Sandboxed by default
Section titled “Sandboxed by default”A plugin is WebAssembly and runs in an isolated sandbox with no filesystem and no network, a 64 MiB memory cap and a metered CPU budget. It can judge a passport’s data and nothing more: it cannot reach the signing key, the database or the rest of the node. The exact limits are on Operating a node securely.
Signed, and installed without a restart
Section titled “Signed, and installed without a restart”A node runs a plugin only if it is signed by the publisher key its operator pins (PLUGIN_SIGNING_KEY). Without a key configured, a node refuses to start while unsigned plugins are present, unless ALLOW_UNSIGNED_PLUGINS=true is set. That override is honoured only under the development profile and logs a warning: a sandbox or production node refuses to start with it set, and an unsigned plugin never counts as real rule checking.
A new signed version can be installed on a running node:
odal plugin install product-group-battery.wasm # uploads the .wasm and its sibling .sigThe node verifies the signature, checks the plugin’s interface version, stores it so a restart reloads it, and switches it into service. A plugin that fails any step is refused, and the previous one keeps running.
Writing a plugin
Section titled “Writing a plugin”A plugin is a Rust crate compiled to wasm32-wasip1 against the core’s plugin SDK. The SDK generates the interface the node calls and a describe() export the node checks before it sends anything to the plugin. The battery plugin in the core repository is the reference implementation.
All of it is open
Section titled “All of it is open”The extension point is part of the architecture, not a pricing tier. The built-in product groups and any added later use the same mechanism, and all of them are open. New regulatory coverage is never a paid add-on.
Read next
Section titled “Read next”- What the core does: the library the product groups plug into.
- Battery DPP · Textile DPP · Toy DPP · Detergent DPP · Construction product DPP · Phones and tablets: product groups in context.
- Acts and standards: the acts each group rests on.
Information on this site is not legal advice. Legal noticePrivacy policy