TNFR Logo
TheoryLearnSoftwareResearch

On this page

TNFR

Resonant Fractal Nature Theory — a mathematical framework for coherent patterns on graph-coupled networks.

About
  • Project history
  • Editorial policy
  • Contact
Resources
  • GitHub
  • PyPI
  • DOI · Zenodo
Legal
  • MIT License
  • Citation
© 2026 TNFR project — MIT licensed.DOI 10.5281/zenodo.17602860
docs
grammar
PHYSICS_VERIFICATION.md
API_CONTRACTS.mdCANONICAL_OZ_SEQUENCES.mdEMPIRICAL_CONFRONTATION_EEG.mdREADME.mdSTRUCTURAL_FIELDS_TETRAD.mdSTRUCTURAL_INTERFACE_THEORY.md
theory
APPLIED_STRUCTURAL_ANALYSIS.mdCATALOG_TYPE_HYGIENE_PROGRAMME.mdDISSIPATIVE_AND_OPEN_SYSTEMS.mdEMERGENT_ONTOLOGY.mdEXTENDED_FIELDS_AND_DERIVED_QUANTITIES.mdFUNDAMENTAL_THEORY.mdGAUGE_SYMMETRY_AND_UNIFICATION.mdGLOSSARY.mdMATHEMATICAL_DYNAMICS_BASIS.mdMINIMAL_STRUCTURAL_DEGREES.mdNUCLEUS_A_PRIME_LADDER_ATLAS.mdNUCLEUS_B_EQUIVARIANCE_OBSTRUCTIONS.mdPHYSICAL_REGIME_CORRESPONDENCES.mdREADME.mdREMESH_INFINITY_DERIVATION.mdSTRUCTURAL_CONSERVATION_THEOREM.mdSTRUCTURAL_OPERATORS.mdSTRUCTURAL_STABILITY_AND_DYNAMICS.mdTNFR_BSD_RESEARCH_NOTES.mdTNFR_HODGE_RESEARCH_NOTES.mdTNFR_NAVIER_STOKES_RESEARCH_NOTES.mdTNFR_NUMBER_THEORY.mdTNFR_P_VS_NP_RESEARCH_NOTES.mdTNFR_RIEMANN_RESEARCH_NOTES.mdTNFR_VARIATIONAL_PRINCIPLE.mdTNFR_YANG_MILLS_RESEARCH_NOTES.mdTNFR.pdfUNIFIED_GRAMMAR_RULES.md
factorization-lab
analysis
analyze_patterns.pycertificate_manifest.py
benchmarks
benchmark_analysis.pybenchmark_expansion_suite.pyfull_spectrum_factorization.pypaley_gap_extended.pypaley_gap_smoke.pytest_benchmark_suite.py
demos
experiment_contexts
exp_0b1663cd19b7.jsonexp_0bf0054b7474.jsonexp_75a4c8ca616a.jsonexp_848ee0fd1857.jsonexp_f6fe00562193.jsonexp_fdf3da424e1e.json
failure_telemetry_batch.pyfeedback_integration_demo.pyintegration_demo_snapshots.dbseed_management_integration_demo.pysnapshot_integration_demo.pytrajectory_143.jsontrajectory_77.jsontrajectory_89.jsontrajectory_91.jsontrajectory_97.json
docs
FACTORING_PLAYBOOK.mdFALSE_POSITIVE_TEST_SUITE.mdOPERATOR_CERTIFICATES.mdROADMAP.mdSPECTRAL_ROUTE.md
experiment_contexts
exp_cebe1d9e7d8e.json
notebooks
spectral_history.ipynb
scripts
run_false_positive_tests.py
tests
run_false_positive_test_suite.pytest_cli.pytest_false_positive_methodology.pytest_false_positive_verifier.pytest_feedback_integration.pytest_partitioning.pytest_seed_management.pytest_self_opt_support.pytest_snapshot_system.pytest_spectral_paley.pytest_verification_robustness.py
tnfr_factorization
__init__.pyapi.pycli.pyfailure_telemetry.pyfeedback_adapter.pyfeedback_integration.pypartitioning.pyself_opt_support.pyspectral_paley.py
demo_snapshots.dbLICENSE_SNAPSHOT.mdPACKAGE_SUMMARY.mdREADME.mdseed_management.pysnapshot_system.pytest_certificate_hashing.pytest_installation.pyverification_trajectory_77.json
benchmarks
analyze_tetrad_universality.pyb0star_alpha_canonical_product_graphs.pybenchmark_optimization_tracks.pybenchmark_utils.pyboundary_vibration.pybridge_primes_riemann.pychiral_involution.pycli_utils.pycoherence_projector_sense_index.pycommutant_bridge.pycomposition_arithmetic.pyconfinement_zones_test.pyconservation_law_validation.pydirected_paley_bridge.pyemergent_arithmetic_pulse.pyemergent_atom_dynamics.pyemergent_atomic_shells.pyemergent_base_dimension.pyemergent_dimension_dynamics.pyemergent_fractal_pulse.pyemergent_fractal_simplex_dimension.pyemergent_integers_symmetry.pyemergent_musical_nfr.pyemergent_nfr_geometry.pyemergent_nfr_where.pyemergent_rationals.pyemergent_rhythm.pyemergent_screening.pyemergent_shell_cardinals.pyemergent_shell_ordering.pyemergent_simplex_dimension.pyemergent_substrate_symmetry.pyequivariance_wall.pyexternal_phase_gate_validation.pyfield_methods_battery.pygolden_residue_remesh_bridge.pyintegrated_force_regime_study.pyinverse_spectrum_to_symmetry.pyk_phi_safety_demo.pykuramoto_farey_bridge.pymissing_piece_bridge.pymultichannel_interface_benchmark.pynavier_stokes_recipe_bridge.pynodal_propagator_residue_bridge.pyns_moment_hierarchy_cascade.pyoperational_irreducibility.pypaley_bridge.pyphase_curvature_investigation.pyphase_wall.pyphi_s_confinement_investigation.pyprimes_as_consequence.pypulse_phase_coherence_budget.pyREADME.mdremesh_infinity_riemann_baseline.pyremesh_infinity_riemann_composed.pyremesh_infinity_riemann_modified_graph.pyremesh_infinity_riemann_operator.pyremesh_infinity_riemann_spectral_basis.pyremesh_infinity_riemann_spectral_robustness.pyremesh_infinity_riemann_spectral.pyresidue_phase_vs_riemann.pystructural_interface_benchmark.pytemporal_interface_benchmark.pytetrad_results_aggregate.pyu2_destabilization_irreversibility.pyuniversality_clusters.pyxi_c_fast_experiment.py
primality-test
benchmarks
comprehensive_benchmark.py
docs
ADVANCED_INTEGRATION.mdmathematical_foundation.mdperformance_analysis.md
examples
advanced_examples.pybasic_usage.py
tnfr_primality
__init__.py__main__.pyadvanced_cli.pyadvanced_core.pycli.pyconstants.pycore.pyoptimized.py
MANIFEST.inPACKAGE_SUMMARY.mdREADME.mdRELEASE_NOTES_v1.0.mdsetup.pytest_installation.py
tests
core_physics
__init__.pytest_conservation_laws.pytest_delta_nfr_computation_paths.pytest_delta_nfr.pytest_dispersion_coherence_sign_invariance.pytest_emergent_constants_guard.pytest_lyapunov_operators.pytest_nodal_equation.pytest_structural_triad.py
data
replay_manifests
sample_run
_manifest_summary.json_manifest.json_partition_files.txt.gz
self_opt_validation
seed_alpha
paley.json
seed_beta
integration.json
seed_gamma
unknown.json
self_optimization
test_run
partitioned
test_run
test_run_p0.jsontest_run_p1.json
_manifest_summary.json_manifest.json
engines
test_pattern_discovery_manifest.pytest_self_optimization_engine.py
mathematics
__init__.pytest_autodiff.pytest_backends.pytest_dissipative_dynamics.pytest_epi.pytest_factory_patterns.pytest_metrics.pytest_navier_stokes_refounded.pytest_number_theory_canonical.pytest_operators.pytest_residue_networks.pytest_riemann_nodal_pulse.pytest_riemann_pulse_coherence.pytest_spaces.pytest_transforms.pytest_validator.py
operators
test_canonical_operators_modern.pytest_grammar_canon.pytest_grammar_canonical_consistency.pytest_grammar_dynamics.pytest_operator_contracts.pytest_operator_strategies.py
parallel
test_fractal_partition_manifest.py
physics
test_conservation_gauge_unification.pytest_dissipative_conservation.pytest_emergent_chemistry.pytest_field_cache_invalidation.pytest_gauge.pytest_phase_transition.pytest_signatures.pytest_spectral_conservation.pytest_structural_diffusion.pytest_structural_integrity.pytest_symplectic_substrate.pytest_tetrad_bounds.pytest_variational.pytest_yang_mills_closure.pytest_yang_mills_derivability.pytest_yang_mills_scaling.pytest_yang_mills_structural_gap.pytest_yang_mills_u6_sweep.py
scripts
test_run_self_opt_validation.pytest_run_self_optimization.py
sdk
__init__.pytest_simple_advanced.py
__init__.pyconftest.pyREADME.mdtest_breast_cancer_phase_gate_demo.pytest_classical_mechanics.pytest_distributed_fft.pytest_external_phase_gate_validation.pytest_factorization_entrypoint.pytest_multichannel_interface.pytest_nodal_optimizer.pytest_phase_gate_api.pytest_replay_register_manifest.pytest_signal_confrontation.pytest_structural_interface_api.pytest_structural_interface_baselines.pytest_structural_interface_benchmark.pytest_temporal_interface.pytest_vectorized_coherence_length_regression.pytest_wine_quality_phase_gate_demo.pyutils.py
examples
01_foundations
01_hello_world.py02_musical_resonance.py03_network_formation.py04_operator_sequences.py05_coherence_evolution.py06_network_topologies.py07_phase_transitions.py08_emergent_phenomena.py09_visualization_suite.py10_simplified_sdk_showcase.py
02_physics_regimes
11_classical_limit_comparison.py115_operator_contract_audit.py12_classical_mechanics_demo.py13_quantum_mechanics_demo.py14_uncertainty_and_interference.py15_train_crossing_demo.py17_conservation_law_demo.py26_gauge_structure_demo.py27_variational_principle_demo.py28_dissipative_systems_demo.py29_lyapunov_stability_demo.py30_self_optimization_demo.py31_mathematical_constants_basis.py33_complex_field_unification.py34_conservation_protocol_suite.py35_tetrad_irreducibility.py36_grammar_violation_detector.py37_operator_tetrad_synergy.py38_grammar_energy_landscape.py39_nodal_equation_decomposition.py
03_riemann_zeta
157_nodal_pulse_phase_attack.py41_von_mangoldt_zeta_demo.py42_riemann_zeros_as_resonances.py43_prime_ladder_hamiltonian_demo.py44_weil_explicit_formula_demo.py45_li_keiper_demo.py46_weil_tnfr_positivity_demo.py47_alpha_sweep_demo.py48_admissible_family_sweep_demo.py49_nodeaware_gauge_sweep_demo.py50_uniform_coercivity_demo.py51_adaptive_coercivity_demo.py52_paley_gap_coercivity_demo.py53_lyapunov_spectral_positivity_demo.py54_hilbert_polya_demo.py55_structural_zero_density_demo.py56_spectral_emergence_demo.py57_admissible_rescaling_demo.py58_oscillatory_correction_demo.py
04_riemann_L_twisted
59_dirichlet_l_function_demo.py60_dirichlet_l_continuation_demo.py61_dirichlet_l_hamiltonian_demo.py62_dirichlet_weil_explicit_formula_demo.py63_dirichlet_li_keiper_demo.py64_twisted_weil_positivity_demo.py65_twisted_alpha_sweep_demo.py66_twisted_admissible_family_sweep_demo.py67_twisted_nodeaware_gauge_sweep_demo.py68_twisted_hermite_family_demo.py69_twisted_coercivity_uniform_demo.py70_twisted_paley_gap_coercivity_demo.py71_twisted_lyapunov_spectral_demo.py72_twisted_hilbert_polya_demo.py73_twisted_structural_zero_density_demo.py74_twisted_spectral_emergence_demo.py75_twisted_admissible_rescaling_demo.py76_twisted_oscillatory_correction_demo.py
05_type_hygiene
77_remesh_infinity_residue_split_demo.py78_nuf_type_signature_demo.py79_epi_type_signature_demo.py80_phi_type_signature_demo.py81_dnfr_type_signature_demo.py82_remesh_window_type_signature_demo.py83_delta_phi_max_type_signature_demo.py84_coupling_weights_type_signature_demo.py85_tetrad_closure_signature_demo.py86_currents_closure_signature_demo.py87_aggregates_closure_signature_demo.py88_urules_consistency_signature_demo.py89_operator_catalog_discipline_signature_demo.py
06_navier_stokes
158_navier_stokes_two_face_refounded.py
07_number_theory
100_prime_families_orbits.py101_numbers_as_coupled_network.py102_nodal_flow_primes_equilibria.py116_nuf_emergent_prime_visibility.py146_primality_grammatical_inertness.py147_numbers_as_free_monoid_words.py148_capacity_arm_carries_von_mangoldt.py149_p14_is_the_capacity_arm_operator.py153_structural_frequency_rank_cyclotomy.py40_arithmetic_number_theory.py94_generative_number_construction.py95_primes_from_spectral_waves.py96_spectral_vibration_of_coherence.py97_goldbach_additive_multiplicative.pyemergent_chemistry_particles_demo.py
08_emergent_geometry
103_emergent_substrate_meets_riemann.py106_per_node_polarization_geometry.py107_orthogonal_structure_emergent_geometry.py108_emergent_field_generating_structure.py112_structure_predicts_coherence_flow.py113_overdamped_projection_bridge.py114_substrate_conserved_quantities.py117_emergent_geometry_residue_graph.py118_emergent_vs_classical_operator.py119_phase_sector_directed_residue.py120_symmetry_wall_substrate_vs_spectrum.py121_canonical_symmetry_break_negative.py122_factorization_phase_sector.py123_symmetry_sector_decomposition.py124_emergent_metric_fractal_consistency.py125_node_is_the_emergent_substrate.py126_two_layers_base_fiber.py127_base_is_emergent_not_imposed.py128_base_substrate_coemergence.py129_spectral_gap_base_fiber_clock.py130_operators_break_substrate_charges.py131_coemergent_loop_convergence.py132_geometric_phase_holonomy.py133_psi_topological_defects.py134_spectral_dimension_heat_kernel.py135_arrow_of_time_h_theorem.py136_heat_kernel_coefficients.py137_synchronization_transition.py138_structure_frequency_synchronization.py139_grammar_formal_language.py140_grammar_automaton.py141_grammar_rule_decomposition.py142_grammar_operator_quotient.py143_glyphic_function_sublanguage.py144_branching_combinator.py145_syntactic_monoid_starfree.py150_emergent_grammatical_pattern_parry.py151_grammar_in_emergent_geometry.py152_operator_contract_tetrahedron.py154_conductor_annotated_qr_spectrum.py155_ontological_position_of_numbers.py156_emergence_directness_law.py98_emergent_symplectic_substrate.py99_structural_diffusion.pyunified_fields_showcase.py
09_millennium
109_p_vs_np_coherence_synthesis.py110_bsd_rank_structural_pressure.py111_hodge_discrete_and_honest_gap.py
10_applications
159_empirical_confrontation_pipeline.py90_phase_gate_monitor_demo.py91_breast_cancer_phase_gate_demo.py92_wine_quality_phase_gate_demo.py93_structural_interface_demo.pypytorch_cuda_demo.py
README.md
scripts
replay
__init__.pyregister_manifest.py
__init__.pyREADME.mdrebuild_failure_manifest.pyrun_reproducible_benchmarks.pyrun_self_opt_validation.pyrun_self_optimization.pytnfr_is_prime.pyvalidate_conservation_law.pyverify_internal_references.py
src
core
__init__.pyevaluation.py
tnfr
backends
__init__.pyjax_backend.pynumpy_backend.pyoptimized_numpy.pyREADME.mdtorch_backend.py
cli
__init__.py__init__.pyiarguments.pyarguments.pyiexecution.pyexecution.pyiinteractive_validator.pyREADME.mdutils.pyutils.pyi
compat
__init__.pydataclass.pyjsonschema_stub.pymatplotlib_stub.pynumpy_stub.pyREADME.md
config
__init__.py__init__.pyiconstants.pyconstants.pyidefaults_core.pydefaults_init.pydefaults_metric.pydefaults.pyfeature_flags.pyfeature_flags.pyiglyph_constants.pyoperator_names.pyoperator_names.pyiphysics_derivation.pyprecision_modes.pypresets.pypresets.pyiREADME.mdsecurity.pythresholds.pytnfr_config.py
constants
__init__.py__init__.pyialiases.pyaliases.pyicanonical.pymetric.pymetric.pyioperational.py
core
__init__.pycontainer.pydefault_implementations.pyexceptions.pyinterfaces.pyREADME.md
dynamics
__init__.py__init__.pyiadaptation.pyadaptation.pyiadaptive_sequences.pyadaptive_sequences.pyiadelic.pyadvanced_cache_optimizer.pyadvanced_fft_arithmetic.pyaliases.pyaliases.pyibifurcation.pycache_aware_fft_engine.pycanonical.pycanonical.pyicomputational_hub.pycoordination.pycoordination.pyidistributed_fft.pydnfr.pydnfr.pyidynamic_limits.pyemergent_centralization.pyemergent_integration_engine.pyfeedback.pyfeedback.pyifft_backend.pyfft_cache_coordinator.pyfft_dispatchers.pyfft_engine.pyfft_workers.pyfused_dnfr.pyhomeostasis.pyhomeostasis.pyiintegrators.pyintegrators.pyilearning.pylearning.pyimetabolism.pymulti_modal_cache.pynbody_tnfr.pynbody.pynodal_optimizer.pyoptimization_orchestrator.pypropagation.pyREADME.mdruntime.pyruntime.pyisampling.pysampling.pyiselectors.pyselectors.pyiself_optimizing_engine.pyspectral_structural_fusion.pystructural_cache.pystructural_clip.pysymplectic.pyunified_backend.pyunified_mathematical_cache_orchestrator.py
engines
computation
__init__.pyfft_engine.pyunified_fft_engine.pyunified_gpu_system.py
constants
__init__.pycanonical.pyoperational.py
integration
__init__.pyemergent_integration.py
pattern_discovery
__init__.pymathematical_patterns.pymulti_modal_cache.py
self_optimization
__init__.pyengine.py
__init__.pyREADME.md
errors
__init__.pycontextual.py
factorization
__init__.py
flatten
README.md
gamma
README.md
glyph_history
README.md
glyph_runtime
README.md
immutable
README.md
initialization
README.md
io
README.md
math
__init__.pyfields_symbolic.pygrammar_validators.pyoptimizer.pyREADME.mdsymbolic.py
mathematics
__init__.pybackend.pybackend.pyidynamics.pydynamics.pyiepi.pyepi.pyigenerators.pygenerators.pyiliouville.pymetrics.pymetrics.pyinumber_theory.pyoperators_factory.pyoperators_factory.pyioperators.pyoperators.pyioptimized_primality.pyprojection.pyprojection.pyiREADME.mdruntime.pyruntime.pyispaces.pyspaces.pyispectral.pytransforms.pytransforms.pyiunified_cache.pyunified_numerical.pyzeta.py
metrics
__init__.py__init__.pyibuffer_cache.pybuffer_cache.pyicache_utils.pycoherence.pycoherence.pyicommon.pycommon.pyicore.pycore.pyidiagnosis.pydiagnosis.pyiemergence.pyexport.pyexport.pyiglyph_timing.pyglyph_timing.pyilearning_metrics.pylearning_metrics.pyilocal_coherence.pyphase_coherence.pyphase_compatibility.pyREADME.mdreporting.pyreporting.pyisense_index.pysense_index.pyitelemetry.pytetrad.pytrig_cache.pytrig_cache.pyitrig.pytrig.pyi
multiscale
__init__.pyhierarchical.pyREADME.md
navier_stokes
__init__.pyconservative_face.pyoperator.py
node
README.md
observers
README.md
operators
network_analysis
__init__.pysource_detection.py
postconditions
__init__.pymutation.py
preconditions
__init__.pycoherence.pydissonance.pyemission.pymutation.pyreception.pyresonance.py
strategies
__init__.pydefaults.pygpu_strategies.pystrategy.py
__init__.py__init__.pyialgebra.pycanonical_patterns.pycascade.pycoherence.pycontraction.pycoupling.pycycle_detection.pydefinitions_base.pydefinitions.pydefinitions.pyidissonance.pyemission.pyexpansion.pygrammar_application.pygrammar_canon.pygrammar_context.pygrammar_core.pygrammar_dynamics.pygrammar_error_factory.pygrammar_memoization.pygrammar_patterns.pygrammar_telemetry.pygrammar_types.pygrammar_u6.pygrammar_validate.pygrammar.pygrammar.pyihamiltonian.pyhealth_analyzer.pyintrospection.pyjitter.pyjitter.pyilifecycle.pymetabolism.pymetrics_basic.pymetrics_core.pymetrics_network.pymetrics_structural.pymetrics_u6.pymetrics.pymutation.pynodal_equation.pyoperator_contracts.pypattern_detection.pypatterns.pyREADME.mdreception.pyrecursivity.pyregistry.pyregistry.pyiremesh.pyremesh.pyiresonance.pyself_organization.pysilence.pystructural_units.pytransition.py
parallel
__init__.pyauto_scaler.pydistributed.pyengine.pymonitoring.pypartitioner.pyREADME.md
performance
guardrails.py
physics
__init__.py_helpers.pycalibration.pycanonical.pycell.pyclassical_mechanics.pyconservation_gauge_unification.pyconservation.pydissipative_conservation.pyemergent_chemistry.pyemergent_particles.pyextended.pyfields.pygauge.pyintegrity.pyinteractions.pylife.pylyapunov.pypatterns.pyphase_transition.pyquantum_mechanics.pyREADME.mdsignatures.pyspectral_conservation.pyspectral_metrics.pystructural_diffusion.pysymplectic_substrate.pytelemetry.pyunified.pyvariational.pyvectorized_ops.py
primality
__init__.py
recipes
__init__.pycookbook.pyREADME.md
riemann
__init__.pyadmissible_family_sweep.pyadmissible_rescaling.pyaggregates_closure_signature.pyalpha_sweep.pyanalytic_continuation_dirichlet.pyanalytic_continuation.pycoercivity_uniform.pycoupling_weights_type_signature.pycurrents_closure_signature.pydelta_phi_max_type_signature.pydirichlet_l.pydnfr_type_signature.pyepi_type_signature.pyhilbert_polya.pyli_keiper.pylyapunov_spectral_positivity.pynodal_pulse.pynodeaware_gauge_sweep.pynuf_type_signature.pyoperator_catalog_discipline_signature.pyoperator.pyoscillatory_correction.pypaley_gap_coercivity.pyphi_type_signature.pyprime_ladder_hamiltonian.pypulse_coherence.pyremesh_infinity_residue_split.pyremesh_window_type_signature.pyspectral_emergence.pystructural_zero_density.pytelemetry.pytetrad_closure_signature.pytwisted_admissible_family_sweep.pytwisted_admissible_rescaling.pytwisted_alpha_sweep.pytwisted_coercivity_uniform.pytwisted_hermite_family.pytwisted_hilbert_polya.pytwisted_li_keiper.pytwisted_lyapunov_spectral_positivity.pytwisted_nodeaware_gauge_sweep.pytwisted_oscillatory_correction.pytwisted_paley_gap_coercivity.pytwisted_prime_ladder_hamiltonian.pytwisted_spectral_emergence.pytwisted_structural_zero_density.pytwisted_weil_explicit_formula.pytwisted_weil_positivity.pyurules_consistency_signature.pyvon_mangoldt.pyweil_explicit_formula.pyweil_positivity.py
schemas
__init__.pygrammar.jsonREADME.md
sdk
__init__.py__init__.pyiadaptive_system.pyadaptive_system.pyibuilders.pybuilders.pyifluent.pyfluent.pyiREADME.mdself_opt.pysimple.pytemplates.pytemplates.pyiutils.py
security
__init__.pycrypto.pydatabase.pyREADME.mdsubprocess.pyvalidation.py
sequencing
__init__.pypatterns.pyREADME.md
services
__init__.pyorchestrator.pyREADME.md
sparse
__init__.pyREADME.mdrepresentations.py
structural
README.md
telemetry
__init__.pycache_metrics.pycache_metrics.pyiconstants.pynu_f.pynu_f.pyiREADME.mdunified_telemetry_system.pyverbosity.pyverbosity.pyi
tools
__init__.pydomain_templates.pyREADME.mdsequence_generator.pytnfr_is_prime_cli_optimized.pytnfr_is_prime_cli.py
topology
__init__.pyasymmetry.pyREADME.md
utils
cache_layers.pycache.pycache.pyicallbacks.pycallbacks.pyichunks.pychunks.pyidata.pydata.pyifast_diameter.pygraph.pygraph.pyiinit.pyinit.pyiio.pyio.pyinumeric.pynumeric.pyiREADME.mdtopology.pyunified_cache.py
validation
__init__.py__init__.pyiaggregator.pybase.pycompatibility.pycompatibility.pyiconfig.pygraph.pygraph.pyihealth.pyinput_validation.pyinterface_baselines.pyinvariants.pymultichannel_interface.pyphase_gate.pyREADME.mdrules.pyrules.pyiruntime.pyruntime.pyisequence_validator.pysignal_confrontation.pysoft_filters.pysoft_filters.pyispectral.pyspectral.pyistructural_interface.pytemporal_interface.pyunified_validation_system.pyvalidator.pywindow.pywindow.pyi
visualization
__init__.pycascade_viz.pyhierarchy.pyREADME.mdsequence_plotter.py
yang_mills
__init__.pyclosure.pyderivability.pyscaling.pystructural_gap.pyu6_sweep.py
__init__.py__init__.pyi_compat.py_version.py_version.pyialias.pyalias.pyibackend_config.pycache.pycache.pyiexecution.pyexecution.pyiflatten.pyflatten.pyigamma.pygamma.pyiglyph_history.pyglyph_history.pyiglyph_runtime.pyglyph_runtime.pyiimmutable.pyimmutable.pyiinitialization.pyinitialization.pyiio.pyio.pyilocking.pylocking.pyinode.pynode.pyiobservers.pyobservers.pyiontosim.pyontosim.pyipy.typedrng.pyrng.pyisecure_config.pyselector.pyselector.pyisense.pysense.pyistructural.pystructural.pyitokens.pytokens.pyitrace.pytrace.pyitypes.pytypes.pyiunits.pyunits.pyi
tetrad_evaluator.py
.pre-commit-config.yaml.semgrep.yaml.zenodo.jsonARCHITECTURE.mdbandit.yamlCHANGELOG.mdCITATION.cffCONTRIBUTING.mdEMERGENT_CANON_AUDIT.mdEMERGENT_DERIVATION_PLAN.mdLICENSE.mdMakefileMANIFEST.inpyproject.tomlpyrightconfig.jsonPYTORCH_CUDA_INTEGRATION.mdREADME.mdSECURITY.mdTESTING.mdTNFR_Website_Content_Brief.md
FILE: src/tnfr/operators/remesh.py

