I don’t think it makes much sense to require segwit in the params if we’re not going to bother reporting it ourselves. I think the additional code would just be:
0    if (pindex->nHeight+1 >= consensusparams.CSVHeight) aRules.push_back("csv");
1    if (!fPreSegWit) aRules.push_back("segwit");
(also, could have said fPreSegWit = !IsWitnessEnabled(pindexPrev, consensusParams);)
Looks like including the ! got broken prior to activation in March 2017 in #9955 with segwit’s gbt_force value changing from false to true, so bitcoind hasn’t been compliant with bip145 since 0.15, though 0.14 should have been.
I think the logic here isn’t right and we should have two settings in VBDeploymentInfo, gbt_simplified which just adds the ! when false, and gbt_optional which, when the client doesn’t specify the rule, avoids setting the versionbit while signalling if gbt_optional is true, and errors out when the rule is activated and gbt_optional is false. segwit should initially have had gbt_simplified=false and gbt_optional=true, and just changed gbt_optional=false in #14811.
There’s no provision in bip9 or bip145 for ever removing forks from the rules list, which might be worth improving, as an alternative.
@luke-jr – thoughts? You added the gbt changes for bip9 and acked 9955 :)