plesty-sdk#17 turns "use the shared data layer" into "don't fork it": three static checks — Gate 4, d2 and e2 — that keep every HUB module speaking the same plesty-lib schemas. Here's what that means when you use plesty, and what you do to keep a module you build green.

plesty-sdk Gate 4 · d2 · e2
Using plesty You can trust the data across modules

Every device's status(), every experiment's results, and every analyzer's input now resolve through one plesty-lib definition — so a value read from one module means the same thing in another. A module can no longer quietly ship its own DeviceStatus or dump loose .npy files that only look compatible: that fails CI now, instead of surfacing as an unresolvable mismatch at runtime while you're taking data.

Nothing to configure — pick any HUB module tagged with the current standard and its data lines up with the rest of your experiment by construction.

Contributing a module Two habits keep you green

The checks run inside plesty check (and in CI), so you find out at your desk, not in review. To pass:

  1. Consume plesty-lib schemas — don't redefine them. Import DeviceStatus, the config / op-schema / telemetry models, ResultDocument and the scheduling models from plesty-lib rather than declaring a class of the same name in your package.
  2. Persist through the data layer. Write results with plesty.lib.data.save_result instead of np.save, pickle.dump, h5py or a raw open(…, "w") inside your module.
  3. Keep the annotations. If you override status() keep it -> DeviceStatus; override device_state() keep it -> str — that's what lets telemetry consumers rely on your module.
✗ what fails — forking the layer
# plesty/mydevice/models.py class DeviceStatus: # ✗ shadows plesty-lib ok: bool # plesty/myexp/run.py np.save(path, frame) # ✗ direct write ✗ 'DeviceStatus' shadows the plesty-lib model ✗ 'np.save(...)' bypasses the data layer
✓ what passes — consume the layer
from plesty.lib.device.funcs import DeviceStatus from plesty.lib.data import save_result def status(self) -> DeviceStatus: ... save_result(doc) ✓ Data Layer Compliance
What each gate asks of your module
Gate 4No schema shadowing
Every module except plesty-lib is scanned for classes that shadow a plesty-lib schema model by name — config, op-schema, telemetry, result-document and scheduling models, plus the three system classes. Redefining one is rejected: import and use the plesty-lib model instead.
Gate d2Device status contract
Device modules only. An override of status() must stay annotated -> DeviceStatus and device_state() must stay -> str, so telemetry consumers can rely on the plesty-lib schema.
Gate e2Experiment persistence
Experiment modules only. Results must be persisted via plesty.lib.data.save_result. Direct writes — np.save/savez, pickle.dump, h5py.File(…, write), builtin open(…, write) — inside the package are rejected.

Experiment gate naming was normalised to lowercase (e1/e2) to match d1/d2.

Don't redefine these — import them

Gate 4 guards a fixed set of plesty-lib names — the models and systems every HUB module consumes rather than redefines:

DeviceStatus config model op-schema model telemetry model ResultDocument experiment scheduling + 3 system classes

The reference modules — plesty-pm100d, amc300, pl-image-scan and plesty-lib itself — all pass, including with module_type declared, so you can copy their layout as a known-green starting point.