Note that the cd command has no effect with a bang but works standalone or with %.
Possible this is by design, but it is a confusing behavior when other commands work as expected.
It is a side effect of how the exclamation works. It runs a separate shell instance that ends with the run of that command. So you only change within that line. Documented here:
“Note that !cd doesn’t work for this purpose because the shell where !command runs is immediately discarded after executing ‘command’.”
Because it is discarded there’s no persistence with ! unless you pass the output back to the kernel. That isn’t possible with !cd.
You want to use %cd as you found. The one with cd alone works because of automagics, that is enabled by default. See about automagics here.
There’s also the %%bash cell magic that can allow you to use multiple commands on multiple lines in one cell and not string them together all on one line using ;. Changes of the working directory will be maintained within the cell if using that.