remesh.py

Canonical REMESH operator: Recursive pattern propagation preserving structural coherence.

REMESH (Recursivity) - Glyph: REMESH

Physical Foundation

From the nodal equation: ∂EPI/∂t = νf · ΔNFR(t)

REMESH implements: EPI(t) ↔ EPI(t-τ) (operational fractality)

REMESH enables patterns to echo across temporal and spatial scales while maintaining coherence. "What persists at one scale can be rewritten at another, with coherence propagating structurally, not imposed." - El pulso que nos atraviesa

Canonical Physical Behavior

REMESH acts on the nodal equation by creating temporal/spatial coupling:

  1. Memory Activation: References EPI(t-τ) from structural history
  2. Pattern Recognition: Identifies similar EPIs across network (structural_similarity)
  3. Coherent Propagation: Propagates patterns maintaining identity (StructuralIdentity)
  4. Scale Invariance: Preserves structural properties across reorganizations

Effect on nodal components:

  • EPI: Mixed with historical states (EPI_new = (1-α)·EPI_now + α·EPI_past)
  • νf: Can increase during memory activation (reactivation of dormant patterns)
  • ΔNFR: Implicitly calculated from reorganization (ΔNFR = ΔEPI/νf from nodal equation)
  • Phase: Preserved through StructuralIdentity tracking

