I've found the problem. The 'production' environment wasn't actually 'production', it was a custom 'uat' environment. The uat configuration file had been created by copying config/environment/development.rb so that all noisy error messages were still generated in uat, so as to make bug fixing easier. However, the asset pipeline configuration had been left as used in development. The application was being deployed via a standard capistrano deployment script which was compiling the assets.
This meant that all the assets (including the JavaScript files) where being loaded both individually, and via the precompiled asset pipeline. That is, all the JavaScript code was duplicated.
I've modified the config/environment/uat.rb and the confirmation dialogue duplication has gone away:
# Code is not reloaded between requests
config.cache_classes = true
# Log error messages when you accidentally call methods on nil.
config.whiny_nils = true
# Show full error reports and enable caching
config.consider_all_requests_local = true
config.action_controller.perform_caching = true
# Disable Rails's static asset server (Apache or nginx will already do this)
config.serve_static_assets = false
# Compress JavaScripts and CSS
config.assets.compress = true
# Don't fallback to assets pipeline if a precompiled asset is missed
config.assets.compile = false
# Generate digests for assets URLs
config.assets.digest = true