Files
firmware/assets
Oleksandr ShyshatskyiandClaude Opus 5 68afe65485 Fix two features that silently did nothing, and give Moonraker a user seam
Both bugs were found by auditing a40bc86, which the first pass never saw.

1. The plain Creator 5 could not print at all. ff-filament.cfg subscripted
   printer["heater_generic chamber_heater"] unguarded, and that object exists
   only on the Pro. Klipper renders a macro's whole template before executing
   any of it, so _FF_FILAMENT_PREP/_FF_FILAMENT_FINISH raised on a non-Pro --
   taking LOAD_FILAMENT, UNLOAD_FILAMENT, PURGE, _FF_NOZZLE_CLEAN and
   therefore START_PRINT and every Moonraker print with them. Guarded with the
   `in printer` idiom ff-chamber.cfg already used.

   test_chamber.py gains a static gate over every ff-*.cfg macro. Proven to
   catch it: reverted the guards and the test fails naming both macros.

2. The shipped moonraker.conf could never install. /usr/data/config/
   moonraker.conf is ON the factory image -- verified by probing the replica --
   so the compare-and-.mod-new rule saw an existing file with no snapshot to
   compare it against and parked ours as .mod-new, on the first install and on
   every one after. The [webcam] entry therefore never reached the printer and
   Mainsail still showed no camera, which is the entire reason a40bc86 exists.
   The API lockdown never applied either.

   /usr/prog/klipper/runConfig/moonraker.conf is FlashForge's pristine
   template and is byte-identical to the live copy on an untouched machine
   (both 371 bytes, md5 a49bd5ea...), so that is now the test for "nobody has
   edited this": matching it means the file is ours to write.

   case-install.sh asserts the LIVE file has a [webcam] block, not that a
   .mod-new appeared. It reproduced the bug before the fix.

3. moonraker.conf is mod-owned and overwritten every update, so it needed the
   seam printer.cfg gives the Klipper configs. New moonraker-custom.conf:
   created once, never written again, and included at the END of
   moonraker.conf -- Moonraker applies options in read order, so the user's
   win. Moonraker treats an include matching no file as fatal, so the file is
   guaranteed to exist and both it and its header say not to delete it.

   case-install.sh writes a trusted_clients block into it before boot 2 and
   asserts it is byte-identical afterwards, so "survives an update" is tested
   rather than asserted.

Verified on the printer replica through all three boots: the config lands, the
seam is created and included, a user edit survives the re-install, and
Moonraker still starts -- which is what proves the include parses.

53 passed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-24 19:48:44 +03:00
..