Operator Relationships (from Nodal Equation Physics)

All relationships emerge naturally from how operators affect EPI, νf, ΔNFR, and phase:

REMESH Hierarchical (Central Control → Periphery)

Physics: Controlled replication from center maintaining coherence descendente

  1. IL (Coherence): Reduces |ΔNFR| → stabilizes each recursion level

    • Relationship: Estabilización multinivel (coherence extended)
    • Dynamics: REMESH propagates pattern, IL consolidates at each level
    • Sequence: REMESH → IL (recursive propagation → multi-level stabilization)
  2. VAL (Expansion): Increases dim(EPI) → structural expansion

    • Relationship: Expansión estructural coherente (fractal growth)
    • Dynamics: REMESH replicates, VAL expands each replica maintaining form
    • Sequence: VAL → REMESH (expand → replicate expanded form)
  3. SHA (Silence): νf → 0 → latent memory

    • Relationship: Estabilización de red latente (structural memory)
    • Dynamics: SHA freezes pattern (∂EPI/∂t → 0), REMESH propagates frozen state
    • Sequence: SHA → REMESH (freeze → propagate frozen memory)
    • Critical: NO functional redundancy - uses existing Silence operator
  4. NUL (Contraction): Reduces dim(EPI) → compression

    • Relationship: Compresión estructural coherente (fractal distillation)
    • Dynamics: Complementary to VAL, reduces dimensionality maintaining identity
    • Sequence: NUL → REMESH (compress → replicate compressed essence)
    • Note: Hierarchical simplification preserving core structure

REMESH Rhizomatic (Decentralized Propagation)

Physics: Propagation without fixed center, by local resonance

  1. OZ (Dissonance): Increases |ΔNFR| → exploration

    • Relationship: Bifurcación distribuida (distributed bifurcation)
    • Dynamics: REMESH + OZ creates decentralized local variations
    • Sequence: OZ → REMESH (destabilize → replicate variations)
  2. UM (Coupling): φᵢ → φⱼ → structural connection

    • Relationship: Acoplamiento multiescala (multi-scale coupling)
    • Dynamics: REMESH propagates, UM connects replicas without hierarchy
    • Sequence: REMESH → UM (propagate → connect peers)
  3. THOL (Self-organization): Creates sub-EPIs → emergence

    • Relationship: Auto-organización recursiva (recursive self-organization)
    • Dynamics: REMESH + THOL generates emergent structures without center
    • Sequence: THOL → REMESH (emerge sub-EPIs → replicate emergent forms)

REMESH Fractal Harmonic (Perfect Self-Similarity)

Physics: Scale-symmetric replication maintaining perfect auto-similitud

  1. RA (Resonance): Amplifies coherently → propagation

    • Relationship: Resonancia multiescala (multi-scale resonance)
    • Dynamics: REMESH replicates, RA amplifies with perfect symmetry
    • Sequence: REMESH → RA (replicate → amplify symmetrically)
  2. NAV (Transition): Activates latent EPI → regime shift

    • Relationship: Transición entre attractores fractales
    • Dynamics: REMESH navigates between self-similar attractor states
    • Sequence: NAV → REMESH (transition → replicate new regime)
  3. AL (Emission): Creates EPI from vacuum → generation

    • Relationship: Emisión fractal (fractal emission)
    • Dynamics: REMESH + AL generates self-similar patterns from origin
    • Sequence: AL → REMESH (emit seed → replicate fractally)
  4. EN (Reception): Updates EPI from network → reception

    • Relationship: Recepción multi-escala simétrica (symmetric multi-scale reception)
    • Dynamics: EN captures patterns from multiple sources → REMESH replicates symmetrically
    • Sequence: EN → REMESH (receive multi-scale → propagate symmetrically)
    • Note: Pre-recursion operator that feeds REMESH

Operators with Indirect Relationships

ZHIR (Mutation): Present in canonical relationships but NOT in types

  • Physical Reason: ZHIR is a TRANSFORMER that emerges POST-recursion
  • Dynamics: REMESH propagates → local variations + destabilizers → ZHIR transforms
  • Grammar: Requires IL previo + recent destabilizer (U4b)
  • Relationship: Mutación replicativa (replication facilitates mutation)
  • Conclusion: Operates AFTER REMESH completes, not during

Grammar Implications from Physical Analysis

REMESH's physical behavior affects unified grammar rules (UNIFIED_GRAMMAR_RULES.md):

U1: STRUCTURAL INITIATION & CLOSURE

Physical Basis: REMESH echoes EPI(t-τ), can activate from dormant/null states

U1a (Initiation): REMESH is a GENERATOR

  • Can start sequences when operating on latent structure
  • Activates dormant patterns via temporal coupling
  • Rule: Sequences can begin with REMESH

U1b (Closure): REMESH is a CLOSURE operator

  • Distributes structure across scales leaving system in recursive attractor
  • Creates self-sustaining multi-scale coherence
  • Rule: Sequences can end with REMESH

U2: CONVERGENCE & BOUNDEDNESS

Physical Basis: REMESH mixing with historical states can amplify or dampen ΔNFR

Requirement: REMESH + destabilizers → must include stabilizers

  • Example: REMESH + VAL (expansion) → requires IL (coherence)
  • Prevents: Unbounded growth through recursive expansion
  • Rule: If REMESH precedes/follows VAL, OZ, or ZHIR → require IL or THOL

Integration Convergence: ∫ νf · ΔNFR dt must converge

  • REMESH temporal mixing: (1-α)·EPI_now + α·EPI_past
  • Without stabilizers: Can create positive feedback loop
  • Rule: Stabilizers ensure convergence of recursive reorganization

U3: RESONANT COUPLING

Physical Basis: REMESH propagates patterns - must verify phase compatibility

Requirement: REMESH with UM or RA → verify |φᵢ - φⱼ| ≤ Δφ_max

  • REMESH creates replicas that must be phase-compatible for resonance
  • Antiphase replicas → destructive interference
  • Rule: StructuralIdentity.matches() includes phase verification
  • Implementation: Phase pattern captured and validated during propagation

U4: BIFURCATION DYNAMICS

Physical Basis: REMESH can trigger bifurcation through recursive amplification

U4a (Triggers Need Handlers): REMESH + destabilizers → need handlers

  • REMESH → THOL sequence: Recursion enables self-organization
  • Must handle emergent sub-EPIs from recursive bifurcation
  • Rule: REMESH + OZ or ZHIR → require THOL or IL handlers

U4b (Transformers Need Context): ZHIR requires REMESH context

  • REMESH creates variations across scales
  • ZHIR then transforms local variations (post-recursion)
  • Rule: ZHIR after REMESH → requires prior IL + recent destabilizer

Centralized Flow - No Redundancy

This implementation maintains a single, centralized flow:

  1. SHA Integration: Uses existing Silence operator from definitions.py

    • NO reimplementation of SHA functionality
    • StructuralIdentity only CAPTURES frozen states, doesn't freeze
    • Workflow: Silence() → capture_from_node(is_sha_frozen=True) → validate
  2. Coherence Calculation: Simplified C(t) for REMESH validation

    • Full coherence calculation in tnfr.metrics module
    • compute_global_coherence() specific to REMESH fidelity checks
    • No duplication with main coherence computation
  3. Pattern Recognition: Unique to REMESH structural memory

    • structural_similarity(): Pattern matching (no operator overlap)
    • structural_memory_match(): Network-wide search (REMESH-specific)
    • No duplication with network analysis tools
  4. Identity Tracking: REMESH-specific fractal identity

    • StructuralIdentity: Persistent identity across reorganizations
    • Captures EPI signature, νf range, phase pattern
    • Validates preservation post-recursion

Key Capabilities

  • Structural memory: Pattern recognition across network nodes
  • Identity preservation: Fractal lineage tracking across reorganizations
  • Coherence conservation: Validating structural fidelity during remeshing
  • Multi-modal recursivity: Hierarchical, rhizomatic, and fractal harmonic modes
  • Grammar-compliant: All operations respect unified grammar rules (U1-U5)

Source Code

