11"""Canonical grammar validator - Pure physics from nodal equation.
22
33This module implements grammar validation that emerges EXCLUSIVELY from
4- the nodal equation ∂EPI/∂t = νf · ΔNFR(t), without organizational conventions .
4+ the nodal equation ∂EPI/∂t = νf · ΔNFR(t), TNFR invariants, and formal contracts .
55
66Canonical Rules (Inevitable from Physics)
77------------------------------------------
1111RC2: Convergence - If sequence has destabilizers, must include stabilizer
1212 Reason: ∫νf·ΔNFR dt must converge (convergence theorem)
1313
14+ RC3: Phase Verification - Coupling/resonance requires phase compatibility
15+ Reason: AGENTS.md Invariant #5 + resonance physics (φᵢ ≈ φⱼ)
16+
17+ RC4: Bifurcation Limits - If ∂²EPI/∂t² > τ, bifurcation handler required
18+ Reason: AGENTS.md Contract OZ + bifurcation theory (conditional)
19+
1420Non-Canonical Rules (Organizational Conventions)
1521-------------------------------------------------
1622RNC1: Termination - Sequence must end with specific terminators
2127
2228References
2329----------
24- See CANONICAL_GRAMMAR_DERIVATION.md for complete mathematical derivation.
30+ See CANONICAL_GRAMMAR_DERIVATION.md and EMERGENT_GRAMMAR_ANALYSIS.md
31+ for complete mathematical derivations.
2532"""
2633
2734from __future__ import annotations
4956 # Note: Some operators have destabilizing components
5057})
5158
59+ # RC3: Operators that require phase verification (coupling/resonance)
60+ COUPLING_RESONANCE = frozenset ({'coupling' , 'resonance' })
61+
62+ # RC4: Bifurcation triggers and handlers
63+ BIFURCATION_TRIGGERS = frozenset ({'dissonance' , 'mutation' })
64+ BIFURCATION_HANDLERS = frozenset ({'self_organization' , 'coherence' })
65+
5266# Conventional terminators (NOT canonical - organizational only)
5367CONVENTIONAL_TERMINATORS = frozenset ({
5468 'silence' ,
6175class CanonicalGrammarValidator :
6276 """Validates sequences using ONLY physics-derived rules.
6377
64- This validator implements RC1 and RC2 , which emerge inevitably from
65- the nodal equation ∂EPI/∂t = νf · ΔNFR(t). It does NOT enforce
66- organizational conventions like required terminators.
78+ This validator implements RC1, RC2, and RC3 , which emerge inevitably from
79+ the nodal equation ∂EPI/∂t = νf · ΔNFR(t), TNFR invariants, and formal
80+ contracts. It does NOT enforce organizational conventions like required terminators.
6781
6882 Use this for testing algebraic properties where you want to validate
6983 pure physics without implementation conventions.
@@ -158,16 +172,71 @@ def validate_convergence(sequence: List[Operator]) -> tuple[bool, str]:
158172 f"bound destabilizers { destabilizers_present } "
159173 )
160174
175+ @staticmethod
176+ def validate_phase_compatibility (sequence : List [Operator ]) -> tuple [bool , str ]:
177+ """Validate RC3: Phase compatibility requirement for coupling/resonance.
178+
179+ Physical basis: AGENTS.md Invariant #5 states "no coupling is valid
180+ without explicit phase verification (synchrony)". Resonance physics
181+ requires phase compatibility: |φᵢ - φⱼ| ≤ Δφ_max for structural coupling.
182+
183+ Without phase verification, nodes with incompatible phases (e.g., antiphase)
184+ could attempt coupling, violating resonance physics.
185+
186+ Parameters
187+ ----------
188+ sequence : List[Operator]
189+ Sequence of operators to validate
190+
191+ Returns
192+ -------
193+ tuple[bool, str]
194+ (is_valid, message)
195+
196+ Notes
197+ -----
198+ RC3 is a META-rule: it requires that when UM (Coupling) or RA (Resonance)
199+ operators are used, the implementation MUST verify phase compatibility.
200+ The actual phase check happens in operator preconditions, not in grammar.
201+
202+ This grammar rule serves to document the requirement and ensure awareness
203+ that phase checks are MANDATORY (Invariant #5), not optional.
204+ """
205+ # Check if sequence contains coupling/resonance operators
206+ coupling_ops = [
207+ getattr (op , 'canonical_name' , op .name .lower ())
208+ for op in sequence
209+ if getattr (op , 'canonical_name' , op .name .lower ()) in COUPLING_RESONANCE
210+ ]
211+
212+ if not coupling_ops :
213+ # No coupling/resonance = RC3 not applicable
214+ return True , "RC3 not applicable: no coupling/resonance operators"
215+
216+ # RC3 satisfied: Sequence contains coupling/resonance
217+ # Phase verification is MANDATORY per Invariant #5
218+ # Actual check happens in operator preconditions (validate_coupling, validate_resonance)
219+ return (
220+ True ,
221+ f"RC3 awareness: operators { coupling_ops } require phase verification "
222+ f"(MANDATORY per Invariant #5). Enforced in preconditions."
223+ )
224+
161225 @classmethod
162226 def validate (
163227 cls ,
164228 sequence : List [Operator ],
165229 epi_initial : float = 0.0 ,
166230 ) -> tuple [bool , List [str ]]:
167- """Validate sequence using ONLY canonical rules (RC1, RC2).
231+ """Validate sequence using ONLY canonical rules (RC1, RC2, RC3 ).
168232
169233 This validates pure physics without organizational conventions.
170234
235+ Canonical rules validated:
236+ - RC1: Initialization (if EPI=0, use generator)
237+ - RC2: Convergence (if destabilizers, use stabilizer)
238+ - RC3: Phase compatibility (coupling/resonance require phase check)
239+
171240 Parameters
172241 ----------
173242 sequence : List[Operator]
@@ -195,6 +264,11 @@ def validate(
195264 messages .append (f"RC2: { msg_conv } " )
196265 all_valid = all_valid and valid_conv
197266
267+ # RC3: Phase compatibility
268+ valid_phase , msg_phase = cls .validate_phase_compatibility (sequence )
269+ messages .append (f"RC3: { msg_phase } " )
270+ all_valid = all_valid and valid_phase
271+
198272 return all_valid , messages
199273
200274
@@ -207,10 +281,11 @@ def validate_canonical_only(
207281 This function validates ONLY:
208282 - RC1: Initialization (if EPI=0, use generator)
209283 - RC2: Convergence (if destabilizers, use stabilizer)
284+ - RC3: Phase compatibility (coupling/resonance require phase check)
210285
211286 It does NOT validate:
212- - Terminator requirements (organizational convention)
213- - Specific composition restrictions (high-level semantics)
287+ - RNC1: Terminator requirements (organizational convention)
288+ - RNC2: Specific composition restrictions (high-level semantics)
214289
215290 Use this when testing algebraic properties where you want pure physics
216291 validation without implementation conventions.
@@ -236,8 +311,12 @@ def validate_canonical_only(
236311
237312 Notes
238313 -----
239- This validator is 100% physics-based. All rules emerge inevitably from
240- the nodal equation ∂EPI/∂t = νf · ΔNFR(t).
314+ This validator is 100% physics-based. All rules emerge inevitably from:
315+ - Nodal equation: ∂EPI/∂t = νf · ΔNFR(t)
316+ - TNFR invariants (especially Invariant #5: phase verification)
317+ - Formal operator contracts (AGENTS.md §4)
318+
319+ See EMERGENT_GRAMMAR_ANALYSIS.md for complete derivations.
241320 """
242321 is_valid , messages = CanonicalGrammarValidator .validate (sequence , epi_initial )
243322 return is_valid
@@ -250,7 +329,7 @@ def validate_with_conventions(
250329 """Validate sequence with both canonical rules and conventions.
251330
252331 This validates:
253- - RC1, RC2: Canonical physics rules
332+ - RC1, RC2, RC3 : Canonical physics rules
254333 - RNC1: Terminator convention (organizational, NOT physics)
255334
256335 Parameters
@@ -268,14 +347,14 @@ def validate_with_conventions(
268347 messages = []
269348 all_valid = True
270349
271- # First validate canonical rules
350+ # First validate canonical rules (RC1, RC2, RC3)
272351 valid_canonical , canonical_msgs = CanonicalGrammarValidator .validate (
273352 sequence , epi_initial
274353 )
275354 messages .extend (canonical_msgs )
276355 all_valid = all_valid and valid_canonical
277356
278- # Then check conventions
357+ # Then check conventions (RNC1)
279358 if sequence :
280359 last_op = getattr (sequence [- 1 ], 'canonical_name' , sequence [- 1 ].name .lower ())
281360 if last_op not in CONVENTIONAL_TERMINATORS :
0 commit comments