Three layers were each blind to nested composition in different ways:
- FlatteningPipeline only loaded compositions for templates in the parent's
inheritance chain, so depth-2 composed attributes (e.g.
Pump.AlarmSensor.SensorReading) never materialized. Walk composed chains
breadth-first so the flattener's nested step has the data it needs.
- InstanceConfigure's alarm trigger picker was fed only direct, non-locked
attributes, hiding inherited and composed-member paths. Feed it the full
flattened attribute list via FlatteningPipeline.
- ValidationService.ExtractAttributeNameFromTriggerConfig only recognized
"attributeName", silently passing alarms still using the legacy
"attribute" key. Accept both keys, matching FlatteningService,
AlarmActor, and AlarmTriggerConfigCodec.