python
"""Canonical REMESH operator: Recursive pattern propagation preserving structural coherence.

REMESH (Recursivity) - Glyph: REMESH
====================================

Physical Foundation
-------------------
From the nodal equation: ∂EPI/∂t = νf · ΔNFR(t)

REMESH implements: **EPI(t) ↔ EPI(t-τ)** (operational fractality)

REMESH enables patterns to echo across temporal and spatial scales while maintaining
coherence. "What persists at one scale can be rewritten at another, with coherence
propagating structurally, not imposed." - El pulso que nos atraviesa

Canonical Physical Behavior
----------------------------
REMESH acts on the nodal equation by creating temporal/spatial coupling:

1. **Memory Activation**: References EPI(t-τ) from structural history
2. **Pattern Recognition**: Identifies similar EPIs across network (structural_similarity)
3. **Coherent Propagation**: Propagates patterns maintaining identity (StructuralIdentity)
4. **Scale Invariance**: Preserves structural properties across reorganizations

Effect on nodal components:
- EPI: Mixed with historical states (EPI_new = (1-α)·EPI_now + α·EPI_past)
- νf: Can increase during memory activation (reactivation of dormant patterns)
- ΔNFR: Implicitly calculated from reorganization (ΔNFR = ΔEPI/νf from nodal equation)
- Phase: Preserved through StructuralIdentity tracking

Operator Relationships (from Nodal Equation Physics)
-----------------------------------------------------
All relationships emerge naturally from how operators affect EPI, νf, ΔNFR, and phase:

### REMESH Hierarchical (Central Control → Periphery)
**Physics**: Controlled replication from center maintaining coherence descendente

1. **IL (Coherence)**: Reduces |ΔNFR| → stabilizes each recursion level
   - Relationship: Estabilización multinivel (coherence extended)
   - Dynamics: REMESH propagates pattern, IL consolidates at each level
   - Sequence: REMESH → IL (recursive propagation → multi-level stabilization)

2. **VAL (Expansion)**: Increases dim(EPI) → structural expansion
   - Relationship: Expansión estructural coherente (fractal growth)
   - Dynamics: REMESH replicates, VAL expands each replica maintaining form
   - Sequence: VAL → REMESH (expand → replicate expanded form)

3. **SHA (Silence)**: νf → 0 → latent memory
   - Relationship: Estabilización de red latente (structural memory)
   - Dynamics: SHA freezes pattern (∂EPI/∂t → 0), REMESH propagates frozen state
   - Sequence: SHA → REMESH (freeze → propagate frozen memory)
   - **Critical**: NO functional redundancy - uses existing Silence operator

4. **NUL (Contraction)**: Reduces dim(EPI) → compression
   - Relationship: Compresión estructural coherente (fractal distillation)
   - Dynamics: Complementary to VAL, reduces dimensionality maintaining identity
   - Sequence: NUL → REMESH (compress → replicate compressed essence)
   - **Note**: Hierarchical simplification preserving core structure

### REMESH Rhizomatic (Decentralized Propagation)
**Physics**: Propagation without fixed center, by local resonance

1. **OZ (Dissonance)**: Increases |ΔNFR| → exploration
   - Relationship: Bifurcación distribuida (distributed bifurcation)
   - Dynamics: REMESH + OZ creates decentralized local variations
   - Sequence: OZ → REMESH (destabilize → replicate variations)

2. **UM (Coupling)**: φᵢ → φⱼ → structural connection
   - Relationship: Acoplamiento multiescala (multi-scale coupling)
   - Dynamics: REMESH propagates, UM connects replicas without hierarchy
   - Sequence: REMESH → UM (propagate → connect peers)

3. **THOL (Self-organization)**: Creates sub-EPIs → emergence
   - Relationship: Auto-organización recursiva (recursive self-organization)
   - Dynamics: REMESH + THOL generates emergent structures without center
   - Sequence: THOL → REMESH (emerge sub-EPIs → replicate emergent forms)

### REMESH Fractal Harmonic (Perfect Self-Similarity)
**Physics**: Scale-symmetric replication maintaining perfect auto-similitud

1. **RA (Resonance)**: Amplifies coherently → propagation
   - Relationship: Resonancia multiescala (multi-scale resonance)
   - Dynamics: REMESH replicates, RA amplifies with perfect symmetry
   - Sequence: REMESH → RA (replicate → amplify symmetrically)

2. **NAV (Transition)**: Activates latent EPI → regime shift
   - Relationship: Transición entre attractores fractales
   - Dynamics: REMESH navigates between self-similar attractor states
   - Sequence: NAV → REMESH (transition → replicate new regime)

3. **AL (Emission)**: Creates EPI from vacuum → generation
   - Relationship: Emisión fractal (fractal emission)
   - Dynamics: REMESH + AL generates self-similar patterns from origin
   - Sequence: AL → REMESH (emit seed → replicate fractally)

4. **EN (Reception)**: Updates EPI from network → reception
   - Relationship: Recepción multi-escala simétrica (symmetric multi-scale reception)
   - Dynamics: EN captures patterns from multiple sources → REMESH replicates symmetrically
   - Sequence: EN → REMESH (receive multi-scale → propagate symmetrically)
   - **Note**: Pre-recursion operator that feeds REMESH

### Operators with Indirect Relationships

**ZHIR (Mutation)**: Present in canonical relationships but NOT in types
- **Physical Reason**: ZHIR is a TRANSFORMER that emerges POST-recursion
- **Dynamics**: REMESH propagates → local variations + destabilizers → ZHIR transforms
- **Grammar**: Requires IL previo + recent destabilizer (U4b)
- **Relationship**: Mutación replicativa (replication facilitates mutation)
- **Conclusion**: Operates AFTER REMESH completes, not during

Grammar Implications from Physical Analysis
--------------------------------------------
REMESH's physical behavior affects unified grammar rules (UNIFIED_GRAMMAR_RULES.md):

### U1: STRUCTURAL INITIATION & CLOSURE
**Physical Basis**: REMESH echoes EPI(t-τ), can activate from dormant/null states

**U1a (Initiation)**: REMESH is a GENERATOR
- Can start sequences when operating on latent structure
- Activates dormant patterns via temporal coupling
- **Rule**: Sequences can begin with REMESH

**U1b (Closure)**: REMESH is a CLOSURE operator
- Distributes structure across scales leaving system in recursive attractor
- Creates self-sustaining multi-scale coherence
- **Rule**: Sequences can end with REMESH

### U2: CONVERGENCE & BOUNDEDNESS
**Physical Basis**: REMESH mixing with historical states can amplify or dampen ΔNFR

**Requirement**: REMESH + destabilizers → must include stabilizers
- Example: REMESH + VAL (expansion) → requires IL (coherence)
- Prevents: Unbounded growth through recursive expansion
- **Rule**: If REMESH precedes/follows VAL, OZ, or ZHIR → require IL or THOL

**Integration Convergence**: ∫ νf · ΔNFR dt must converge
- REMESH temporal mixing: (1-α)·EPI_now + α·EPI_past
- Without stabilizers: Can create positive feedback loop
- **Rule**: Stabilizers ensure convergence of recursive reorganization

### U3: RESONANT COUPLING
**Physical Basis**: REMESH propagates patterns - must verify phase compatibility

**Requirement**: REMESH with UM or RA → verify |φᵢ - φⱼ| ≤ Δφ_max
- REMESH creates replicas that must be phase-compatible for resonance
- Antiphase replicas → destructive interference
- **Rule**: StructuralIdentity.matches() includes phase verification
- **Implementation**: Phase pattern captured and validated during propagation

### U4: BIFURCATION DYNAMICS
**Physical Basis**: REMESH can trigger bifurcation through recursive amplification

**U4a (Triggers Need Handlers)**: REMESH + destabilizers → need handlers
- REMESH → THOL sequence: Recursion enables self-organization
- Must handle emergent sub-EPIs from recursive bifurcation
- **Rule**: REMESH + OZ or ZHIR → require THOL or IL handlers

**U4b (Transformers Need Context)**: ZHIR requires REMESH context
- REMESH creates variations across scales
- ZHIR then transforms local variations (post-recursion)
- **Rule**: ZHIR after REMESH → requires prior IL + recent destabilizer

Centralized Flow - No Redundancy
---------------------------------
This implementation maintains a single, centralized flow:

1. **SHA Integration**: Uses existing Silence operator from definitions.py
   - NO reimplementation of SHA functionality
   - StructuralIdentity only CAPTURES frozen states, doesn't freeze
   - Workflow: Silence() → capture_from_node(is_sha_frozen=True) → validate

2. **Coherence Calculation**: Simplified C(t) for REMESH validation
   - Full coherence calculation in tnfr.metrics module
   - compute_global_coherence() specific to REMESH fidelity checks
   - No duplication with main coherence computation

3. **Pattern Recognition**: Unique to REMESH structural memory
   - structural_similarity(): Pattern matching (no operator overlap)
   - structural_memory_match(): Network-wide search (REMESH-specific)
   - No duplication with network analysis tools

4. **Identity Tracking**: REMESH-specific fractal identity
   - StructuralIdentity: Persistent identity across reorganizations
   - Captures EPI signature, νf range, phase pattern
   - Validates preservation post-recursion

Key Capabilities
----------------
- Structural memory: Pattern recognition across network nodes
- Identity preservation: Fractal lineage tracking across reorganizations
- Coherence conservation: Validating structural fidelity during remeshing
- Multi-modal recursivity: Hierarchical, rhizomatic, and fractal harmonic modes
- Grammar-compliant: All operations respect unified grammar rules (U1-U5)
"""

from __future__ import annotations

import hashlib
import heapq
import random
from collections import deque
from collections.abc import Hashable, Iterable, Mapping, MutableMapping, Sequence
from dataclasses import dataclass, field
from functools import cache
from io import StringIO
from itertools import combinations
from operator import ge, le
from statistics import StatisticsError, fmean
from types import ModuleType
from typing import Any, cast

from .._compat import TypeAlias
from ..alias import get_attr, set_attr
from ..constants import DEFAULTS, REMESH_DEFAULTS, get_param
from ..constants.aliases import ALIAS_DNFR, ALIAS_EPI, ALIAS_VF
from ..constants.canonical import REMESH_SIMILARITY_THRESHOLD_CANONICAL
from ..errors import TNFRValueError
from ..mathematics.unified_numerical import np
from ..rng import make_rng
from ..types import RemeshMeta
from ..utils import cached_import, edge_version_update, kahan_sum_nd

CommunityGraph: TypeAlias = Any
NetworkxModule: TypeAlias = ModuleType
CommunityModule: TypeAlias = ModuleType
RemeshEdge: TypeAlias = tuple[Hashable, Hashable]
NetworkxModules: TypeAlias = tuple[NetworkxModule, CommunityModule]
RemeshConfigValue: TypeAlias = bool | float | int

# ---------------------------------------------------------------------------
# Latency detection threshold (νf → 0 for SHA-frozen nodes)
# ---------------------------------------------------------------------------
_VF_FROZEN_THRESHOLD = 0.05

# ==============================================================================
# Phase 1: Structural Memory & Pattern Recognition
# ==============================================================================


