In our case, and I believe this would be the case with most devices, once the device has backed off, it will set the ADRACKReq bit in subsequent uplink packets (as per Semtech’s ADR backoff flow guidelines).
Chirpstack does response in this situation with the enabled channels, but not the full channel mask. I agree that it’s silly to send it periodically if it’s not needed.
I would suggest that Chirpstack should respond with the full channel mask (setting chMaskCntl=7 first, and then the enabled channels) any time the device sends an uplink with ADRACKReq set. This should not cause unnecessary overhead as it’s basically already the behaviour of Chirpstack. We are just adding the additional command for chMaskCntl=7 to downlink. It should be up to the device to know when to set ADRACKReq (e.g. when it needs this information and not with every uplink). In this case the NS doesn’t need to send anything periodically, it would just act as it already does unless the device is specifically requesting ADR Ack.
I have a Chirpstack frame log of device uplinks and gateway responses when we simulated this scenario. I’m happy to share if it’s helpful.