В конце концов, похоже, я действительно поступил неправильно. Попытка подавить обнаружение изменений VS неверна, и я должен заставить MSBuild перестроиться при изменении анализатора.
Таким образом, в основном, сделайте так, чтобы поведение обнаружения изменений в MSBuild совпадало с VS, а не наоборот.
Я достиг этого, добавив сборки анализатора как скрытые, фиктивные элементы содержимого в каждый проект, поэтому моя общая ItemGroup теперь выглядит так:
<ItemGroup>
<Analyzer Include="@(AnalyzerAssemblies)" />
<Content Include="@(AnalyzerAssemblies)">
<Private>False</Private>
<Visible>False</Visible>
</Content>
</ItemGroup>
Это, похоже, дает желаемый результат, заставляя MSBuild учитывать временную метку анализатора при его вызове VS, что заставляет все решение перестроиться один раз, а затем останавливается.