@dataclass
class StructuralIdentity:
    """Persistent fractal identity maintained across reorganizations.

    Captures the canonical structural "signature" of a pattern that must be
    preserved as it echoes across scales. This implements TNFR's requirement
    that patterns maintain identity through reorganization.

    **REMESH ↔ SHA Relationship**: According to TNFR theory, SHA (Silence)
    stabilizes latent network memory by reducing νf → 0, which freezes EPI
    via the nodal equation: ∂EPI/∂t = νf · ΔNFR → 0. When REMESH propagates
    patterns across scales, SHA-frozen nodes act as "structural anchors" that
    maintain identity during reorganization.

    **Usage Pattern**:
    1. Apply SHA to freeze node: νf → 0, preserves EPI
    2. Capture identity from frozen state (this class)
    3. Apply REMESH to propagate pattern across scales
    4. Validate identity preservation post-reorganization

    Attributes
    ----------
    epi_signature : float
        Characteristic EPI pattern value (preserved when SHA applied)
    vf_range : tuple[float, float]
        Range of structural frequencies (min, max) in Hz_str
    phase_pattern : float | None
        Characteristic phase pattern in [0, 2π], if applicable
    frozen_by_sha : bool
        Whether this identity was captured from SHA-frozen state (νf ≈ 0)
    lineage : list[str]
        History of transformations preserving this identity
    tolerance : float
        Maximum deviation for identity match (default: 0.1)

    Notes
    -----
    From TNFR physics (definitions.py::Silence): SHA reduces νf causing
    ∂EPI/∂t → 0 regardless of ΔNFR. This creates "latent memory" - frozen
    structural patterns that REMESH can propagate coherently across scales.

    **Do NOT reimplement SHA** - use existing Silence operator from
    tnfr.operators.definitions. This class only captures and validates
    identity, it does NOT apply SHA itself.

    See Also
    --------
    tnfr.operators.definitions.Silence : SHA operator implementation
    SHA_ALGEBRA_PHYSICS.md : SHA as identity operator derivation
    """

    epi_signature: float
    vf_range: tuple[float, float]
    phase_pattern: float | None = None
    frozen_by_sha: bool = False
    lineage: list[str] = field(default_factory=list)
    tolerance: float = 0.1

    def matches(
        self, node_data: Mapping[str, Any], *, tolerance: float | None = None
    ) -> bool:
        """Check if a node maintains this structural identity.

        Parameters
        ----------
        node_data : Mapping
            Node attributes containing EPI, vf, and optionally phase
        tolerance : float, optional
            Override default tolerance for this check

        Returns
        -------
        bool
            True if node matches this identity within tolerance

        Notes
        -----
        If frozen_by_sha=True, vf check is relaxed since SHA-frozen patterns
        have νf ≈ 0 (frozen state) while maintaining identity via EPI.
        """
        tol = tolerance if tolerance is not None else self.tolerance

        # Check EPI signature match (primary identity criterion)
        node_epi = _as_float(get_attr(node_data, ALIAS_EPI, 0.0))
        if abs(node_epi - self.epi_signature) > tol:
            return False

        # Check vf range (relaxed if SHA-frozen)
        node_vf = _as_float(get_attr(node_data, ALIAS_VF, 0.0))
        vf_min, vf_max = self.vf_range

        if self.frozen_by_sha:
            # SHA-frozen: accept low νf (frozen state) OR original range
            # (pattern may be reactivated after SHA)
            if node_vf < _VF_FROZEN_THRESHOLD:  # Frozen by SHA (νf → 0)
                pass  # Accept - this is expected for SHA-frozen patterns
            elif not (vf_min - tol <= node_vf <= vf_max + tol):
                return False
        else:
            # Normal check: must be within range
            if not (vf_min - tol <= node_vf <= vf_max + tol):
                return False

        # Check phase pattern if specified
        if self.phase_pattern is not None:
            from ..constants.aliases import ALIAS_THETA

            node_phase = _as_float(get_attr(node_data, ALIAS_THETA, None))
            if node_phase is None:
                return False
            # Phase comparison with circular wrap-around
            import math

            phase_diff = abs(node_phase - self.phase_pattern)
            phase_diff = min(phase_diff, 2 * math.pi - phase_diff)
            if phase_diff > tol:
                return False

        return True

    def record_transformation(self, operation: str) -> None:
        """Record a structural transformation in this identity's lineage.

        Parameters
        ----------
        operation : str
            Description of the transformation applied
        """
        self.lineage.append(operation)

    @classmethod
    def capture_from_node(
        cls,
        node_data: Mapping[str, Any],
        *,
        is_sha_frozen: bool = False,
        tolerance: float = 0.1,
    ) -> "StructuralIdentity":
        """Capture structural identity from a node's current state.

        This creates a "memory snapshot" of the node's structural signature
        that can be propagated via REMESH across scales.

        Parameters
        ----------
        node_data : Mapping
            Node attributes containing EPI, vf, phase
        is_sha_frozen : bool, default=False
            If True, mark identity as captured from SHA-frozen state (νf ≈ 0).
            **NOTE**: This does NOT apply SHA - it only marks that SHA was
            already applied. Use tnfr.operators.definitions.Silence to apply SHA.
        tolerance : float, default=0.1
            Tolerance for future identity matching

        Returns
        -------
        StructuralIdentity
            Captured structural identity

        Notes
        -----
        **REMESH ↔ SHA Integration Pattern**:

        1. Apply SHA operator to freeze node (see tnfr.operators.definitions.Silence)
        2. Call this method with is_sha_frozen=True to capture frozen state
        3. Apply REMESH to propagate pattern across scales
        4. Use identity.matches() to validate preservation

        **DO NOT use this to apply SHA** - SHA is a separate operator that must
        be applied via the grammar system. This only captures state AFTER SHA.

        Example
        -------
        >>> from tnfr.operators.definitions import Silence
        >>> from tnfr.structural import run_sequence
        >>> # Step 1: Apply SHA operator to freeze node
        >>> run_sequence(G, node, [Silence()])
        >>> # Step 2: Capture frozen identity
        >>> identity = StructuralIdentity.capture_from_node(
        ...     G.nodes[node],
        ...     is_sha_frozen=True
        ... )
        >>> # Step 3: Apply REMESH (propagates frozen pattern)
        >>> # ... REMESH operations ...
        >>> # Step 4: Validate identity preserved
        >>> assert identity.matches(G.nodes[node])
        """
        epi = _as_float(get_attr(node_data, ALIAS_EPI, 0.0))
        vf = _as_float(get_attr(node_data, ALIAS_VF, 0.0))

        # For vf_range, use small window around current value
        # (unless SHA-frozen, in which case we expect νf ≈ 0)
        vf_tolerance = 0.1
        vf_min = max(0.0, vf - vf_tolerance)
        vf_max = vf + vf_tolerance

        # Capture phase if present
        from ..constants.aliases import ALIAS_THETA

        phase = _as_float(get_attr(node_data, ALIAS_THETA, None))

        identity = cls(
            epi_signature=epi,
            vf_range=(vf_min, vf_max),
            phase_pattern=phase if phase is not None else None,
            frozen_by_sha=is_sha_frozen,
            tolerance=tolerance,
        )

        if is_sha_frozen:
            identity.record_transformation(
                "Captured from SHA-frozen state (latent structural memory)"
            )

        return identity


def structural_similarity(
    epi1: float | Sequence[float],
    epi2: float | Sequence[float],
    *,
    metric: str = "euclidean",
) -> float:
    """Compute structural similarity between two EPI patterns.

    Implements pattern matching for structural memory recognition.
    Returns a similarity score in [0, 1] where 1 = identical patterns.

    Parameters
    ----------
    epi1, epi2 : float or array-like
        EPI patterns to compare. Can be scalars or vectors.
    metric : {'euclidean', 'cosine', 'correlation'}
        Distance/similarity metric to use

    Returns
    -------
    float
        Similarity score in [0, 1], where 1 indicates identical patterns

    Notes
    -----
    This function is fundamental to REMESH's structural memory capability,
    enabling pattern recognition across network scales.

    Examples
    --------
    >>> structural_similarity(0.5, 0.52)  # Nearly identical scalars
    0.98
    >>> structural_similarity([0.5, 0.3], [0.52, 0.31])  # Similar vectors
    0.97
    """
    # Convert to numpy arrays for consistent handling
    if np is None:
        # Fallback: scalar comparison only
        if isinstance(epi1, (list, tuple)) or isinstance(epi2, (list, tuple)):
            raise ImportError(
                "NumPy required for vector EPI comparison. "
                "Install numpy: pip install numpy"
            )
        # Simple scalar distance -> similarity
        distance = abs(float(epi1) - float(epi2))
        # Map distance to similarity using exponential decay
        # similarity = exp(-k * distance) where k controls sensitivity
        import math

        k = 5.0  # Sensitivity parameter (higher = stricter matching)
        return math.exp(-k * distance)

    # NumPy available - use vector operations
    arr1 = np.atleast_1d(np.asarray(epi1, dtype=float))
    arr2 = np.atleast_1d(np.asarray(epi2, dtype=float))

    if arr1.shape != arr2.shape:
        raise TNFRValueError(
            f"EPI patterns must have same shape: {arr1.shape} vs {arr2.shape}",
            context={"shape1": arr1.shape, "shape2": arr2.shape},
        )

    if metric == "euclidean":
        distance = np.linalg.norm(arr1 - arr2)
        # Normalize by dimension for fair comparison across scales
        distance /= np.sqrt(len(arr1))
        # Convert to similarity
        import math

        k = 5.0
        return float(math.exp(-k * distance))

    elif metric == "cosine":
        # Cosine similarity: (a · b) / (||a|| ||b||)
        dot_product = np.dot(arr1, arr2)
        norm1 = np.linalg.norm(arr1)
        norm2 = np.linalg.norm(arr2)
        if norm1 < 1e-10 or norm2 < 1e-10:
            return 0.0  # Zero vectors have no meaningful similarity
        similarity = dot_product / (norm1 * norm2)
        # Map [-1, 1] to [0, 1]
        return float((similarity + 1.0) / 2.0)

    elif metric == "correlation":
        # Pearson correlation coefficient
        if len(arr1) < 2:
            # Fall back to euclidean for scalars
            return structural_similarity(epi1, epi2, metric="euclidean")
        corr_matrix = np.corrcoef(arr1, arr2)
        correlation = corr_matrix[0, 1]
        # Handle NaN (constant arrays)
        if not np.isfinite(correlation):
            correlation = 1.0 if np.allclose(arr1, arr2) else 0.0
        # Map [-1, 1] to [0, 1]
        return float((correlation + 1.0) / 2.0)

    else:
        raise TNFRValueError(
            f"Unknown metric '{metric}'. Choose from: euclidean, cosine, correlation",
            context={"metric": metric},
            suggestion="Choose from: euclidean, cosine, correlation",
        )


def structural_memory_match(
    G: CommunityGraph,
    source_node: Hashable,
    target_nodes: Iterable[Hashable] | None = None,
    *,
    threshold: float = REMESH_SIMILARITY_THRESHOLD_CANONICAL,
    metric: str = "euclidean",
) -> list[tuple[Hashable, float]]:
    """Identify nodes with EPI patterns similar to source node.

    Implements REMESH's structural memory: recognizing coherent patterns
    across the network that resonate with the source pattern.

    Parameters
    ----------
    G : TNFRGraph
        Network containing nodes with EPI attributes
    source_node : Hashable
        Node whose pattern to match against
    target_nodes : Iterable, optional
        Nodes to search. If None, searches all nodes except source.
    threshold : float, default=0.75
        Minimum similarity score for a match
    metric : str, default='euclidean'
        Similarity metric (see structural_similarity)

    Returns
    -------
    list of (node, similarity) tuples
        Nodes matching the source pattern, sorted by similarity (highest first)

    Notes
    -----
    This function is critical for REMESH's ability to propagate patterns
    coherently across scales, as specified in TNFR theoretical foundation.
    """
    source_epi = _as_float(get_attr(G.nodes[source_node], ALIAS_EPI, 0.0))

    if target_nodes is None:
        target_nodes = [n for n in G.nodes() if n != source_node]

    matches = []
    for target in target_nodes:
        if target == source_node:
            continue
        target_epi = _as_float(get_attr(G.nodes[target], ALIAS_EPI, 0.0))
        similarity = structural_similarity(source_epi, target_epi, metric=metric)
        if similarity >= threshold:
            matches.append((target, similarity))

    # Sort by similarity descending
    matches.sort(key=lambda x: x[1], reverse=True)
    return matches


def compute_structural_signature(
    G: CommunityGraph,
    node: Hashable,
) -> Any:
    """Compute multidimensional structural signature of a node.

    The signature captures the node's complete structural identity including:
    - EPI: coherence magnitude
    - νf: structural frequency
    - θ: phase
    - ΔNFR: reorganization gradient
    - Topological properties: degree, local clustering

    This signature enables REMESH's structural memory capability - recognizing
    the same pattern across different nodes and scales.

    Parameters
    ----------
    G : TNFRGraph
        Network containing the node
    node : Hashable
        Node identifier whose signature to compute

    Returns
    -------
    signature : ndarray, shape (n_features,)
        Normalized structural signature vector. If NumPy unavailable, returns
        a tuple of features.

    Notes
    -----
    The signature is normalized to unit length for consistent similarity
    comparisons across different network scales and configurations.

    Features included:
    1. EPI magnitude (coherence)
    2. νf (structural frequency in Hz_str)
    3. sin(θ), cos(θ) (circular phase representation)
    4. ΔNFR (reorganization gradient)
    5. Normalized degree (relative connectivity)
    6. Local clustering coefficient (triadic closure)

    Examples
    --------
    >>> G = nx.Graph()
    >>> G.add_node(1, EPI=0.5, vf=1.0, theta=0.2, DNFR=0.1)
    >>> G.add_edge(1, 2)
    >>> sig = compute_structural_signature(G, 1)
    >>> len(sig)  # 7 features
    7
    """
    # Extract TNFR structural attributes
    epi = _as_float(get_attr(G.nodes[node], ALIAS_EPI, 0.0))
    vf = _as_float(get_attr(G.nodes[node], ALIAS_VF, 0.0))
    from ..constants.aliases import ALIAS_THETA

    theta = _as_float(get_attr(G.nodes[node], ALIAS_THETA, 0.0))
    dnfr = _as_float(get_attr(G.nodes[node], ALIAS_DNFR, 0.0))

    # Compute topological features
    degree = G.degree(node) if G.has_node(node) else 0
    n_nodes = G.number_of_nodes()
    normalized_degree = degree / n_nodes if n_nodes > 0 else 0.0

    # Local clustering coefficient (requires networkx)
    try:
        nx, _ = _get_networkx_modules()
        clustering = nx.clustering(G, node)
    except Exception:
        clustering = 0.0

    # Build feature vector
    import math

    features = [
        epi,
        vf,
        math.sin(theta),  # Circular phase representation
        math.cos(theta),
        dnfr,
        normalized_degree,
        clustering,
    ]

    # Try to use NumPy for normalization
    if np is not None:
        signature = np.array(features, dtype=float)
        norm = np.linalg.norm(signature)
        if norm > 1e-10:
            signature = signature / norm
        return signature
    else:
        # Fallback: manual normalization
        norm = math.sqrt(sum(f * f for f in features))
        if norm > 1e-10:
            features = [f / norm for f in features]
        return tuple(features)


