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/health_analyzer.py

health_analyzer.py

Structural health metrics analyzer for TNFR operator sequences.

Provides quantitative assessment of sequence structural quality through canonical TNFR metrics: coherence, balance, sustainability, and efficiency.

Source Code

python
"""Structural health metrics analyzer for TNFR operator sequences.

Provides quantitative assessment of sequence structural quality through
canonical TNFR metrics: coherence, balance, sustainability, and efficiency.
"""

from __future__ import annotations

from functools import lru_cache
from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
    from ..types import TNFRGraph

from ..compat.dataclass import dataclass
from ..config.operator_names import (
    BIFURCATION_WINDOW,
    COHERENCE,
    DESTABILIZERS,
    DISSONANCE,
    RECURSIVITY,
    RESONANCE,
    SELF_ORGANIZATION,
    SILENCE,
    TRANSFORMERS,
    TRANSITION,
)
from ..constants.canonical import THOL_MIN_COLLECTIVE_COHERENCE

__all__ = [
    "SequenceHealthMetrics",
    "SequenceHealthAnalyzer",
]

# Import canonical stabilizer set from grammar_types (single source of truth)
from .grammar_types import STABILIZERS as _GRAMMAR_STABILIZERS

# Extended stabilizers for health analysis include silence & resonance (defensive)
_STABILIZERS = _GRAMMAR_STABILIZERS | frozenset({SILENCE, RESONANCE})
_REGENERATORS = frozenset({TRANSITION, RECURSIVITY})  # NAV, REMESH


@dataclass
class SequenceHealthMetrics:
    """Structural health metrics for a TNFR operator sequence.

    All metrics range from 0.0 (poor) to 1.0 (excellent), measuring different
    aspects of sequence structural quality according to TNFR principles.

    Attributes
    ----------
    coherence_index : float
        Global sequential flow quality (0.0-1.0). Measures how well operators
        transition and whether the sequence forms a recognizable pattern.
    balance_score : float
        Equilibrium between stabilizers and destabilizers (0.0-1.0). Ideal
        sequences have balanced structural forces.
    sustainability_index : float
        Capacity for long-term maintenance (0.0-1.0). Considers final stabilization,
        resolved dissonance, and regenerative elements.
    complexity_efficiency : float
        Value-to-complexity ratio (0.0-1.0). Penalizes unnecessarily long sequences
        that don't provide proportional structural value.
    frequency_harmony : float
        Structural frequency transition smoothness (0.0-1.0). High when transitions
        respect νf harmonics.
    pattern_completeness : float
        How complete the detected pattern is (0.0-1.0). Full cycles score higher.
    transition_smoothness : float
        Quality of operator transitions (0.0-1.0). Measures valid transitions vs
        total transitions.
    overall_health : float
        Composite health index (0.0-1.0). Weighted average of primary metrics.
    sequence_length : int
        Number of operators in the sequence.
    dominant_pattern : str
        Detected structural pattern type (e.g., "activation", "therapeutic", "unknown").
    recommendations : list[str]
        Specific suggestions for improving sequence health.
    """

    coherence_index: float
    balance_score: float
    sustainability_index: float
    complexity_efficiency: float
    frequency_harmony: float
    pattern_completeness: float
    transition_smoothness: float
    overall_health: float
    sequence_length: int
    dominant_pattern: str
    recommendations: list[str]


