One minor issue, you should probably use ("x" `isPrefixOf`) instead of
(\i -> head i == 'x'), since the second crashes on any blank lines.
If you call exitFailure do you avoid the verbosity of the error
message? If not, Shake should probably avoid capturing that error
message, to allow people to exit from within Shake.
As to whether it is idiomatic - it looks reasonable to me. Tracking
the values directly from the *.node files would be a bit more
principled, and hopefully will be a bit easier in the next release of
Shake - but it's still probably not actually necessary.
Thanks, Neil