def detect_recursive_patterns(
    G: CommunityGraph,
    threshold: float = REMESH_SIMILARITY_THRESHOLD_CANONICAL,
    metric: str = "cosine",
    min_cluster_size: int = 2,
) -> list[list[Hashable]]:
    """Detect groups of nodes with similar structural patterns.

    These groups represent the same EPI pattern replicated across different
    nodes/scales in the network. This is fundamental to REMESH's capability
    to recognize and propagate structural identity.

    Parameters
    ----------
    G : TNFRGraph
        Network to analyze
    threshold : float, default=0.75
        Minimum similarity score (0-1) to consider patterns as "same identity".
        Higher values require stricter matching.
    metric : str, default='cosine'
        Similarity metric for signature comparison.
        Options: 'cosine', 'euclidean', 'correlation'
    min_cluster_size : int, default=2
        Minimum number of nodes required to consider as a recursive pattern.
        Single nodes are not patterns.

    Returns
    -------
    clusters : list of list
        Each cluster contains nodes sharing a structural pattern.
        Clusters are independent - nodes appear in at most one cluster.

    Notes
    -----
    Algorithm uses greedy clustering:
    1. Compute structural signatures for all nodes
    2. For each unvisited node, find all similar nodes (similarity >= threshold)
    3. Form cluster if size >= min_cluster_size
    4. Mark all cluster members as visited

    This implements TNFR's principle: "A node can recognize itself in other
    nodes" through structural resonance.

    Examples
    --------
    >>> # Network with two groups of similar nodes
    >>> clusters = detect_recursive_patterns(G, threshold=0.8)
    >>> len(clusters)
    2
    >>> all(len(c) >= 2 for c in clusters)
    True
    """
    nodes = list(G.nodes())
    n = len(nodes)

    if n < min_cluster_size:
        return []

    # Compute all signatures
    signatures = {}
    for node in nodes:
        signatures[node] = compute_structural_signature(G, node)

    # Compute similarity matrix (only upper triangle needed)
    if np is not None:
        # Use NumPy for efficient computation
        sig_array = np.array([signatures[node] for node in nodes])

        if metric == "cosine":
            # Cosine similarity matrix
            norms = np.linalg.norm(sig_array, axis=1, keepdims=True)
            norms = np.maximum(norms, 1e-10)  # Avoid division by zero
            normalized = sig_array / norms
            similarities = np.dot(normalized, normalized.T)
        elif metric == "euclidean":
            # Euclidean distance -> similarity
            from scipy.spatial.distance import pdist, squareform

            distances = squareform(pdist(sig_array, metric="euclidean"))
            max_dist = np.sqrt(2)  # Max distance for unit vectors
            similarities = 1.0 - (distances / max_dist)
        elif metric == "correlation":
            # Pearson correlation
            similarities = np.corrcoef(sig_array)
            # Handle NaN (constant signatures)
            similarities = np.nan_to_num(similarities, nan=0.0)
        else:
            raise TNFRValueError(
                f"Unknown metric: {metric}",
                context={"metric": metric},
                suggestion="Choose from: euclidean, cosine, correlation",
            )
    else:
        # Fallback: pairwise computation
        similarities = {}
        for i, node1 in enumerate(nodes):
            for j, node2 in enumerate(nodes):
                if i == j:
                    similarities[(i, j)] = 1.0
                elif i < j:
                    # Use existing structural_similarity function
                    sim = structural_similarity(
                        signatures[node1], signatures[node2], metric=metric
                    )
                    similarities[(i, j)] = sim
                    similarities[(j, i)] = sim

    # Greedy clustering
    visited = set()
    clusters = []

    for i, node in enumerate(nodes):
        if node in visited:
            continue

        # Find all similar nodes
        cluster = [node]
        visited.add(node)

        for j, other_node in enumerate(nodes):
            if other_node in visited:
                continue

            # Get similarity
            if np is not None:
                sim = similarities[i, j]
            else:
                sim = similarities.get((i, j), 0.0)

            if sim >= threshold:
                cluster.append(other_node)
                visited.add(other_node)

        # Only keep clusters meeting minimum size
        if len(cluster) >= min_cluster_size:
            clusters.append(cluster)

    return clusters


def identify_pattern_origin(
    G: CommunityGraph,
    cluster: Sequence[Hashable],
) -> Hashable | None:
    """Identify the origin node of a recursive structural pattern.

    The origin is the node with the strongest structural manifestation,
    determined by combining coherence (EPI) and reorganization capacity (νf).
    This represents the "source" from which the pattern can most coherently
    propagate.

    Parameters
    ----------
    G : TNFRGraph
        Network containing the cluster
    cluster : sequence of node identifiers
        Nodes sharing the same structural pattern

    Returns
    -------
    origin_node : Hashable or None
        Node identified as pattern origin (highest structural strength).
        Returns None if cluster is empty.

    Notes
    -----
    Structural strength score = EPI × νf

    This metric captures:
    - EPI: How coherent the pattern is (magnitude)
    - νf: How actively the pattern reorganizes (frequency)

    High score indicates a node that both maintains strong coherence AND
    has high reorganization capacity, making it ideal for propagation.

    Physical interpretation: The origin node is the "loudest" instance of
    the pattern in the network's structural field.

    Examples
    --------
    >>> cluster = [1, 2, 3]  # Nodes with similar patterns
    >>> origin = identify_pattern_origin(G, cluster)
    >>> # Origin will be node with highest EPI × νf
    """
    if not cluster:
        return None

    # Compute structural strength for each node
    scores = []
    for node in cluster:
        epi = _as_float(get_attr(G.nodes[node], ALIAS_EPI, 0.0))
        vf = _as_float(get_attr(G.nodes[node], ALIAS_VF, 0.0))
        # Structural strength = coherence × reorganization capacity
        strength = epi * vf
        scores.append((strength, node))

    # Return node with maximum strength
    scores.sort(reverse=True)
    return scores[0][1]


def propagate_structural_identity(
    G: CommunityGraph,
    origin_node: Hashable,
    target_nodes: Sequence[Hashable],
    propagation_strength: float = 0.5,
) -> None:
    """Propagate structural identity from origin to similar nodes.

    This implements REMESH's core principle: nodes with similar patterns
    mutually reinforce their coherence through structural resonance.
    The origin's pattern is propagated to targets via weighted interpolation.

    Parameters
    ----------
    G : TNFRGraph
        Network to modify (changes node attributes in-place)
    origin_node : Hashable
        Source node whose pattern to propagate
    target_nodes : sequence
        Nodes that will receive pattern reinforcement
    propagation_strength : float, default=0.5
        Interpolation weight in [0, 1]:
        - 0.0: No effect (targets unchanged)
        - 1.0: Complete copy (targets become identical to origin)
        - 0.5: Balanced blending

    Notes
    -----
    For each target node, updates:
    - EPI: new = (1-α)×old + α×origin
    - νf: new = (1-α)×old + α×origin
    - θ: new = (1-α)×old + α×origin

    Where α = propagation_strength.

    Updates respect structural boundaries (EPI_MIN, EPI_MAX) via
    structural_clip to prevent overflow and maintain physical validity.

    Records propagation in node's 'structural_lineage' attribute for
    traceability and analysis.

    **TNFR Physics**: This preserves the nodal equation ∂EPI/∂t = νf·ΔNFR
    by interpolating the structural state rather than imposing it directly.

    Examples
    --------
    >>> origin = 1
    >>> targets = [2, 3, 4]  # Similar nodes
    >>> propagate_structural_identity(G, origin, targets, 0.3)
    >>> # Targets now have patterns 30% closer to origin
    """
    # Get origin pattern
    origin_epi = _as_float(get_attr(G.nodes[origin_node], ALIAS_EPI, 0.0))
    origin_vf = _as_float(get_attr(G.nodes[origin_node], ALIAS_VF, 0.0))
    from ..constants.aliases import ALIAS_THETA

    origin_theta = _as_float(get_attr(G.nodes[origin_node], ALIAS_THETA, 0.0))

    # Get structural bounds
    from ..constants import DEFAULTS

    epi_min = float(G.graph.get("EPI_MIN", DEFAULTS.get("EPI_MIN", -1.0)))
    epi_max = float(G.graph.get("EPI_MAX", DEFAULTS.get("EPI_MAX", 1.0)))

    # Get clip mode
    clip_mode_str = str(G.graph.get("CLIP_MODE", "hard"))
    if clip_mode_str not in ("hard", "soft"):
        clip_mode_str = "hard"

    # Propagate to each target
    for target in target_nodes:
        if target == origin_node:
            continue  # Don't propagate to self

        # Get current target state
        target_epi = _as_float(get_attr(G.nodes[target], ALIAS_EPI, 0.0))
        target_vf = _as_float(get_attr(G.nodes[target], ALIAS_VF, 0.0))
        target_theta = _as_float(get_attr(G.nodes[target], ALIAS_THETA, 0.0))

        # Interpolate toward origin pattern
        new_epi = (
            1.0 - propagation_strength
        ) * target_epi + propagation_strength * origin_epi
        new_vf = (
            1.0 - propagation_strength
        ) * target_vf + propagation_strength * origin_vf
        new_theta = (
            1.0 - propagation_strength
        ) * target_theta + propagation_strength * origin_theta

        # Apply structural clipping to preserve boundaries
        from ..dynamics.structural_clip import structural_clip

        new_epi = structural_clip(new_epi, lo=epi_min, hi=epi_max, mode=clip_mode_str)  # type: ignore[arg-type]

        # Update node attributes
        set_attr(G.nodes[target], ALIAS_EPI, new_epi)
        set_attr(G.nodes[target], ALIAS_VF, new_vf)
        set_attr(G.nodes[target], ALIAS_THETA, new_theta)

        # Record lineage for traceability
        if "structural_lineage" not in G.nodes[target]:
            G.nodes[target]["structural_lineage"] = []

        # Get current step for timestamp
        from ..glyph_history import current_step_idx

        step = current_step_idx(G)

        G.nodes[target]["structural_lineage"].append(
            {
                "origin": origin_node,
                "step": step,
                "propagation_strength": propagation_strength,
                "epi_before": target_epi,
                "epi_after": new_epi,
            }
        )


# ==============================================================================
# Phase 2: Coherence Preservation & Fidelity Validation
# ==============================================================================


class RemeshCoherenceLossError(Exception):
    """Raised when REMESH reorganization loses structural coherence.

    REMESH must preserve coherence during reorganization. This error indicates
    that the structural fidelity dropped below acceptable thresholds, violating
    TNFR's requirement that "coherence propagates structurally, not imposed."
    """

    def __init__(
        self,
        fidelity: float,
        min_fidelity: float,
        details: dict[str, Any] | None = None,
    ):
        """Initialize coherence loss error.

        Parameters
        ----------
        fidelity : float
            Measured structural fidelity (coherence_after / coherence_before)
        min_fidelity : float
            Minimum required fidelity threshold
        details : dict, optional
            Additional diagnostic information
        """
        self.fidelity = fidelity
        self.min_fidelity = min_fidelity
        self.details = details or {}

        super().__init__(
            f"REMESH coherence loss: structural fidelity {fidelity:.2%} "
            f"< minimum {min_fidelity:.2%}\n"
            f"  Details: {details}"
        )


def validate_coherence_preservation(
    G_before: CommunityGraph,
    G_after: CommunityGraph,
    *,
    min_fidelity: float = 0.85,
    rollback_on_failure: bool = False,
) -> float:
    """Validate that reorganization preserved structural coherence.

    Implements TNFR requirement that REMESH reorganization must occur
    "without loss of coherence" - the total structural stability must
    be maintained within acceptable bounds.

    This function uses the canonical TNFR coherence computation from
    tnfr.metrics.common.compute_coherence() which is based on ΔNFR and dEPI.

    Parameters
    ----------
    G_before : TNFRGraph
        Network state before reorganization
    G_after : TNFRGraph
        Network state after reorganization
    min_fidelity : float, default=0.85
        Minimum acceptable fidelity (coherence_after / coherence_before)
    rollback_on_failure : bool, default=False
        If True and fidelity check fails, raise RemeshCoherenceLossError

    Returns
    -------
    float
        Structural fidelity score (coherence_after / coherence_before)

    Raises
    ------
    RemeshCoherenceLossError
        If fidelity < min_fidelity and rollback_on_failure=True

    Notes
    -----
    Structural fidelity ≈ 1.0 indicates perfect coherence preservation.
    Fidelity > 1.0 is possible (reorganization increased coherence).
    Fidelity < min_fidelity indicates unacceptable coherence loss.

    Uses canonical TNFR coherence: C = 1/(1 + |ΔNFR|_mean + |dEPI|_mean)
    from tnfr.metrics.common module.
    """
    # Use canonical TNFR coherence computation
    from ..metrics.common import compute_coherence

    coherence_before = compute_coherence(G_before)
    coherence_after = compute_coherence(G_after)

    if coherence_before < 1e-10:
        # Edge case: network had no coherence to begin with
        return 1.0

    structural_fidelity = coherence_after / coherence_before

    if rollback_on_failure and structural_fidelity < min_fidelity:
        details = {
            "coherence_before": coherence_before,
            "coherence_after": coherence_after,
            "n_nodes_before": G_before.number_of_nodes(),
            "n_nodes_after": G_after.number_of_nodes(),
        }
        raise RemeshCoherenceLossError(structural_fidelity, min_fidelity, details)

    return structural_fidelity