class SequenceHealthAnalyzer:
    """Analyzer for structural health of TNFR operator sequences.

    Evaluates sequences along multiple dimensions to provide quantitative
    assessment of structural quality, coherence, and sustainability.

    Uses caching to optimize repeated analysis of identical sequences,
    which is common in pattern exploration and batch validation workflows.

    Examples
    --------
    >>> from tnfr.operators.health_analyzer import SequenceHealthAnalyzer
    >>> analyzer = SequenceHealthAnalyzer()
    >>> sequence = ["emission", "reception", "coherence", "silence"]
    >>> health = analyzer.analyze_health(sequence)
    >>> health.overall_health
    0.82
    >>> health.recommendations
    []
    """

    def __init__(self) -> None:
        """Initialize the health analyzer with caching support."""
        self._recommendations: list[str] = []
        # Cache for single-pass analysis results keyed by sequence tuple
        # Using maxsize=128 to avoid unbounded growth while caching common sequences
        self._analysis_cache = lru_cache(maxsize=128)(self._compute_single_pass)

    def _compute_single_pass(
        self, sequence_tuple: tuple[str, ...]
    ) -> tuple[int, int, int, int, int, list[tuple[str, str]]]:
        """Compute sequence statistics in a single pass for efficiency.

        This method scans the sequence once and extracts all the information
        needed for the various health metrics, avoiding redundant iterations.

        Parameters
        ----------
        sequence_tuple : tuple[str, ...]
            Immutable sequence of operators (tuple for hashability in cache).

        Returns
        -------
        tuple containing:
            - stabilizer_count: int
            - destabilizer_count: int
            - transformer_count: int
            - regenerator_count: int
            - unique_ops: int
            - problematic_transitions: list[(op1, op2)] pairs

        Notes
        -----
        This function is cached using lru_cache to optimize repeated analysis
        of identical sequences, which is common in batch validation and
        pattern exploration workflows.
        """
        sequence = list(sequence_tuple)

        # Initialize counters
        stabilizer_count = 0
        destabilizer_count = 0
        transformer_count = 0
        regenerator_count = 0
        unique_ops_set = set()
        problematic_transitions = []

        # Single pass through sequence
        for i, op in enumerate(sequence):
            unique_ops_set.add(op)

            # Count operator categories
            if op in _STABILIZERS:
                stabilizer_count += 1
            if op in DESTABILIZERS:
                destabilizer_count += 1
            if op in TRANSFORMERS:
                transformer_count += 1
            if op in _REGENERATORS:
                regenerator_count += 1

            # Check transitions
            if i < len(sequence) - 1:
                next_op = sequence[i + 1]
                # Destabilizer → destabilizer is problematic
                if op in DESTABILIZERS and next_op in DESTABILIZERS:
                    problematic_transitions.append((op, next_op))

        return (
            stabilizer_count,
            destabilizer_count,
            transformer_count,
            regenerator_count,
            len(unique_ops_set),
            problematic_transitions,
        )

    def analyze_health(self, sequence: list[str]) -> SequenceHealthMetrics:
        """Perform complete structural health analysis of a sequence.

        Parameters
        ----------
        sequence : list[str]
            Operator sequence to analyze (canonical names like "emission", "coherence").

        Returns
        -------
        SequenceHealthMetrics
            Comprehensive health metrics for the sequence.

        Examples
        --------
        >>> analyzer = SequenceHealthAnalyzer()
        >>> health = analyzer.analyze_health(["emission", "reception", "coherence", "silence"])
        >>> health.coherence_index > 0.7
        True
        """
        self._recommendations = []

        # Use single-pass analysis for efficiency (cached)
        sequence_tuple = tuple(sequence)
        analysis = self._analysis_cache(sequence_tuple)

        # Extract results from single-pass analysis
        (
            stabilizer_count,
            destabilizer_count,
            transformer_count,
            regenerator_count,
            unique_count,
            problematic_transitions,
        ) = analysis

        coherence = self._calculate_coherence(sequence, problematic_transitions)
        balance = self._calculate_balance(
            sequence, stabilizer_count, destabilizer_count
        )
        sustainability = self._calculate_sustainability(
            sequence, stabilizer_count, destabilizer_count, regenerator_count
        )
        efficiency = self._calculate_efficiency(sequence, unique_count)
        frequency = self._calculate_frequency_harmony(sequence)
        completeness = self._calculate_completeness(
            sequence, stabilizer_count, destabilizer_count, transformer_count
        )
        smoothness = self._calculate_smoothness(sequence, problematic_transitions)

        # Calculate overall health as weighted average
        # Primary metrics weighted more heavily
        overall = (
            coherence * 0.20
            + balance * 0.20
            + sustainability * 0.20
            + efficiency * 0.15
            + frequency * 0.10
            + completeness * 0.10
            + smoothness * 0.05
        )

        pattern = self._detect_pattern(sequence)

        return SequenceHealthMetrics(
            coherence_index=coherence,
            balance_score=balance,
            sustainability_index=sustainability,
            complexity_efficiency=efficiency,
            frequency_harmony=frequency,
            pattern_completeness=completeness,
            transition_smoothness=smoothness,
            overall_health=overall,
            sequence_length=len(sequence),
            dominant_pattern=pattern,
            recommendations=self._recommendations.copy(),
        )

    def _calculate_coherence(
        self, sequence: list[str], problematic_transitions: list[tuple[str, str]]
    ) -> float:
        """Calculate coherence index: how well the sequence flows.

        Factors:
        - Valid transitions between operators
        - Recognizable pattern structure
        - Structural closure (proper ending)

        Parameters
        ----------
        sequence : list[str]
            Operator sequence
        problematic_transitions : list[tuple[str, str]]
            Pre-computed list of problematic transition pairs

        Returns
        -------
        float
            Coherence score (0.0-1.0)
        """
        if not sequence:
            return 0.0

        # Transition quality: use pre-computed problematic transitions
        if len(sequence) < 2:
            transition_quality = 1.0
        else:
            total_transitions = len(sequence) - 1
            # Each problematic transition gets 0.5 penalty
            penalty = len(problematic_transitions) * 0.5
            transition_quality = max(0.0, 1.0 - (penalty / total_transitions))

        # Pattern clarity: does it form a recognizable structure?
        pattern_clarity = self._assess_pattern_clarity(sequence)

        # Structural closure: does it end properly?
        structural_closure = self._assess_closure(sequence)

        return (transition_quality + pattern_clarity + structural_closure) / 3.0

    def _calculate_balance(
        self, sequence: list[str], stabilizer_count: int, destabilizer_count: int
    ) -> float:
        """Calculate balance score: equilibrium between stabilizers and destabilizers.

        Ideal sequences have roughly equal stabilization and transformation forces.
        Severe imbalance reduces structural health.

        Parameters
        ----------
        sequence : list[str]
            Operator sequence
        stabilizer_count : int
            Pre-computed count of stabilizing operators
        destabilizer_count : int
            Pre-computed count of destabilizing operators

        Returns
        -------
        float
            Balance score (0.0-1.0)
        """
        if not sequence:
            return 0.5  # Neutral for empty

        # If neither present, neutral balance
        if stabilizer_count == 0 and destabilizer_count == 0:
            return 0.5

        # Calculate ratio: closer to 1.0 means better balance
        max_count = max(stabilizer_count, destabilizer_count)
        min_count = min(stabilizer_count, destabilizer_count)

        if max_count == 0:
            return 0.5

        ratio = min_count / max_count

        # Penalize severe imbalance (difference > half the sequence length)
        imbalance = abs(stabilizer_count - destabilizer_count)
        if imbalance > len(sequence) // 2:
            ratio *= 0.7  # Apply penalty
            self._recommendations.append(
                "Severe imbalance detected: add stabilizers or reduce destabilizers"
            )

        return ratio

    def _calculate_sustainability(
        self,
        sequence: list[str],
        stabilizer_count: int,
        destabilizer_count: int,
        regenerator_count: int,
    ) -> float:
        """Calculate sustainability index: capacity to maintain without collapse.

        Factors:
        - Final operator is a stabilizer
        - Dissonance is resolved (not left unbalanced)
        - Contains regenerative elements

        Parameters
        ----------
        sequence : list[str]
            Operator sequence
        stabilizer_count : int
            Pre-computed count of stabilizing operators
        destabilizer_count : int
            Pre-computed count of destabilizing operators
        regenerator_count : int
            Pre-computed count of regenerative operators

        Returns
        -------
        float
            Sustainability score (0.0-1.0)
        """
        if not sequence:
            return 0.0

        sustainability = 0.0

        # Factor 1: Ends with stabilizer (0.4 points)
        has_final_stabilizer = sequence[-1] in _STABILIZERS
        if has_final_stabilizer:
            sustainability += 0.4
        else:
            sustainability += 0.1  # Some credit for other endings
            self._recommendations.append(
                "Consider ending with a stabilizer (coherence, silence, resonance, or self_organization)"
            )

        # Factor 2: Resolved dissonance (0.3 points)
        unresolved_dissonance = self._count_unresolved_dissonance(sequence)
        if unresolved_dissonance == 0:
            sustainability += 0.3
        else:
            penalty = min(0.3, unresolved_dissonance * 0.1)
            sustainability += max(0, 0.3 - penalty)
            if unresolved_dissonance > 1:
                self._recommendations.append(
                    "Multiple unresolved dissonances detected: add stabilizers after destabilizing operators"
                )

        # Factor 3: Regenerative elements (0.3 points)
        # Use pre-computed regenerator count
        if regenerator_count > 0:
            sustainability += 0.3
        else:
            sustainability += 0.1  # Some credit even without

        return min(1.0, sustainability)

    def _calculate_efficiency(self, sequence: list[str], unique_count: int) -> float:
        """Calculate complexity efficiency: value achieved relative to length.

        Penalizes unnecessarily long sequences that don't provide proportional value.

        Parameters
        ----------
        sequence : list[str]
            Operator sequence
        unique_count : int
            Pre-computed count of unique operators in sequence

        Returns
        -------
        float
            Efficiency score (0.0-1.0)
        """
        if not sequence:
            return 0.0

        # Note: We call _assess_pattern_value for category coverage
        # This is minimal overhead as it's a single pass checking set memberships
        pattern_value = self._assess_pattern_value_optimized(sequence, unique_count)

        # Length penalty: sequences longer than 10 operators get penalized
        # Optimal range is 3-8 operators
        length = len(sequence)
        if length < 3:
            length_factor = 0.7  # Too short, limited value
        elif length <= 8:
            length_factor = 1.0  # Optimal range
        else:
            # Gradual penalty for length > 8
            excess = length - 8
            length_factor = max(0.5, 1.0 - (excess * 0.05))

        if length > 12:
            self._recommendations.append(
                f"Sequence is long ({length} operators): consider breaking into sub-sequences"
            )

        return pattern_value * length_factor

    def _calculate_frequency_harmony(self, sequence: list[str]) -> float:
        """Calculate frequency harmony: smoothness of νf transitions.

        Note: Full implementation requires integration with STRUCTURAL_FREQUENCIES
        and FREQUENCY_TRANSITIONS from the grammar module. Currently returns
        a conservative estimate based on transition patterns.

        Parameters
        ----------
        sequence : list[str]
            Operator sequence

        Returns
        -------
        float
            Harmony score (0.0-1.0)
        """
        # Conservative estimate: assume good harmony unless obvious issues detected
        # Future enhancement: integrate with grammar.STRUCTURAL_FREQUENCIES
        return 0.85

    def _calculate_completeness(
        self,
        sequence: list[str],
        stabilizer_count: int,
        destabilizer_count: int,
        transformer_count: int,
    ) -> float:
        """Calculate pattern completeness: how complete the pattern is.

        Complete patterns (with activation, transformation, stabilization) score higher.

        Parameters
        ----------
        sequence : list[str]
            Operator sequence
        stabilizer_count : int
            Pre-computed count of stabilizing operators
        destabilizer_count : int
            Pre-computed count of destabilizing operators
        transformer_count : int
            Pre-computed count of transforming operators

        Returns
        -------
        float
            Completeness score (0.0-1.0)
        """
        if not sequence:
            return 0.0

        # Check for key phases using pre-computed counts and minimal checks
        has_activation = any(op in {"emission", "reception"} for op in sequence)
        has_transformation = destabilizer_count > 0 or transformer_count > 0
        has_stabilization = stabilizer_count > 0
        has_completion = any(op in {"silence", "transition"} for op in sequence)

        phase_count = sum(
            [has_activation, has_transformation, has_stabilization, has_completion]
        )

        # All 4 phases = 1.0, 3 phases = 0.75, 2 phases = 0.5, 1 phase = 0.25
        return phase_count / 4.0

    def _calculate_smoothness(
        self, sequence: list[str], problematic_transitions: list[tuple[str, str]]
    ) -> float:
        """Calculate transition smoothness: quality of operator transitions.

        Measures ratio of valid/smooth transitions vs total transitions.

        Parameters
        ----------
        sequence : list[str]
            Operator sequence
        problematic_transitions : list[tuple[str, str]]
            Pre-computed list of problematic transition pairs

        Returns
        -------
        float
            Smoothness score (0.0-1.0)
        """
        if len(sequence) < 2:
            return 1.0  # No transitions to assess

        total_transitions = len(sequence) - 1
        # Each problematic transition gets 0.5 penalty (same as in _calculate_coherence)
        penalty = len(problematic_transitions) * 0.5
        return max(0.0, 1.0 - (penalty / total_transitions))

    def _assess_pattern_clarity(self, sequence: list[str]) -> float:
        """Assess how clearly the sequence forms a recognizable pattern.

        Parameters
        ----------
        sequence : list[str]
            Operator sequence

        Returns
        -------
        float
            Pattern clarity score (0.0-1.0)
        """
        if len(sequence) < 3:
            return 0.5  # Too short for clear pattern

        # Check for canonical patterns
        pattern = self._detect_pattern(sequence)

        if pattern in {"activation", "therapeutic", "regenerative", "transformative"}:
            return 0.9  # Clear, recognized pattern
        elif pattern in {"stabilization", "exploratory"}:
            return 0.7  # Recognizable but simpler
        else:
            return 0.5  # No clear pattern

    def _assess_closure(self, sequence: list[str]) -> float:
        """Assess structural closure quality.

        Parameters
        ----------
        sequence : list[str]
            Operator sequence

        Returns
        -------
        float
            Closure quality score (0.0-1.0)
        """
        if not sequence:
            return 0.0

        # Valid endings per grammar
        valid_endings = {SILENCE, TRANSITION, RECURSIVITY, DISSONANCE}

        if sequence[-1] in valid_endings:
            # Stabilizer endings are best
            if sequence[-1] in _STABILIZERS:
                return 1.0
            # Other valid endings are good
            return 0.8

        # Invalid ending
        return 0.3

    def _count_unresolved_dissonance(self, sequence: list[str]) -> int:
        """Count destabilizers not followed by stabilizers within reasonable window.

        Parameters
        ----------
        sequence : list[str]
            Operator sequence

        Returns
        -------
        int
            Count of unresolved dissonant operators
        """
        unresolved = 0
        # The destabilizer-resolution reach is the structural-relaxation window
        # BIFURCATION_WINDOW (topology-independent; a destabilizer not
        # compensated within it has either relaxed or diverged per U2).
        window = BIFURCATION_WINDOW

        for i, op in enumerate(sequence):
            if op in DESTABILIZERS:
                # Check if a stabilizer appears in the next 'window' operators
                lookahead = sequence[i + 1 : i + 1 + window]
                if not any(stabilizer in _STABILIZERS for stabilizer in lookahead):
                    unresolved += 1

        return unresolved

    def _assess_pattern_value_optimized(
        self, sequence: list[str], unique_count: int
    ) -> float:
        """Assess the structural value of the pattern using pre-computed unique count.

        Value is higher when:
        - Multiple operator types present (diversity)
        - Key structural phases are included
        - Balance between forces

        Parameters
        ----------
        sequence : list[str]
            Operator sequence
        unique_count : int
            Pre-computed count of unique operators in sequence

        Returns
        -------
        float
            Pattern value score (0.0-1.0)
        """
        if not sequence:
            return 0.0

        # Diversity: use pre-computed unique count
        diversity_score = min(
            1.0, unique_count / 6.0
        )  # 6+ operators is excellent diversity

        # Coverage: how many operator categories are represented
        # This is still a minimal single-pass check
        categories_present = 0
        if any(op in {"emission", "reception"} for op in sequence):
            categories_present += 1  # Activation
        if any(op in _STABILIZERS for op in sequence):
            categories_present += 1  # Stabilization
        if any(op in DESTABILIZERS for op in sequence):
            categories_present += 1  # Destabilization
        if any(op in TRANSFORMERS for op in sequence):
            categories_present += 1  # Transformation

        coverage_score = categories_present / 4.0

        # Combine factors
        return (diversity_score * 0.5) + (coverage_score * 0.5)

    def _detect_pattern(self, sequence: list[str]) -> str:
        """Detect the dominant structural pattern type.

        Parameters
        ----------
        sequence : list[str]
            Operator sequence

        Returns
        -------
        str
            Pattern name (e.g., "activation", "therapeutic", "unknown")
        """
        if not sequence:
            return "empty"

        # Check for common patterns
        starts_with_emission = sequence[0] == "emission"
        has_reception = "reception" in sequence
        has_coherence = COHERENCE in sequence
        has_dissonance = DISSONANCE in sequence
        has_self_org = SELF_ORGANIZATION in sequence
        has_regenerator = any(op in _REGENERATORS for op in sequence)

        # Pattern detection logic
        if starts_with_emission and has_reception and has_coherence:
            if has_dissonance and has_self_org:
                return "therapeutic"
            elif has_regenerator:
                return "regenerative"
            else:
                return "activation"

        if has_dissonance and has_self_org:
            return "transformative"

        if sum(1 for op in sequence if op in _STABILIZERS) > len(sequence) // 2:
            return "stabilization"

        if sum(1 for op in sequence if op in DESTABILIZERS) > len(sequence) // 2:
            return "exploratory"

        return "unknown"

    def analyze_thol_coherence(self, G: TNFRGraph) -> dict[str, Any] | None:
        """Analyze collective coherence of THOL bifurcations across the network.

        Examines all nodes that have undergone THOL bifurcation and provides
        statistics on their collective coherence metrics.

        Parameters
        ----------
        G : TNFRGraph
            Graph containing nodes with potential THOL bifurcations

        Returns
        -------
        dict or None
            Dictionary containing coherence statistics:
            - mean_coherence: Average coherence across all THOL nodes
            - min_coherence: Lowest coherence value observed
            - max_coherence: Highest coherence value observed
            - nodes_below_threshold: Count of nodes with coherence < 0.3
            - total_thol_nodes: Total nodes with sub-EPIs
            Returns None if no THOL bifurcations exist in the network.

        Notes
        -----
        TNFR Principle: Collective coherence measures the structural alignment
        of emergent sub-EPIs. Low coherence may indicate chaotic fragmentation
        rather than controlled emergence.

        This metric is particularly useful for:
        - Detecting pathological bifurcation patterns
        - Monitoring network-wide self-organization quality
        - Identifying nodes requiring stabilization

        Examples
        --------
        >>> analyzer = SequenceHealthAnalyzer()
        >>> # After running THOL operations on graph G
        >>> coherence_stats = analyzer.analyze_thol_coherence(G)
        >>> if coherence_stats:
        ...     print(f"Mean coherence: {coherence_stats['mean_coherence']:.3f}")
        ...     print(f"Nodes below threshold: {coherence_stats['nodes_below_threshold']}")
        """
        # Find all nodes with sub-EPIs (THOL bifurcation occurred)
        thol_nodes = []
        for node in G.nodes():
            if G.nodes[node].get("sub_epis"):
                thol_nodes.append(node)

        if not thol_nodes:
            return None

        # Collect coherence values
        coherences = []
        for node in thol_nodes:
            coh = G.nodes[node].get("_thol_collective_coherence")
            if coh is not None:
                coherences.append(coh)

        if not coherences:
            return None

        # Compute statistics
        mean_coherence = sum(coherences) / len(coherences)
        min_coherence = min(coherences)
        max_coherence = max(coherences)

        # Get threshold from graph config (fallback: canonical 1/(π+1) ≈ 0.2415)
        threshold = float(
            G.graph.get("THOL_MIN_COLLECTIVE_COHERENCE", THOL_MIN_COLLECTIVE_COHERENCE)
        )
        nodes_below_threshold = sum(1 for c in coherences if c < threshold)

        return {
            "mean_coherence": mean_coherence,
            "min_coherence": min_coherence,
            "max_coherence": max_coherence,
            "nodes_below_threshold": nodes_below_threshold,
            "total_thol_nodes": len(thol_nodes),
            "threshold": threshold,
        }