@@ -994,7 +994,8 @@ def validate_mutation(G: "TNFRGraph", node: "NodeId") -> None:
994994
995995 1. Minimum νf for phase transformation capacity
996996 2. **∂EPI/∂t > ξ: Structural change velocity exceeds threshold**
997- 3. Stable base (IL precedence validated by grammar U4b)
997+ 3. **U4b Part 1: Prior IL (Coherence) for stable transformation base**
998+ 4. **U4b Part 2: Recent destabilizer (~3 ops) for threshold energy**
998999
9991000 Also detects and records the destabilizer type that enabled this mutation
10001001 for telemetry and structural tracing purposes.
@@ -1009,7 +1010,20 @@ def validate_mutation(G: "TNFRGraph", node: "NodeId") -> None:
10091010 Raises
10101011 ------
10111012 OperatorPreconditionError
1012- If node state is unsuitable for mutation
1013+ If node state is unsuitable for mutation or U4b requirements not met
1014+
1015+ Configuration Parameters
1016+ ------------------------
1017+ ZHIR_MIN_VF : float, default 0.05
1018+ Minimum structural frequency for phase transformation
1019+ ZHIR_THRESHOLD_XI : float, default 0.1
1020+ Threshold for ∂EPI/∂t velocity check
1021+ VALIDATE_OPERATOR_PRECONDITIONS : bool, default False
1022+ Enable strict U4b validation (IL precedence + destabilizer requirement)
1023+ ZHIR_REQUIRE_IL_PRECEDENCE : bool, default False
1024+ Require prior IL even if VALIDATE_OPERATOR_PRECONDITIONS=False
1025+ ZHIR_REQUIRE_DESTABILIZER : bool, default False
1026+ Require recent destabilizer even if VALIDATE_OPERATOR_PRECONDITIONS=False
10131027
10141028 Notes
10151029 -----
@@ -1023,6 +1037,14 @@ def validate_mutation(G: "TNFRGraph", node: "NodeId") -> None:
10231037 - If ∂EPI/∂t ≥ ξ: Logs success, sets validation flag
10241038 - If insufficient history: Logs warning, cannot verify
10251039
1040+ **U4b Validation (Grammar Rule)**:
1041+
1042+ When strict validation enabled (VALIDATE_OPERATOR_PRECONDITIONS=True):
1043+ - **Part 1**: Prior IL (Coherence) required for stable base
1044+ - **Part 2**: Recent destabilizer (OZ/VAL/etc) required within ~3 ops
1045+
1046+ Without strict validation: Only telemetry/warnings logged.
1047+
10261048 This function implements R4 Extended telemetry by analyzing the glyph_history
10271049 to determine which destabilizer (strong/moderate/weak) enabled the mutation.
10281050 The destabilizer context is stored in node metadata for structural tracing.
@@ -1075,9 +1097,53 @@ def validate_mutation(G: "TNFRGraph", node: "NodeId") -> None:
10751097 )
10761098 G .nodes [node ]["_zhir_threshold_unknown" ] = True
10771099
1100+ # U4b Part 1: IL Precedence Check (stable base for transformation)
1101+ # Check if strict validation enabled
1102+ strict_validation = bool (G .graph .get ("VALIDATE_OPERATOR_PRECONDITIONS" , False ))
1103+ require_il = strict_validation or bool (G .graph .get ("ZHIR_REQUIRE_IL_PRECEDENCE" , False ))
1104+
1105+ if require_il :
1106+ # Get glyph history
1107+ glyph_history = G .nodes [node ].get ("glyph_history" , [])
1108+
1109+ # Import glyph_function_name to convert glyphs to operator names
1110+ from ..grammar import glyph_function_name
1111+
1112+ # Convert history to operator names
1113+ history_names = [glyph_function_name (g ) for g in glyph_history ]
1114+
1115+ # Check for prior IL (coherence)
1116+ il_found = "coherence" in history_names
1117+
1118+ if not il_found :
1119+ raise OperatorPreconditionError (
1120+ "Mutation" ,
1121+ "U4b violation: ZHIR requires prior IL (Coherence) for stable transformation base. "
1122+ "Apply Coherence before mutation sequence. "
1123+ f"Recent history: { history_names [- 5 :] if len (history_names ) > 5 else history_names } "
1124+ )
1125+
1126+ logger .debug (f"Node { node } : ZHIR IL precedence satisfied (prior Coherence found)" )
1127+
1128+ # U4b Part 2: Recent Destabilizer Check (threshold energy for bifurcation)
10781129 # R4 Extended: Detect and record destabilizer type for telemetry
1079- # This provides structural traceability for bifurcation events
10801130 _record_destabilizer_context (G , node , logger )
1131+
1132+ # If strict validation enabled, enforce destabilizer requirement
1133+ require_destabilizer = strict_validation or bool (G .graph .get ("ZHIR_REQUIRE_DESTABILIZER" , False ))
1134+
1135+ if require_destabilizer :
1136+ context = G .nodes [node ].get ("_mutation_context" , {})
1137+ destabilizer_found = context .get ("destabilizer_operator" )
1138+
1139+ if destabilizer_found is None :
1140+ recent_history = context .get ("recent_history" , [])
1141+ raise OperatorPreconditionError (
1142+ "Mutation" ,
1143+ "U4b violation: ZHIR requires recent destabilizer (OZ/VAL/etc) within ~3 ops. "
1144+ f"Recent history: { recent_history } . "
1145+ "Apply Dissonance or Expansion to elevate ΔNFR first."
1146+ )
10811147
10821148
10831149def validate_transition (G : "TNFRGraph" , node : "NodeId" ) -> None :
0 commit comments