The SpoolBuddy "weigh-then-assign" workflow tried to configure an empty AMS
slot at assign time, but Bambu firmware silently drops ams_filament_setting
and extrusion_cali_sel for unloaded slots — the MQTT calls completed and the
modal closed, yet BambuStudio kept showing the slot as default-PLA forever.
assign_spool now detects an empty target slot (fingerprint_type empty) and
persists the SpoolAssignment without publishing MQTT, returning a new
pending_config flag so the frontend can swap "Assigned!" for "Slot will
configure when you insert the spool." on_ams_change watches for the slot
to load (state == 11, which fires for 3rd-party tags too even when
tray_type stays empty) and replays the deferred ams_filament_setting +
extrusion_cali_sel — including the printer-kp realignment that converts
PFUS-prefix cloud user presets to the P-prefix local-preset filament_id
the slicer actually accepts.
The full assign-time MQTT block was extracted into
apply_spool_to_slot_via_mqtt so both the assign endpoint and the
on_ams_change replay path use the same resolution logic; the helper takes
~270 lines of duplication out of assign_spool.