# ==============================================================================
# Original Helper Functions
# ==============================================================================


def _as_float(value: Any, default: float = 0.0) -> float:
    """Best-effort conversion to ``float`` returning ``default`` on failure."""

    if value is None:
        return default
    try:
        return float(value)
    except (TypeError, ValueError):
        return default


def _ordered_edge(u: Hashable, v: Hashable) -> RemeshEdge:
    """Return a deterministic ordering for an undirected edge."""

    return (u, v) if repr(u) <= repr(v) else (v, u)


COOLDOWN_KEY = "REMESH_COOLDOWN_WINDOW"


@cache
def _get_networkx_modules() -> NetworkxModules:
    nx = cached_import("networkx")
    if nx is None:
        raise ImportError(
            "networkx is required for network operators; install 'networkx' "
            "to enable this feature"
        )
    nx_comm = cached_import("networkx.algorithms", "community")
    if nx_comm is None:
        raise ImportError(
            "networkx.algorithms.community is required for community-based "
            "operations; install 'networkx' to enable this feature"
        )
    return cast(NetworkxModule, nx), cast(CommunityModule, nx_comm)


def _remesh_alpha_info(G: CommunityGraph) -> tuple[float, str]:
    """Return ``(alpha, source)`` with explicit precedence."""
    if bool(G.graph.get("REMESH_ALPHA_HARD", REMESH_DEFAULTS["REMESH_ALPHA_HARD"])):
        val = _as_float(
            G.graph.get("REMESH_ALPHA", REMESH_DEFAULTS["REMESH_ALPHA"]),
            float(REMESH_DEFAULTS["REMESH_ALPHA"]),
        )
        return val, "REMESH_ALPHA"
    gf = G.graph.get("GLYPH_FACTORS", DEFAULTS.get("GLYPH_FACTORS", {}))
    if "REMESH_alpha" in gf:
        return _as_float(gf["REMESH_alpha"]), "GLYPH_FACTORS.REMESH_alpha"
    if "REMESH_ALPHA" in G.graph:
        return _as_float(G.graph["REMESH_ALPHA"]), "REMESH_ALPHA"
    return (
        float(REMESH_DEFAULTS["REMESH_ALPHA"]),
        "REMESH_DEFAULTS.REMESH_ALPHA",
    )


def _snapshot_topology(G: CommunityGraph, nx: NetworkxModule) -> str | None:
    """Return a hash representing the current graph topology."""
    try:
        n_nodes = G.number_of_nodes()
        n_edges = G.number_of_edges()
        degs = sorted(d for _, d in G.degree())
        topo_str = f"n={n_nodes};m={n_edges};deg=" + ",".join(map(str, degs))
        return hashlib.blake2b(topo_str.encode(), digest_size=6).hexdigest()
    except (AttributeError, TypeError, nx.NetworkXError):
        return None


def _snapshot_epi(G: CommunityGraph) -> tuple[float, str]:
    """Return ``(mean, checksum)`` of the node EPI values."""
    buf = StringIO()
    values = []
    for n, data in G.nodes(data=True):
        v = _as_float(get_attr(data, ALIAS_EPI, 0.0))
        values.append(v)
        buf.write(f"{str(n)}:{round(v, 6)};")
    total = kahan_sum_nd(((v,) for v in values), dims=1)[0]
    mean_val = total / len(values) if values else 0.0
    checksum = hashlib.blake2b(buf.getvalue().encode(), digest_size=6).hexdigest()
    return float(mean_val), checksum


def _log_remesh_event(G: CommunityGraph, meta: RemeshMeta) -> None:
    """Store remesh metadata and optionally log and trigger callbacks."""
    from ..glyph_history import append_metric
    from ..utils import CallbackEvent, callback_manager

    G.graph["_REMESH_META"] = meta
    if G.graph.get("REMESH_LOG_EVENTS", REMESH_DEFAULTS["REMESH_LOG_EVENTS"]):
        hist = G.graph.setdefault("history", {})
        append_metric(hist, "remesh_events", dict(meta))
    callback_manager.invoke_callbacks(G, CallbackEvent.ON_REMESH.value, dict(meta))


def apply_network_remesh(G: CommunityGraph) -> None:
    """Network-scale REMESH using ``_epi_hist`` with multi-scale memory."""
    from ..dynamics.structural_clip import structural_clip
    from ..glyph_history import current_step_idx, ensure_history

    nx, _ = _get_networkx_modules()
    tau_g = int(get_param(G, "REMESH_TAU_GLOBAL"))
    tau_l = int(get_param(G, "REMESH_TAU_LOCAL"))
    tau_req = max(tau_g, tau_l)
    alpha, alpha_src = _remesh_alpha_info(G)
    G.graph["_REMESH_ALPHA_SRC"] = alpha_src
    hist = G.graph.get("_epi_hist", deque())
    if len(hist) < tau_req + 1:
        return

    past_g = hist[-(tau_g + 1)]
    past_l = hist[-(tau_l + 1)]

    topo_hash = _snapshot_topology(G, nx)
    epi_mean_before, epi_checksum_before = _snapshot_epi(G)

    # Get EPI bounds for structural preservation
    epi_min = float(G.graph.get("EPI_MIN", DEFAULTS.get("EPI_MIN", -1.0)))
    epi_max = float(G.graph.get("EPI_MAX", DEFAULTS.get("EPI_MAX", 1.0)))
    clip_mode_str = str(G.graph.get("CLIP_MODE", "hard"))
    if clip_mode_str not in ("hard", "soft"):
        clip_mode_str = "hard"
    clip_mode = clip_mode_str  # type: ignore[assignment]

    for n, nd in G.nodes(data=True):
        epi_now = _as_float(get_attr(nd, ALIAS_EPI, 0.0))
        epi_old_l = _as_float(
            past_l.get(n) if isinstance(past_l, Mapping) else None, epi_now
        )
        epi_old_g = _as_float(
            past_g.get(n) if isinstance(past_g, Mapping) else None, epi_now
        )
        mixed = (1 - alpha) * epi_now + alpha * epi_old_l
        mixed = (1 - alpha) * mixed + alpha * epi_old_g

        # Apply structural boundary preservation to prevent overflow
        mixed_clipped = structural_clip(mixed, lo=epi_min, hi=epi_max, mode=clip_mode)
        set_attr(nd, ALIAS_EPI, mixed_clipped)

    epi_mean_after, epi_checksum_after = _snapshot_epi(G)

    step_idx = current_step_idx(G)
    meta: RemeshMeta = {
        "alpha": alpha,
        "alpha_source": alpha_src,
        "tau_global": tau_g,
        "tau_local": tau_l,
        "step": step_idx,
        "topo_hash": topo_hash,
        "epi_mean_before": float(epi_mean_before),
        "epi_mean_after": float(epi_mean_after),
        "epi_checksum_before": epi_checksum_before,
        "epi_checksum_after": epi_checksum_after,
    }

    h = ensure_history(G)
    if h:
        if h.get("stable_frac"):
            meta["stable_frac_last"] = h["stable_frac"][-1]
        if h.get("phase_sync"):
            meta["phase_sync_last"] = h["phase_sync"][-1]
        if h.get("glyph_load_disr"):
            meta["glyph_disr_last"] = h["glyph_load_disr"][-1]

    _log_remesh_event(G, meta)


def apply_network_remesh_with_memory(
    G: CommunityGraph,
    *,
    enable_structural_memory: bool = True,
    similarity_threshold: float = REMESH_SIMILARITY_THRESHOLD_CANONICAL,
    similarity_metric: str = "cosine",
    propagation_strength: float = 0.5,
    min_cluster_size: int = 2,
) -> None:
    """Apply REMESH with structural field memory activation.

    This extended version of REMESH implements the theoretical capability
    of "structural memory": nodes can recognize themselves in other nodes
    through pattern similarity, enabling coherent propagation across scales.

    The function performs:
    1. Standard REMESH reorganization (temporal EPI mixing)
    2. Pattern detection (find groups of structurally similar nodes)
    3. Identity propagation (reinforce shared patterns from origin nodes)

    Parameters
    ----------
    G : TNFRGraph
        Network to reorganize (modified in-place)
    enable_structural_memory : bool, default=True
        Whether to activate structural memory after standard REMESH.
        If False, performs only standard REMESH.
    similarity_threshold : float, default=0.75
        Minimum similarity [0-1] to recognize patterns as "same identity".
        Higher = stricter matching. Typical range: 0.7-0.9.
    similarity_metric : str, default='cosine'
        Metric for comparing structural signatures.
        Options: 'cosine', 'euclidean', 'correlation'
    propagation_strength : float, default=0.5
        Interpolation weight [0-1] for identity propagation.
        - 0.0: No propagation (structural memory detection only)
        - 0.5: Balanced blending (recommended)
        - 1.0: Full replacement (aggressive, may reduce diversity)
    min_cluster_size : int, default=2
        Minimum nodes required to form a recursive pattern.
        Single isolated nodes are not considered patterns.

    Notes
    -----
    **TNFR Physics**: This implements the principle that "coherence propagates
    structurally, not imposed" (TNFR.pdf § 4.2). Patterns that resonate across
    the network mutually reinforce through similarity-based coupling.

    **Workflow**:
    1. `apply_network_remesh(G)` - Standard temporal memory mixing
    2. `detect_recursive_patterns(G, threshold)` - Find similar node groups
    3. For each cluster:
       - `identify_pattern_origin(G, cluster)` - Find strongest instance
       - `propagate_structural_identity(G, origin, targets)` - Reinforce pattern

    **Telemetry**: Logs structural memory events to G.graph['history']['structural_memory_events']
    including cluster statistics and propagation metadata.

    **Canonical Relationships**:
    - Hierarchical REMESH: Combine with IL (coherence) for stable multi-level propagation
    - Rhizomatic REMESH: Combine with UM (coupling) for decentralized pattern spread
    - Fractal Harmonic: Combine with RA (resonance) for symmetric amplification

    Examples
    --------
    >>> # Standard REMESH with structural memory (recommended)
    >>> apply_network_remesh_with_memory(G)
    >>>
    >>> # Strict pattern matching with gentle propagation
    >>> apply_network_remesh_with_memory(
    ...     G,
    ...     similarity_threshold=0.85,
    ...     propagation_strength=0.3
    ... )
    >>>
    >>> # Disable structural memory (standard REMESH only)
    >>> apply_network_remesh_with_memory(G, enable_structural_memory=False)
    """
    # Phase 1: Apply standard REMESH (temporal memory)
    apply_network_remesh(G)

    if not enable_structural_memory:
        return

    # Phase 2: Structural memory - detect and propagate patterns
    try:
        # Detect recursive patterns across network
        clusters = detect_recursive_patterns(
            G,
            threshold=similarity_threshold,
            metric=similarity_metric,
            min_cluster_size=min_cluster_size,
        )

        # Propagate identity from origin to similar nodes
        propagation_events = []
        for cluster in clusters:
            if len(cluster) < min_cluster_size:
                continue

            # Identify strongest instance of pattern
            origin = identify_pattern_origin(G, cluster)
            if origin is None:
                continue

            # Propagate to other cluster members
            targets = [n for n in cluster if n != origin]
            if targets:
                propagate_structural_identity(
                    G,
                    origin,
                    targets,
                    propagation_strength=propagation_strength,
                )

                propagation_events.append(
                    {
                        "origin": origin,
                        "n_targets": len(targets),
                        "targets": targets[:5],  # Sample for telemetry (avoid bloat)
                    }
                )

        # Log structural memory event
        if G.graph.get("REMESH_LOG_EVENTS", REMESH_DEFAULTS["REMESH_LOG_EVENTS"]):
            from ..glyph_history import append_metric

            hist = G.graph.setdefault("history", {})
            append_metric(
                hist,
                "structural_memory_events",
                {
                    "n_clusters": len(clusters),
                    "cluster_sizes": [len(c) for c in clusters],
                    "n_propagations": len(propagation_events),
                    "propagation_events": propagation_events[:10],  # Sample
                    "similarity_threshold": similarity_threshold,
                    "similarity_metric": similarity_metric,
                    "propagation_strength": propagation_strength,
                    "min_cluster_size": min_cluster_size,
                },
            )

    except Exception as e:
        # Graceful degradation: if structural memory fails, REMESH still applied
        import warnings

        warnings.warn(
            f"Structural memory activation failed: {e}. "
            "Standard REMESH applied successfully.",
            RuntimeWarning,
            stacklevel=2,
        )


