There are a couple of things going on here, and two possible causes, which might even be layered.
trey wrote:and it's set to publish straight to my website storage, which is mounted locally with Mountain Duck
So just keep in mind, when you "publish" anything to X3 outside of the X3 control panel, X3 may still use OLD cache data, because it doesn't know that you have made any changes. Therefore, after updating images outside of X3, you would still need to go to the X3 control panel and click "save", just to make sure the page cache is invalidated and updated on next page load.
So basically, the above might resolve your issue. You need to invalidate cache, because just updating images into the disk won't clear X3's cache.
---
However, there is another potential issue at play here, which may or may not be related. When you upload images with IPTC captions into X3, and then when you click "save" in the page, the captions will get get copied into X3's own page.json in the folder. This is because users may edit captions from the X3 interface, and we can't assume we can move this data back into the JPG IPTC on save. Therefore, for one and the same imagename.jpg, you might have caption stored from the original image, which then does not get automatically updated from a new image's IPTC data that you have copied over outside of the X3 control panel. Therefore, deleting the file first from the X3 panel, is the only way to flush old data first. You would somehow need to clear references to the images from the folders page.json before uploading and replacing with new images.
The above would only happen if you first SAVE the page while images exist, and then you update those images later.
For starters, you could go to
Settings > Advanced > DISABLE "Store image settings in image as IPTC". At least old data from page.json would not get written back into your images on page save.