The reason systemd-timesyncd is forcibly installed on upgrade is that it is in the minimal task:
$ apt-cache show systemd-timesyncd | grep Task Task: minimal, ubuntu-desktop-minimal-default-languages, ubuntu-desktop-minimal-default-languages, ubuntu-desktop-minimal-default-languages, ubuntu-desktop-minimal-default-languages, ubuntu-desktop-minimal-default-languages, ubuntu-desktop-minimal-default-languages, ubuntu-desktop-minimal-default-languages, ubuntu-desktop-default-languages, ubuntu-desktop-default-languages, ubuntu-desktop-default-languages, ubuntu-desktop-default-languages, ubuntu-desktop-default-languages, ubuntu-desktop-default-languages, ubuntu-desktop-default-languages, ubuntu-desktop-default-languages, ubuntu-core
The reason systemd-timesyncd is forcibly installed on upgrade is that it is in the minimal task:
$ apt-cache show systemd-timesyncd | grep Task desktop- minimal- default- languages, ubuntu- desktop- minimal- default- languages, ubuntu- desktop- minimal- default- languages, ubuntu- desktop- minimal- default- languages, ubuntu- desktop- minimal- default- languages, ubuntu- desktop- minimal- default- languages, ubuntu- desktop- minimal- default- languages, ubuntu- desktop- default- languages, ubuntu- desktop- default- languages, ubuntu- desktop- default- languages, ubuntu- desktop- default- languages, ubuntu- desktop- default- languages, ubuntu- desktop- default- languages, ubuntu- desktop- default- languages, ubuntu- desktop- default- languages, ubuntu-core
Task: minimal, ubuntu-