Custom notifications are relayed by lightningd with the sender's
payload verbatim as params (origin rides as a sibling field, outside
params). The topic-key nesting the monitor descended through --
params["xrebalance_part"] -- is a built-in-topic convention
(forward_event et al) that custom topics do not get, so every part
notification missed the has() guards and was silently dropped: the
first live delivery (req d7371cfd, 224_294 sat at 1_009 ppm) went
unattributed. Read params as the payload; the unit test now feeds
the true delivery shape (verified against lightningd's
plugin_notification_handle, which json_add_tok's the sender's params
straight through).
A third clboss-rebalance-mode value, xrebalance2, runs the same
XRebalancer planner but executes cycles through the external
xrebalance plugin's RPC instead of the in-clboss clboss-xmovefunds
executor. The plugin does the layer splitting on stock askrene and
owns constraint knowledge and failure feedback, so the in-clboss
layer machinery (including the predictor) stays idle in this mode.
The new XRebalancePartMonitor subscribes to the plugin's
xrebalance_part notifications and raises Msg::XRebalanceAttribution
for each completed part, so EarningsTracker accounts plugin-moved
funds regardless of which client initiated the transfer.
Attribution is notification-only: a part that reaches terminal
state while clboss is down goes unaccounted.
Subscribing to the topic is safe without the plugin loaded
(lightningd only warns about unknown notification topics), and a
cycle fired with the plugin missing logs one line and retries next
cycle.