def _mst_edges_from_epi(
    nx: NetworkxModule,
    nodes: Sequence[Hashable],
    epi: Mapping[Hashable, float],
) -> set[RemeshEdge]:
    """Return MST edges based on absolute EPI distance."""
    H = nx.Graph()
    H.add_nodes_from(nodes)
    H.add_weighted_edges_from(
        (u, v, abs(epi[u] - epi[v])) for u, v in combinations(nodes, 2)
    )
    return {_ordered_edge(u, v) for u, v in nx.minimum_spanning_edges(H, data=False)}


def _knn_edges(
    nodes: Sequence[Hashable],
    epi: Mapping[Hashable, float],
    k_val: int,
    p_rewire: float,
    rnd: random.Random,
) -> set[RemeshEdge]:
    """Edges linking each node to its ``k`` nearest neighbours in EPI."""
    new_edges = set()
    node_set = set(nodes)
    for u in nodes:
        epi_u = epi[u]
        neighbours = [
            v
            for _, v in heapq.nsmallest(
                k_val,
                ((abs(epi_u - epi[v]), v) for v in nodes if v != u),
            )
        ]
        for v in neighbours:
            if rnd.random() < p_rewire:
                choices = list(node_set - {u, v})
                if choices:
                    v = rnd.choice(choices)
            new_edges.add(_ordered_edge(u, v))
    return new_edges


def _community_graph(
    comms: Iterable[Iterable[Hashable]],
    epi: Mapping[Hashable, float],
    nx: NetworkxModule,
) -> CommunityGraph:
    """Return community graph ``C`` with mean EPI per community."""
    C = nx.Graph()
    for idx, comm in enumerate(comms):
        members = list(comm)
        try:
            epi_mean = fmean(_as_float(epi.get(n)) for n in members)
        except StatisticsError:
            epi_mean = 0.0
        C.add_node(idx)
        set_attr(C.nodes[idx], ALIAS_EPI, epi_mean)
        C.nodes[idx]["members"] = members
    for i, j in combinations(C.nodes(), 2):
        w = abs(
            _as_float(get_attr(C.nodes[i], ALIAS_EPI, 0.0))
            - _as_float(get_attr(C.nodes[j], ALIAS_EPI, 0.0))
        )
        C.add_edge(i, j, weight=w)
    return cast(CommunityGraph, C)


def _community_k_neighbor_edges(
    C: CommunityGraph,
    k_val: int,
    p_rewire: float,
    rnd: random.Random,
) -> tuple[set[RemeshEdge], dict[int, int], list[tuple[int, int, int]]]:
    """Edges linking each community to its ``k`` nearest neighbours."""
    epi_vals = {n: _as_float(get_attr(C.nodes[n], ALIAS_EPI, 0.0)) for n in C.nodes()}
    ordered = sorted(C.nodes(), key=lambda v: epi_vals[v])
    new_edges = set()
    attempts = {n: 0 for n in C.nodes()}
    rewired = []
    node_set = set(C.nodes())
    for idx, u in enumerate(ordered):
        epi_u = epi_vals[u]
        left = idx - 1
        right = idx + 1
        added = 0
        while added < k_val and (left >= 0 or right < len(ordered)):
            if left < 0:
                v = ordered[right]
                right += 1
            elif right >= len(ordered):
                v = ordered[left]
                left -= 1
            else:
                if abs(epi_u - epi_vals[ordered[left]]) <= abs(
                    epi_vals[ordered[right]] - epi_u
                ):
                    v = ordered[left]
                    left -= 1
                else:
                    v = ordered[right]
                    right += 1
            original_v = v
            rewired_now = False
            if rnd.random() < p_rewire:
                choices = list(node_set - {u, original_v})
                if choices:
                    v = rnd.choice(choices)
                    rewired_now = True
            new_edges.add(_ordered_edge(u, v))
            attempts[u] += 1
            if rewired_now:
                rewired.append((u, original_v, v))
            added += 1
    return new_edges, attempts, rewired


def _community_remesh(
    G: CommunityGraph,
    epi: Mapping[Hashable, float],
    k_val: int,
    p_rewire: float,
    rnd: random.Random,
    nx: NetworkxModule,
    nx_comm: CommunityModule,
    mst_edges: Iterable[RemeshEdge],
    n_before: int,
) -> None:
    """Remesh ``G`` replacing nodes by modular communities."""
    from ..glyph_history import append_metric

    comms = list(nx_comm.greedy_modularity_communities(G))
    if len(comms) <= 1:
        with edge_version_update(G):
            G.clear_edges()
            G.add_edges_from(mst_edges)
        return
    C = _community_graph(comms, epi, nx)
    mst_c = nx.minimum_spanning_tree(C, weight="weight")
    new_edges: set[RemeshEdge] = {_ordered_edge(u, v) for u, v in mst_c.edges()}
    extra_edges, attempts, rewired_edges = _community_k_neighbor_edges(
        C, k_val, p_rewire, rnd
    )
    new_edges |= extra_edges

    extra_degrees = {idx: 0 for idx in C.nodes()}
    for u, v in extra_edges:
        extra_degrees[u] += 1
        extra_degrees[v] += 1

    with edge_version_update(G):
        G.clear_edges()
        G.remove_nodes_from(list(G.nodes()))
        for idx in C.nodes():
            data = dict(C.nodes[idx])
            G.add_node(idx, **data)
        G.add_edges_from(new_edges)

    if G.graph.get("REMESH_LOG_EVENTS", REMESH_DEFAULTS["REMESH_LOG_EVENTS"]):
        hist = G.graph.setdefault("history", {})
        mapping = {idx: C.nodes[idx].get("members", []) for idx in C.nodes()}
        append_metric(
            hist,
            "remesh_events",
            {
                "mode": "community",
                "n_before": n_before,
                "n_after": G.number_of_nodes(),
                "mapping": mapping,
                "k": int(k_val),
                "p_rewire": float(p_rewire),
                "extra_edges_added": len(extra_edges),
                "extra_edge_attempts": attempts,
                "extra_edge_degrees": extra_degrees,
                "rewired_edges": [
                    {"source": int(u), "from": int(v0), "to": int(v1)}
                    for u, v0, v1 in rewired_edges
                ],
            },
        )


def apply_topological_remesh(
    G: CommunityGraph,
    mode: str | None = None,
    *,
    k: int | None = None,
    p_rewire: float = 0.2,
    seed: int | None = None,
) -> None:
    """Approximate topological remeshing.

    When ``seed`` is ``None`` the RNG draws its base seed from
    ``G.graph['RANDOM_SEED']`` to keep runs reproducible.
    """
    nodes = list(G.nodes())
    n_before = len(nodes)
    if n_before <= 1:
        return
    if seed is None:
        base_seed = int(G.graph.get("RANDOM_SEED", 0))
    else:
        base_seed = int(seed)
    rnd = make_rng(base_seed, -2, G)

    if mode is None:
        mode = str(
            G.graph.get("REMESH_MODE", REMESH_DEFAULTS.get("REMESH_MODE", "knn"))
        )
    mode = str(mode)
    nx, nx_comm = _get_networkx_modules()
    epi = {n: _as_float(get_attr(G.nodes[n], ALIAS_EPI, 0.0)) for n in nodes}
    mst_edges = _mst_edges_from_epi(nx, nodes, epi)
    default_k = int(
        G.graph.get("REMESH_COMMUNITY_K", REMESH_DEFAULTS.get("REMESH_COMMUNITY_K", 2))
    )
    k_val = max(1, int(k) if k is not None else default_k)

    if mode == "community":
        _community_remesh(
            G,
            epi,
            k_val,
            p_rewire,
            rnd,
            nx,
            nx_comm,
            mst_edges,
            n_before,
        )
        return

    new_edges = set(mst_edges)
    if mode == "knn":
        new_edges |= _knn_edges(nodes, epi, k_val, p_rewire, rnd)

    with edge_version_update(G):
        G.clear_edges()
        G.add_edges_from(new_edges)


def _extra_gating_ok(
    hist: MutableMapping[str, Sequence[float]],
    cfg: Mapping[str, RemeshConfigValue],
    w_estab: int,
) -> bool:
    """Check additional stability gating conditions."""
    checks = [
        ("phase_sync", "REMESH_MIN_PHASE_SYNC", ge),
        ("glyph_load_disr", "REMESH_MAX_GLYPH_DISR", le),
        ("sense_sigma_mag", "REMESH_MIN_SIGMA_MAG", ge),
        ("kuramoto_R", "REMESH_MIN_KURAMOTO_R", ge),
        ("Si_hi_frac", "REMESH_MIN_SI_HI_FRAC", ge),
    ]
    for hist_key, cfg_key, op in checks:
        series = hist.get(hist_key)
        if series is not None and len(series) >= w_estab:
            win = series[-w_estab:]
            avg = sum(win) / len(win)
            threshold = _as_float(cfg[cfg_key])
            if not op(avg, threshold):
                return False
    return True


def apply_remesh_if_globally_stable(
    G: CommunityGraph,
    stable_step_window: int | None = None,
    **kwargs: Any,
) -> None:
    """Trigger remeshing when global stability indicators satisfy thresholds."""

    from ..glyph_history import ensure_history

    if kwargs:
        unexpected = ", ".join(sorted(kwargs))
        raise TypeError(
            "apply_remesh_if_globally_stable() got unexpected keyword argument(s): "
            f"{unexpected}"
        )

    params = [
        (
            "REMESH_STABILITY_WINDOW",
            int,
            REMESH_DEFAULTS["REMESH_STABILITY_WINDOW"],
        ),
        (
            "REMESH_REQUIRE_STABILITY",
            bool,
            REMESH_DEFAULTS["REMESH_REQUIRE_STABILITY"],
        ),
        (
            "REMESH_MIN_PHASE_SYNC",
            float,
            REMESH_DEFAULTS["REMESH_MIN_PHASE_SYNC"],
        ),
        (
            "REMESH_MAX_GLYPH_DISR",
            float,
            REMESH_DEFAULTS["REMESH_MAX_GLYPH_DISR"],
        ),
        (
            "REMESH_MIN_SIGMA_MAG",
            float,
            REMESH_DEFAULTS["REMESH_MIN_SIGMA_MAG"],
        ),
        (
            "REMESH_MIN_KURAMOTO_R",
            float,
            REMESH_DEFAULTS["REMESH_MIN_KURAMOTO_R"],
        ),
        (
            "REMESH_MIN_SI_HI_FRAC",
            float,
            REMESH_DEFAULTS["REMESH_MIN_SI_HI_FRAC"],
        ),
        (COOLDOWN_KEY, int, REMESH_DEFAULTS[COOLDOWN_KEY]),
        ("REMESH_COOLDOWN_TS", float, REMESH_DEFAULTS["REMESH_COOLDOWN_TS"]),
    ]
    cfg = {}
    for key, conv, _default in params:
        cfg[key] = conv(get_param(G, key))
    frac_req = _as_float(get_param(G, "FRACTION_STABLE_REMESH"))
    w_estab = (
        stable_step_window
        if stable_step_window is not None
        else cfg["REMESH_STABILITY_WINDOW"]
    )

    hist = ensure_history(G)
    sf = hist.setdefault("stable_frac", [])
    if len(sf) < w_estab:
        return
    win_sf = sf[-w_estab:]
    if not all(v >= frac_req for v in win_sf):
        return
    if cfg["REMESH_REQUIRE_STABILITY"] and not _extra_gating_ok(hist, cfg, w_estab):
        return

    last = G.graph.get("_last_remesh_step", -(10**9))
    step_idx = len(sf)
    if step_idx - last < cfg[COOLDOWN_KEY]:
        return
    t_now = _as_float(G.graph.get("_t", 0.0))
    last_ts = _as_float(G.graph.get("_last_remesh_ts", -1e12))
    if cfg["REMESH_COOLDOWN_TS"] > 0 and (t_now - last_ts) < cfg["REMESH_COOLDOWN_TS"]:
        return

    apply_network_remesh(G)
    G.graph["_last_remesh_step"] = step_idx
    G.graph["_last_remesh_ts"] = t_now


__all__ = [
    # Core remesh functions (existing API)
    "apply_network_remesh",
    "apply_topological_remesh",
    "apply_remesh_if_globally_stable",
    # Phase 1: Structural memory & pattern recognition
    "StructuralIdentity",
    "structural_similarity",
    "structural_memory_match",
    "compute_structural_signature",
    "detect_recursive_patterns",
    "identify_pattern_origin",
    "propagate_structural_identity",
    "apply_network_remesh_with_memory",
    # Phase 2: Coherence preservation & validation
    "RemeshCoherenceLossError",
    "validate_coherence_preservation",
]