diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md
index 5ea72070c..db0d72dd3 100644
--- a/CppCoreGuidelines.md
+++ b/CppCoreGuidelines.md
@@ -477,6 +477,7 @@ Philosophy rules summary:
* [P.11: Encapsulate messy constructs, rather than spreading through the code](#Rp-library)
* [P.12: Use supporting tools as appropriate](#Rp-tools)
* [P.13: Use support libraries as appropriate](#Rp-lib)
+* [P.14: Do not invoke undefined behavior](#Rp-ub)
Philosophical rules are generally not mechanically checkable.
However, individual rules reflecting these philosophical themes are.
@@ -1210,6 +1211,42 @@ By default use
If no well-designed, well-documented, and well-supported library exists for an important domain,
maybe you should design and implement it, and then use it.
+### P.14: Do not invoke undefined behavior
+
+##### Reason
+
+Invoking [undefined behavior](https://en.cppreference.com/w/cpp/language/ub) allows the
+compiler to do literally anything. In fact, when undefined behavior is invoked, the compiler
+can break a completely different part of the code, even one that didn't invoke undefined behavior
+itself! This is a major problem for us for three reasons: correctness, portability, and future-proofing.
+
+Since invoking undefined behavior breaks our side of the compiler/code contract, there
+is no way to fully ensure correctness in code that invokes undefined behavior. Unit tests
+are not a full solution here since undefined behavior could happen differently in a unit-test
+context compared to a real-world context. Additionally, undefined behavior is often
+non-deterministic at runtime, which could give us flaky tests or consistent false negatives.
+Even worse, undefined behavior can be compiled inconsistently, even on the same compiler
+and platform, making root cause identification of failing tests impossible.
+
+We want our code to be portable, and historically we've added new platforms consistently
+over time. Undefined behavior can be a portability problem since the undefined behavior
+will likely occur in a different way with a new platform or compiler. Unit tests again
+aren't a full answer here, since there's no guarantee that the unit tests will behave
+the same way as production code when undefined behavior is at play.
+
+We want to keep relatively up-to-date with our tooling. Having undefined behavior
+in our codebase can become a barrier to quickly upgrading our compilers or enabling new
+optimization passes, since when undefined behavior is at play, these changes have a strong
+likelihood of breaking our code in subtle ways.
+
+##### Enforcement
+
+We should run as much code as possible through llvm's "asan" and "ubsan" sanitizer modes, in
+CI. Together, these check for many instances of undefined behavior.
+
+Static analyzer tools can also detect some undefined behavior, and we should consider using them
+in our CI. Visual Studio's Analyze, Xcode's analyze, and clang-tidy all include some support
+for this.
# I: Interfaces