Symptom

Server.Pin nodes could not observe another node the way Executors and LogicGates do, even though PinMetaData already implemented SourceMetaData. An OUT pin’s level came only from its own meta.state, editable by hand — there was no way to wire a digital input so the pin’s output followed it. The inputs -> invocation wake-wiring deferred for LogicGate (commit 6173e5d70) meant no node type actually woke from an input change.

Root cause

Server.Pin nodes were driven entirely by legacy CRUD: ServerPinProcessor.post() registered/reconfigured/unregistered the pin with krill-pi4j on create/edit/delete (dispatched from the central CrudLifecycleTask), and an OUT pin’s level came from its own meta.state. The pin never joined the observer (onInvoke) path, so setting inputs alone left it inert: it had the data reference but no wake (sources + SOURCE_INVOKED) to trigger re-evaluation, and no execute path to read the input and drive the hardware.

Fix

Extracted DigitalInputReader (server/.../krillapp/digital/) — the shared “read one node’s digital boolean” used by both LogicGateCompute and the pin. ServerPinProcessor.process() now, for an OUT pin with a wired input, reads the input via DigitalInputReader and drives PiManager.setHigh/setLow (non-digital input → NodeState.ERROR; no input → idle), riding the existing onInvoke(EXECUTE) observer path so user edits no longer drive the output. The pi4j register/reconfigure/unregister moved into a dedicated ServerPinLifecycleTask (state-gated on DELETING/CREATE_OR_OVERWRITE/USER_EDIT, preserving the USER_EDIT setStateToNone settle), and the Pin arm (and pinProcessor dep) was removed from CrudLifecycleTask. EditPin shows a single digital-input selector when mode == OUT; picking an input sets inputs AND sources + SOURCE_INVOKED (PinInputsLogic.withInput), which is what makes NodeObservationRegistry wake the pin; the wired-node render guards a deleted input with readNodeStateOrNull. The digital-input picker dialog was extracted into a shared composable with an exclude param (prevents a pin selecting itself).

Prevention