That's sort of a different problem. I often think of comments as "why" and code as "how" (or "what" if you're declarative). If how breaks, then the code breaks, so you have immediate feedback. But if why breaks - like if your reasons for writing it that way no longer apply - then it's impossible to recognize immediately. If there were instead a way to codify the assumptions behind why, such that the why statements would break when the assumptions become false, that would be interesting.
But at any rate, why is relevant, and code doesn't express the why.
My approach to this is that the comment can almost always be turned into a text. A test class called FooPCIDSSCompatibility with tests for all the bits both defines things more strongly and will start failing if you ever break it (either accidentally or because it is no longer required). Either way you need to update either code or test to get through the build process.
Comments can be useful for annotating algorithms or referencing stack overflow though.
That comment I'd interpret as the requirements must be considered in this region; so if the law changes, the requirements still apply, it's just that the code needs to be updated.
"PCI-DSS requirements apply" isn't adequate in a literate program for the same reason that "must work correctly" isn't adequate. Explaining the relevant requirements in detail is a crucial goal.
1. Specs&design docs and code should be in separate files, because I believe the separation of concerns should be applied there. That's indeed the opposite of literate programming.
2. There should be two-way links between documentation and code: in the code, one should have links to the spec; and from the spec, one should have links to the code.
3. If the specs or the code changes, those links should be displayed in a different way to warn the reader that things are potentially not in sync. How to do that: check if the links point to the latest version. The maintainers have to update the links to remove the warnings.
Specification and design/implementation are not separate concerns. They are dual.
A sufficiently detailed specification is an implementation. Prolog does this (and Eve has a very similar feel).
As engineers, we traditionally work declaratively at the top of the "V" and imperatively at the bottom of the "V" -- but the reasons for this are largely historical/cultural.
We could (in theory) carry out the analysis/refinement process using entirely declarative notation.
The problem domain has primacy. Analysis separates problem-domain concerns and the duality takes care of the translation between problem and solution domains.
(OK -- so this is basically just a reiteration of the thesis of good old-fashioned AI -- that with a sufficiently powerful theorem prover and a sufficiently large and detailed knowledge base -- solutions will just pop out of a largely mechanical analysis process -- and I'm pretty sure this isn't at all trendy right now ... so I should relegate this to the "thinking out loud" bucket ...)
In his case, his algo said X, and his code did Y.. very easy to see the mistake.
In your case, lets add a comment
// Note: PCI-DSS requirements apply below
Now 3 years later, the law changes and the requirements do not apply. So you are at the same situation. Code does X, comments say Y. Which is right?
Not a very easy to keep comments and code in sync