@@ -768,37 +768,127 @@ def _op_UM(node: NodeProtocol, gf: GlyphFactors) -> None: # UM — Coupling
768768
769769
770770def _op_RA (node : NodeProtocol , gf : GlyphFactors ) -> None : # RA — Resonance
771- """Diffuse EPI to the node through the Resonance glyph .
771+ """Propagate coherence through resonance with νf amplification .
772772
773- Resonance propagates EPI along existing couplings without affecting νf,
774- ΔNFR, or phase. The glyph nudges the node towards the neighbour mean using
775- ``RA_epi_diff``.
773+ Resonance (RA) propagates EPI along existing couplings while amplifying
774+ the structural frequency (νf) to reflect network coherence propagation.
775+ According to TNFR theory, RA creates "resonant cascades" where coherence
776+ amplifies across the network, increasing collective νf and global C(t).
777+
778+ **Canonical Effects:**
779+
780+ - **EPI Propagation**: Diffuses EPI to neighbors (identity-preserving)
781+ - **νf Amplification**: Increases structural frequency when propagating coherence
782+ - **Network C(t)**: Contributes to global coherence increase
783+ - **Identity Preservation**: Maintains structural identity during propagation
776784
777785 Parameters
778786 ----------
779787 node : NodeProtocol
780788 Node harmonising with its neighbourhood.
781789 gf : GlyphFactors
782- Provides ``RA_epi_diff`` as the mixing coefficient.
790+ Provides ``RA_epi_diff`` (mixing coefficient, default 0.15) and
791+ ``RA_vf_amplification`` (νf boost factor, default 0.05).
792+
793+ Notes
794+ -----
795+ **νf Amplification**: When neighbors have coherence (|epi_bar| > 1e-9),
796+ node.vf is multiplied by (1.0 + RA_vf_amplification). This reflects
797+ the canonical TNFR property that resonance amplifies collective νf.
798+
799+ **Network Coherence Tracking**: If ``TRACK_NETWORK_COHERENCE`` is enabled,
800+ global C(t) is measured before/after RA application to quantify network-level
801+ coherence increase.
802+
803+ **Identity Preservation**: EPI structure (kind and sign) are preserved during
804+ propagation to ensure structural identity is maintained as required by theory.
783805
784806 Examples
785807 --------
786808 >>> class MockNode:
787809 ... def __init__(self, epi, neighbors):
788810 ... self.EPI = epi
789811 ... self.epi_kind = "seed"
812+ ... self.vf = 1.0
790813 ... self.graph = {}
791814 ... self._neighbors = neighbors
792815 ... def neighbors(self):
793816 ... return self._neighbors
794817 >>> neighbor = MockNode(1.0, [])
795818 >>> node = MockNode(0.2, [neighbor])
796- >>> _op_RA(node, {"RA_epi_diff": 0.25})
819+ >>> _op_RA(node, {"RA_epi_diff": 0.25, "RA_vf_amplification": 0.05 })
797820 >>> round(node.EPI, 2)
798821 0.4
822+ >>> node.vf # Amplified due to neighbor coherence
823+ 1.05
799824 """
825+ # Get configuration factors
800826 diff = get_factor (gf , "RA_epi_diff" , 0.15 )
801- _mix_epi_with_neighbors (node , diff , Glyph .RA )
827+ vf_boost = get_factor (gf , "RA_vf_amplification" , 0.05 )
828+
829+ # Track network C(t) before RA if enabled
830+ track_coherence = bool (node .graph .get ("TRACK_NETWORK_COHERENCE" , False ))
831+ c_before = None
832+ if track_coherence and hasattr (node , "G" ):
833+ try :
834+ from ..metrics .coherence import compute_network_coherence
835+ c_before = compute_network_coherence (node .G )
836+ if "_ra_c_tracking" not in node .graph :
837+ node .graph ["_ra_c_tracking" ] = []
838+ except ImportError :
839+ pass # Metrics module not available
840+
841+ # Capture state before for metrics
842+ vf_before = node .vf
843+ epi_before = node .EPI
844+ kind_before = node .epi_kind
845+
846+ # EPI diffusion (existing behavior)
847+ neigh , epi_bar = get_neighbor_epi (node )
848+ epi_bar_result , kind_result = _mix_epi_with_neighbors (node , diff , Glyph .RA )
849+
850+ # νf amplification through resonance (NEW)
851+ # Only amplify if neighbors have coherence to propagate
852+ if abs (epi_bar_result ) > 1e-9 and len (neigh ) > 0 :
853+ node .vf *= (1.0 + vf_boost )
854+
855+ # Track identity preservation
856+ identity_preserved = (
857+ (kind_result == kind_before or kind_result == Glyph .RA .value )
858+ and (epi_before * node .EPI >= 0 ) # Sign preserved
859+ )
860+
861+ # Collect propagation metrics if enabled
862+ collect_metrics = bool (node .graph .get ("COLLECT_RA_METRICS" , False ))
863+ if collect_metrics :
864+ metrics = {
865+ "operator" : "RA" ,
866+ "epi_propagated" : epi_bar_result ,
867+ "vf_amplification" : node .vf / vf_before if vf_before > 0 else 1.0 ,
868+ "neighbors_influenced" : len (neigh ),
869+ "identity_preserved" : identity_preserved ,
870+ "epi_before" : epi_before ,
871+ "epi_after" : float (node .EPI ),
872+ "vf_before" : vf_before ,
873+ "vf_after" : node .vf ,
874+ }
875+ if "ra_metrics" not in node .graph :
876+ node .graph ["ra_metrics" ] = []
877+ node .graph ["ra_metrics" ].append (metrics )
878+
879+ # Track network C(t) after RA if enabled
880+ if track_coherence and c_before is not None and hasattr (node , "G" ):
881+ try :
882+ from ..metrics .coherence import compute_network_coherence
883+ c_after = compute_network_coherence (node .G )
884+ node .graph ["_ra_c_tracking" ].append ({
885+ "node" : getattr (node , "n" , None ),
886+ "c_before" : c_before ,
887+ "c_after" : c_after ,
888+ "c_delta" : c_after - c_before ,
889+ })
890+ except ImportError :
891+ pass
802892
803893
804894def _op_SHA (node : NodeProtocol , gf : GlyphFactors ) -> None : # SHA — Silence
0 commit comments