z2m 1.42's default config is `frontend: true` (boolean shorthand). A
nested env override like ZIGBEE2MQTT_CONFIG_FRONTEND_PORT/_ENABLED makes
z2m try to write a property onto that boolean and die at startup with
"Cannot create property 'port' on boolean 'true'", crash-looping the
container. The default frontend already listens on 8080, which we publish
as host 8084, so no override is needed — remove both lines. Also correct
the comment: zigbee-herdsman opens the serial adapter before connecting to
MQTT, so a stickless box never reaches the broker.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
First catalog apps to exercise core 26.17's app-to-app dependency
feature — until now every app was standalone.
- mosquitto: MQTT broker, first dependency *provider*. Mandatory auth;
per-consumer accounts created by on_install/on_start hooks
(scripts/provision-client.sh, scripts/ensure-client.sh) that run inside
the broker container via `docker compose exec`. Provider-side password
stash so on_start can restore an account after a volume wipe.
- zigbee2mqtt: first dependency *consumer*. `requires` mosquitto; MQTT
creds wired in from the provisioning hook via ZIGBEE2MQTT_CONFIG_* env.
Serial coordinator path as a text setting + devices mapping.
Supporting changes:
- Bump vendored furtka_manifest.py (26.10-era -> 26.17) so the validator
actually validates the `requires` schema instead of ignoring it.
- Document `requires`/hooks in apps/README.md (was undocumented), including
the three framework gaps building this pair surfaced.
- CI now shellchecks app hook scripts (apps/*/scripts/*.sh), not just
repo-root scripts/.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>