That's not what I see.  The only call to after-change-functions that
insert-file-contents does is not done in your recipe: if I set a
breakpoint there, it is never hit.

So I have no doubt that what you see is an unrelated call to
after-change-functions.  The evidence that current-buffer returns the
buffer name you expect is not enough: the actual current buffer can be
different, and I saw it in GDB.

So, given what I see under a debugger, there's no bug here.

Why did you think insert-file-contents should at all call
after-change-functions in this scenario?

I was never able to set up GDB as I'm on a Mac, so I actually am not sure if the signal_after_change call is made directly inside insert-file-contents. Looking at it again, it can't possibly be called there as that line is under the notfound label, which is only jumped to when the file descriptor is invalid.

It is possible that some other Emacs internal machinery set the current buffer-file-name to nil temporarily and invoke signal_after_change after insert-file-contents has replaced the buffer content, but I have not been able to identify where. What is sure is a lone call to insert-file-contents runs the after-change-functions.