tnfr 4.5.2__py3-none-any.whl → 8.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of tnfr might be problematic. Click here for more details.

Files changed (365) hide show
  1. tnfr/__init__.py +334 -50
  2. tnfr/__init__.pyi +33 -0
  3. tnfr/_compat.py +10 -0
  4. tnfr/_generated_version.py +34 -0
  5. tnfr/_version.py +49 -0
  6. tnfr/_version.pyi +7 -0
  7. tnfr/alias.py +214 -37
  8. tnfr/alias.pyi +108 -0
  9. tnfr/backends/__init__.py +354 -0
  10. tnfr/backends/jax_backend.py +173 -0
  11. tnfr/backends/numpy_backend.py +238 -0
  12. tnfr/backends/optimized_numpy.py +420 -0
  13. tnfr/backends/torch_backend.py +408 -0
  14. tnfr/cache.py +149 -556
  15. tnfr/cache.pyi +13 -0
  16. tnfr/cli/__init__.py +51 -16
  17. tnfr/cli/__init__.pyi +26 -0
  18. tnfr/cli/arguments.py +344 -32
  19. tnfr/cli/arguments.pyi +29 -0
  20. tnfr/cli/execution.py +676 -50
  21. tnfr/cli/execution.pyi +70 -0
  22. tnfr/cli/interactive_validator.py +614 -0
  23. tnfr/cli/utils.py +18 -3
  24. tnfr/cli/utils.pyi +7 -0
  25. tnfr/cli/validate.py +236 -0
  26. tnfr/compat/__init__.py +85 -0
  27. tnfr/compat/dataclass.py +136 -0
  28. tnfr/compat/jsonschema_stub.py +61 -0
  29. tnfr/compat/matplotlib_stub.py +73 -0
  30. tnfr/compat/numpy_stub.py +155 -0
  31. tnfr/config/__init__.py +224 -0
  32. tnfr/config/__init__.pyi +10 -0
  33. tnfr/{constants_glyphs.py → config/constants.py} +26 -20
  34. tnfr/config/constants.pyi +12 -0
  35. tnfr/config/defaults.py +54 -0
  36. tnfr/{constants/core.py → config/defaults_core.py} +59 -6
  37. tnfr/config/defaults_init.py +33 -0
  38. tnfr/config/defaults_metric.py +104 -0
  39. tnfr/config/feature_flags.py +81 -0
  40. tnfr/config/feature_flags.pyi +16 -0
  41. tnfr/config/glyph_constants.py +31 -0
  42. tnfr/config/init.py +77 -0
  43. tnfr/config/init.pyi +8 -0
  44. tnfr/config/operator_names.py +254 -0
  45. tnfr/config/operator_names.pyi +36 -0
  46. tnfr/config/physics_derivation.py +354 -0
  47. tnfr/config/presets.py +83 -0
  48. tnfr/config/presets.pyi +7 -0
  49. tnfr/config/security.py +927 -0
  50. tnfr/config/thresholds.py +114 -0
  51. tnfr/config/tnfr_config.py +498 -0
  52. tnfr/constants/__init__.py +51 -133
  53. tnfr/constants/__init__.pyi +92 -0
  54. tnfr/constants/aliases.py +33 -0
  55. tnfr/constants/aliases.pyi +27 -0
  56. tnfr/constants/init.py +3 -1
  57. tnfr/constants/init.pyi +12 -0
  58. tnfr/constants/metric.py +9 -15
  59. tnfr/constants/metric.pyi +19 -0
  60. tnfr/core/__init__.py +33 -0
  61. tnfr/core/container.py +226 -0
  62. tnfr/core/default_implementations.py +329 -0
  63. tnfr/core/interfaces.py +279 -0
  64. tnfr/dynamics/__init__.py +213 -633
  65. tnfr/dynamics/__init__.pyi +83 -0
  66. tnfr/dynamics/adaptation.py +267 -0
  67. tnfr/dynamics/adaptation.pyi +7 -0
  68. tnfr/dynamics/adaptive_sequences.py +189 -0
  69. tnfr/dynamics/adaptive_sequences.pyi +14 -0
  70. tnfr/dynamics/aliases.py +23 -0
  71. tnfr/dynamics/aliases.pyi +19 -0
  72. tnfr/dynamics/bifurcation.py +232 -0
  73. tnfr/dynamics/canonical.py +229 -0
  74. tnfr/dynamics/canonical.pyi +48 -0
  75. tnfr/dynamics/coordination.py +385 -0
  76. tnfr/dynamics/coordination.pyi +25 -0
  77. tnfr/dynamics/dnfr.py +2699 -398
  78. tnfr/dynamics/dnfr.pyi +26 -0
  79. tnfr/dynamics/dynamic_limits.py +225 -0
  80. tnfr/dynamics/feedback.py +252 -0
  81. tnfr/dynamics/feedback.pyi +24 -0
  82. tnfr/dynamics/fused_dnfr.py +454 -0
  83. tnfr/dynamics/homeostasis.py +157 -0
  84. tnfr/dynamics/homeostasis.pyi +14 -0
  85. tnfr/dynamics/integrators.py +496 -102
  86. tnfr/dynamics/integrators.pyi +36 -0
  87. tnfr/dynamics/learning.py +310 -0
  88. tnfr/dynamics/learning.pyi +33 -0
  89. tnfr/dynamics/metabolism.py +254 -0
  90. tnfr/dynamics/nbody.py +796 -0
  91. tnfr/dynamics/nbody_tnfr.py +783 -0
  92. tnfr/dynamics/propagation.py +326 -0
  93. tnfr/dynamics/runtime.py +908 -0
  94. tnfr/dynamics/runtime.pyi +77 -0
  95. tnfr/dynamics/sampling.py +10 -5
  96. tnfr/dynamics/sampling.pyi +7 -0
  97. tnfr/dynamics/selectors.py +711 -0
  98. tnfr/dynamics/selectors.pyi +85 -0
  99. tnfr/dynamics/structural_clip.py +207 -0
  100. tnfr/errors/__init__.py +37 -0
  101. tnfr/errors/contextual.py +492 -0
  102. tnfr/execution.py +77 -55
  103. tnfr/execution.pyi +45 -0
  104. tnfr/extensions/__init__.py +205 -0
  105. tnfr/extensions/__init__.pyi +18 -0
  106. tnfr/extensions/base.py +173 -0
  107. tnfr/extensions/base.pyi +35 -0
  108. tnfr/extensions/business/__init__.py +71 -0
  109. tnfr/extensions/business/__init__.pyi +11 -0
  110. tnfr/extensions/business/cookbook.py +88 -0
  111. tnfr/extensions/business/cookbook.pyi +8 -0
  112. tnfr/extensions/business/health_analyzers.py +202 -0
  113. tnfr/extensions/business/health_analyzers.pyi +9 -0
  114. tnfr/extensions/business/patterns.py +183 -0
  115. tnfr/extensions/business/patterns.pyi +8 -0
  116. tnfr/extensions/medical/__init__.py +73 -0
  117. tnfr/extensions/medical/__init__.pyi +11 -0
  118. tnfr/extensions/medical/cookbook.py +88 -0
  119. tnfr/extensions/medical/cookbook.pyi +8 -0
  120. tnfr/extensions/medical/health_analyzers.py +181 -0
  121. tnfr/extensions/medical/health_analyzers.pyi +9 -0
  122. tnfr/extensions/medical/patterns.py +163 -0
  123. tnfr/extensions/medical/patterns.pyi +8 -0
  124. tnfr/flatten.py +29 -50
  125. tnfr/flatten.pyi +21 -0
  126. tnfr/gamma.py +66 -53
  127. tnfr/gamma.pyi +36 -0
  128. tnfr/glyph_history.py +144 -57
  129. tnfr/glyph_history.pyi +35 -0
  130. tnfr/glyph_runtime.py +19 -0
  131. tnfr/glyph_runtime.pyi +8 -0
  132. tnfr/immutable.py +70 -30
  133. tnfr/immutable.pyi +36 -0
  134. tnfr/initialization.py +22 -16
  135. tnfr/initialization.pyi +65 -0
  136. tnfr/io.py +5 -241
  137. tnfr/io.pyi +13 -0
  138. tnfr/locking.pyi +7 -0
  139. tnfr/mathematics/__init__.py +79 -0
  140. tnfr/mathematics/backend.py +453 -0
  141. tnfr/mathematics/backend.pyi +99 -0
  142. tnfr/mathematics/dynamics.py +408 -0
  143. tnfr/mathematics/dynamics.pyi +90 -0
  144. tnfr/mathematics/epi.py +391 -0
  145. tnfr/mathematics/epi.pyi +65 -0
  146. tnfr/mathematics/generators.py +242 -0
  147. tnfr/mathematics/generators.pyi +29 -0
  148. tnfr/mathematics/metrics.py +119 -0
  149. tnfr/mathematics/metrics.pyi +16 -0
  150. tnfr/mathematics/operators.py +239 -0
  151. tnfr/mathematics/operators.pyi +59 -0
  152. tnfr/mathematics/operators_factory.py +124 -0
  153. tnfr/mathematics/operators_factory.pyi +11 -0
  154. tnfr/mathematics/projection.py +87 -0
  155. tnfr/mathematics/projection.pyi +33 -0
  156. tnfr/mathematics/runtime.py +182 -0
  157. tnfr/mathematics/runtime.pyi +64 -0
  158. tnfr/mathematics/spaces.py +256 -0
  159. tnfr/mathematics/spaces.pyi +83 -0
  160. tnfr/mathematics/transforms.py +305 -0
  161. tnfr/mathematics/transforms.pyi +62 -0
  162. tnfr/metrics/__init__.py +47 -9
  163. tnfr/metrics/__init__.pyi +20 -0
  164. tnfr/metrics/buffer_cache.py +163 -0
  165. tnfr/metrics/buffer_cache.pyi +24 -0
  166. tnfr/metrics/cache_utils.py +214 -0
  167. tnfr/metrics/coherence.py +1510 -330
  168. tnfr/metrics/coherence.pyi +129 -0
  169. tnfr/metrics/common.py +23 -16
  170. tnfr/metrics/common.pyi +35 -0
  171. tnfr/metrics/core.py +251 -36
  172. tnfr/metrics/core.pyi +13 -0
  173. tnfr/metrics/diagnosis.py +709 -110
  174. tnfr/metrics/diagnosis.pyi +86 -0
  175. tnfr/metrics/emergence.py +245 -0
  176. tnfr/metrics/export.py +60 -18
  177. tnfr/metrics/export.pyi +7 -0
  178. tnfr/metrics/glyph_timing.py +233 -43
  179. tnfr/metrics/glyph_timing.pyi +81 -0
  180. tnfr/metrics/learning_metrics.py +280 -0
  181. tnfr/metrics/learning_metrics.pyi +21 -0
  182. tnfr/metrics/phase_coherence.py +351 -0
  183. tnfr/metrics/phase_compatibility.py +349 -0
  184. tnfr/metrics/reporting.py +63 -28
  185. tnfr/metrics/reporting.pyi +25 -0
  186. tnfr/metrics/sense_index.py +1126 -43
  187. tnfr/metrics/sense_index.pyi +9 -0
  188. tnfr/metrics/trig.py +215 -23
  189. tnfr/metrics/trig.pyi +13 -0
  190. tnfr/metrics/trig_cache.py +148 -24
  191. tnfr/metrics/trig_cache.pyi +10 -0
  192. tnfr/multiscale/__init__.py +32 -0
  193. tnfr/multiscale/hierarchical.py +517 -0
  194. tnfr/node.py +646 -140
  195. tnfr/node.pyi +139 -0
  196. tnfr/observers.py +160 -45
  197. tnfr/observers.pyi +31 -0
  198. tnfr/ontosim.py +23 -19
  199. tnfr/ontosim.pyi +28 -0
  200. tnfr/operators/__init__.py +1358 -106
  201. tnfr/operators/__init__.pyi +31 -0
  202. tnfr/operators/algebra.py +277 -0
  203. tnfr/operators/canonical_patterns.py +420 -0
  204. tnfr/operators/cascade.py +267 -0
  205. tnfr/operators/cycle_detection.py +358 -0
  206. tnfr/operators/definitions.py +4108 -0
  207. tnfr/operators/definitions.pyi +78 -0
  208. tnfr/operators/grammar.py +1164 -0
  209. tnfr/operators/grammar.pyi +140 -0
  210. tnfr/operators/hamiltonian.py +710 -0
  211. tnfr/operators/health_analyzer.py +809 -0
  212. tnfr/operators/jitter.py +107 -38
  213. tnfr/operators/jitter.pyi +11 -0
  214. tnfr/operators/lifecycle.py +314 -0
  215. tnfr/operators/metabolism.py +618 -0
  216. tnfr/operators/metrics.py +2138 -0
  217. tnfr/operators/network_analysis/__init__.py +27 -0
  218. tnfr/operators/network_analysis/source_detection.py +186 -0
  219. tnfr/operators/nodal_equation.py +395 -0
  220. tnfr/operators/pattern_detection.py +660 -0
  221. tnfr/operators/patterns.py +669 -0
  222. tnfr/operators/postconditions/__init__.py +38 -0
  223. tnfr/operators/postconditions/mutation.py +236 -0
  224. tnfr/operators/preconditions/__init__.py +1226 -0
  225. tnfr/operators/preconditions/coherence.py +305 -0
  226. tnfr/operators/preconditions/dissonance.py +236 -0
  227. tnfr/operators/preconditions/emission.py +128 -0
  228. tnfr/operators/preconditions/mutation.py +580 -0
  229. tnfr/operators/preconditions/reception.py +125 -0
  230. tnfr/operators/preconditions/resonance.py +364 -0
  231. tnfr/operators/registry.py +74 -0
  232. tnfr/operators/registry.pyi +9 -0
  233. tnfr/operators/remesh.py +1415 -91
  234. tnfr/operators/remesh.pyi +26 -0
  235. tnfr/operators/structural_units.py +268 -0
  236. tnfr/operators/unified_grammar.py +105 -0
  237. tnfr/parallel/__init__.py +54 -0
  238. tnfr/parallel/auto_scaler.py +234 -0
  239. tnfr/parallel/distributed.py +384 -0
  240. tnfr/parallel/engine.py +238 -0
  241. tnfr/parallel/gpu_engine.py +420 -0
  242. tnfr/parallel/monitoring.py +248 -0
  243. tnfr/parallel/partitioner.py +459 -0
  244. tnfr/py.typed +0 -0
  245. tnfr/recipes/__init__.py +22 -0
  246. tnfr/recipes/cookbook.py +743 -0
  247. tnfr/rng.py +75 -151
  248. tnfr/rng.pyi +26 -0
  249. tnfr/schemas/__init__.py +8 -0
  250. tnfr/schemas/grammar.json +94 -0
  251. tnfr/sdk/__init__.py +107 -0
  252. tnfr/sdk/__init__.pyi +19 -0
  253. tnfr/sdk/adaptive_system.py +173 -0
  254. tnfr/sdk/adaptive_system.pyi +21 -0
  255. tnfr/sdk/builders.py +370 -0
  256. tnfr/sdk/builders.pyi +51 -0
  257. tnfr/sdk/fluent.py +1121 -0
  258. tnfr/sdk/fluent.pyi +74 -0
  259. tnfr/sdk/templates.py +342 -0
  260. tnfr/sdk/templates.pyi +41 -0
  261. tnfr/sdk/utils.py +341 -0
  262. tnfr/secure_config.py +46 -0
  263. tnfr/security/__init__.py +70 -0
  264. tnfr/security/database.py +514 -0
  265. tnfr/security/subprocess.py +503 -0
  266. tnfr/security/validation.py +290 -0
  267. tnfr/selector.py +59 -22
  268. tnfr/selector.pyi +19 -0
  269. tnfr/sense.py +92 -67
  270. tnfr/sense.pyi +23 -0
  271. tnfr/services/__init__.py +17 -0
  272. tnfr/services/orchestrator.py +325 -0
  273. tnfr/sparse/__init__.py +39 -0
  274. tnfr/sparse/representations.py +492 -0
  275. tnfr/structural.py +639 -263
  276. tnfr/structural.pyi +83 -0
  277. tnfr/telemetry/__init__.py +35 -0
  278. tnfr/telemetry/cache_metrics.py +226 -0
  279. tnfr/telemetry/cache_metrics.pyi +64 -0
  280. tnfr/telemetry/nu_f.py +422 -0
  281. tnfr/telemetry/nu_f.pyi +108 -0
  282. tnfr/telemetry/verbosity.py +36 -0
  283. tnfr/telemetry/verbosity.pyi +15 -0
  284. tnfr/tokens.py +2 -4
  285. tnfr/tokens.pyi +36 -0
  286. tnfr/tools/__init__.py +20 -0
  287. tnfr/tools/domain_templates.py +478 -0
  288. tnfr/tools/sequence_generator.py +846 -0
  289. tnfr/topology/__init__.py +13 -0
  290. tnfr/topology/asymmetry.py +151 -0
  291. tnfr/trace.py +300 -126
  292. tnfr/trace.pyi +42 -0
  293. tnfr/tutorials/__init__.py +38 -0
  294. tnfr/tutorials/autonomous_evolution.py +285 -0
  295. tnfr/tutorials/interactive.py +1576 -0
  296. tnfr/tutorials/structural_metabolism.py +238 -0
  297. tnfr/types.py +743 -12
  298. tnfr/types.pyi +357 -0
  299. tnfr/units.py +68 -0
  300. tnfr/units.pyi +13 -0
  301. tnfr/utils/__init__.py +282 -0
  302. tnfr/utils/__init__.pyi +215 -0
  303. tnfr/utils/cache.py +4223 -0
  304. tnfr/utils/cache.pyi +470 -0
  305. tnfr/{callback_utils.py → utils/callbacks.py} +26 -39
  306. tnfr/utils/callbacks.pyi +49 -0
  307. tnfr/utils/chunks.py +108 -0
  308. tnfr/utils/chunks.pyi +22 -0
  309. tnfr/utils/data.py +428 -0
  310. tnfr/utils/data.pyi +74 -0
  311. tnfr/utils/graph.py +85 -0
  312. tnfr/utils/graph.pyi +10 -0
  313. tnfr/utils/init.py +821 -0
  314. tnfr/utils/init.pyi +80 -0
  315. tnfr/utils/io.py +559 -0
  316. tnfr/utils/io.pyi +66 -0
  317. tnfr/{helpers → utils}/numeric.py +51 -24
  318. tnfr/utils/numeric.pyi +21 -0
  319. tnfr/validation/__init__.py +257 -0
  320. tnfr/validation/__init__.pyi +85 -0
  321. tnfr/validation/compatibility.py +460 -0
  322. tnfr/validation/compatibility.pyi +6 -0
  323. tnfr/validation/config.py +73 -0
  324. tnfr/validation/graph.py +139 -0
  325. tnfr/validation/graph.pyi +18 -0
  326. tnfr/validation/input_validation.py +755 -0
  327. tnfr/validation/invariants.py +712 -0
  328. tnfr/validation/rules.py +253 -0
  329. tnfr/validation/rules.pyi +44 -0
  330. tnfr/validation/runtime.py +279 -0
  331. tnfr/validation/runtime.pyi +28 -0
  332. tnfr/validation/sequence_validator.py +162 -0
  333. tnfr/validation/soft_filters.py +170 -0
  334. tnfr/validation/soft_filters.pyi +32 -0
  335. tnfr/validation/spectral.py +164 -0
  336. tnfr/validation/spectral.pyi +42 -0
  337. tnfr/validation/validator.py +1266 -0
  338. tnfr/validation/window.py +39 -0
  339. tnfr/validation/window.pyi +1 -0
  340. tnfr/visualization/__init__.py +98 -0
  341. tnfr/visualization/cascade_viz.py +256 -0
  342. tnfr/visualization/hierarchy.py +284 -0
  343. tnfr/visualization/sequence_plotter.py +784 -0
  344. tnfr/viz/__init__.py +60 -0
  345. tnfr/viz/matplotlib.py +278 -0
  346. tnfr/viz/matplotlib.pyi +35 -0
  347. tnfr-8.5.0.dist-info/METADATA +573 -0
  348. tnfr-8.5.0.dist-info/RECORD +353 -0
  349. {tnfr-4.5.2.dist-info → tnfr-8.5.0.dist-info}/entry_points.txt +1 -0
  350. {tnfr-4.5.2.dist-info → tnfr-8.5.0.dist-info}/licenses/LICENSE.md +1 -1
  351. tnfr/collections_utils.py +0 -300
  352. tnfr/config.py +0 -32
  353. tnfr/grammar.py +0 -344
  354. tnfr/graph_utils.py +0 -84
  355. tnfr/helpers/__init__.py +0 -71
  356. tnfr/import_utils.py +0 -228
  357. tnfr/json_utils.py +0 -162
  358. tnfr/logging_utils.py +0 -116
  359. tnfr/presets.py +0 -60
  360. tnfr/validators.py +0 -84
  361. tnfr/value_utils.py +0 -59
  362. tnfr-4.5.2.dist-info/METADATA +0 -379
  363. tnfr-4.5.2.dist-info/RECORD +0 -67
  364. {tnfr-4.5.2.dist-info → tnfr-8.5.0.dist-info}/WHEEL +0 -0
  365. {tnfr-4.5.2.dist-info → tnfr-8.5.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,33 @@
1
+ """Initialization constants."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import math
6
+ from dataclasses import asdict
7
+
8
+ from ..compat.dataclass import dataclass
9
+
10
+
11
+ @dataclass(frozen=True, slots=True)
12
+ class InitDefaults:
13
+ """Default parameters for node initialisation.
14
+
15
+ The fields are collected into :data:`INIT_DEFAULTS` and may therefore
16
+ appear unused to tools like Vulture.
17
+ """
18
+
19
+ INIT_RANDOM_PHASE: bool = True
20
+ INIT_THETA_MIN: float = -math.pi
21
+ INIT_THETA_MAX: float = math.pi
22
+ INIT_VF_MODE: str = "uniform"
23
+ INIT_VF_MIN: float | None = None
24
+ INIT_VF_MAX: float | None = None
25
+ INIT_VF_MEAN: float = 0.5
26
+ INIT_VF_STD: float = 0.15
27
+ INIT_VF_CLAMP_TO_LIMITS: bool = True
28
+ INIT_SI_MIN: float = 0.4
29
+ INIT_SI_MAX: float = 0.7
30
+ INIT_EPI_VALUE: float = 0.0
31
+
32
+
33
+ INIT_DEFAULTS = asdict(InitDefaults())
@@ -0,0 +1,104 @@
1
+ """Metric constants."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import asdict, field
6
+ from types import MappingProxyType
7
+ from typing import Any
8
+
9
+ from ..compat.dataclass import dataclass
10
+
11
+
12
+ @dataclass(frozen=True, slots=True)
13
+ class MetricDefaults:
14
+ """Default parameters for metric computation.
15
+
16
+ The fields are gathered into :data:`METRIC_DEFAULTS` and exposed through
17
+ read-only views below, so they may appear unused to static analysis tools.
18
+ """
19
+
20
+ PHASE_HISTORY_MAXLEN: int = 50
21
+ STOP_EARLY: dict[str, Any] = field(
22
+ default_factory=lambda: {
23
+ "enabled": False,
24
+ "window": 25,
25
+ "fraction": 0.90,
26
+ }
27
+ )
28
+ SIGMA: dict[str, Any] = field(
29
+ default_factory=lambda: {
30
+ "enabled": True,
31
+ "weight": "Si", # "Si" | "EPI" | "1"
32
+ "smooth": 0.0, # EMA over the global vector (0=off)
33
+ "history_key": "sigma_global",
34
+ "per_node": False,
35
+ }
36
+ )
37
+ TRACE: dict[str, Any] = field(
38
+ default_factory=lambda: {
39
+ "enabled": True,
40
+ "verbosity": "debug",
41
+ "history_key": "trace_meta",
42
+ }
43
+ )
44
+ METRICS: dict[str, Any] = field(
45
+ default_factory=lambda: {
46
+ "enabled": True,
47
+ "save_by_node": True,
48
+ "normalize_series": False,
49
+ "n_jobs": 1,
50
+ "verbosity": "debug",
51
+ }
52
+ )
53
+ GRAMMAR_CANON: dict[str, Any] = field(
54
+ default_factory=lambda: {
55
+ "enabled": True,
56
+ "zhir_requires_oz_window": 3,
57
+ "zhir_dnfr_min": 0.05,
58
+ "thol_min_len": 2,
59
+ "thol_max_len": 6,
60
+ "thol_close_dnfr": 0.15,
61
+ "si_high": 0.66,
62
+ }
63
+ )
64
+ COHERENCE: dict[str, Any] = field(
65
+ default_factory=lambda: {
66
+ "enabled": True,
67
+ "scope": "neighbors",
68
+ "weights": {"phase": 0.34, "epi": 0.33, "vf": 0.20, "si": 0.13},
69
+ "self_on_diag": True,
70
+ "store_mode": "sparse",
71
+ "threshold": 0.0,
72
+ "n_jobs": 1,
73
+ "history_key": "W_sparse",
74
+ "Wi_history_key": "W_i",
75
+ "stats_history_key": "W_stats",
76
+ }
77
+ )
78
+ DIAGNOSIS: dict[str, Any] = field(
79
+ default_factory=lambda: {
80
+ "enabled": True,
81
+ "window": 16,
82
+ "history_key": "nodal_diag",
83
+ "stable": {"Rloc_hi": 0.80, "dnfr_lo": 0.20, "persist": 3},
84
+ "dissonance": {"Rloc_lo": 0.40, "dnfr_hi": 0.50, "persist": 3},
85
+ "transition": {"persist": 2},
86
+ "compute_symmetry": True,
87
+ "include_typology": False,
88
+ "advice": {
89
+ "stable": ["Coherence", "Coupling", "Resonance"],
90
+ "transition": ["Transition", "Resonance", "Self-organisation"],
91
+ "dissonant": ["Silence", "Contraction", "Mutation"],
92
+ },
93
+ }
94
+ )
95
+
96
+
97
+ METRIC_DEFAULTS = asdict(MetricDefaults())
98
+
99
+ SIGMA = MappingProxyType(METRIC_DEFAULTS["SIGMA"])
100
+ TRACE = MappingProxyType(METRIC_DEFAULTS["TRACE"])
101
+ METRICS = MappingProxyType(METRIC_DEFAULTS["METRICS"])
102
+ GRAMMAR_CANON = MappingProxyType(METRIC_DEFAULTS["GRAMMAR_CANON"])
103
+ COHERENCE = MappingProxyType(METRIC_DEFAULTS["COHERENCE"])
104
+ DIAGNOSIS = MappingProxyType(METRIC_DEFAULTS["DIAGNOSIS"])
@@ -0,0 +1,81 @@
1
+ """Math feature flag configuration helpers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from contextlib import contextmanager
7
+ from dataclasses import dataclass, replace
8
+ from typing import Iterator
9
+
10
+ __all__ = ("MathFeatureFlags", "get_flags", "context_flags")
11
+
12
+
13
+ @dataclass(frozen=True)
14
+ class MathFeatureFlags:
15
+ """Toggle optional mathematical behaviours in the engine."""
16
+
17
+ enable_math_validation: bool = False
18
+ enable_math_dynamics: bool = False
19
+ log_performance: bool = False
20
+ math_backend: str = "numpy"
21
+
22
+
23
+ _TRUE_VALUES = {"1", "true", "on", "yes", "y", "t"}
24
+ _FALSE_VALUES = {"0", "false", "off", "no", "n", "f"}
25
+
26
+ _BASE_FLAGS: MathFeatureFlags | None = None
27
+ _FLAGS_STACK: list[MathFeatureFlags] = []
28
+
29
+
30
+ def _parse_env_flag(name: str, default: bool) -> bool:
31
+ value = os.getenv(name)
32
+ if value is None:
33
+ return default
34
+ lowered = value.strip().lower()
35
+ if lowered in _TRUE_VALUES:
36
+ return True
37
+ if lowered in _FALSE_VALUES:
38
+ return False
39
+ return default
40
+
41
+
42
+ def _load_base_flags() -> MathFeatureFlags:
43
+ global _BASE_FLAGS
44
+ if _BASE_FLAGS is None:
45
+ backend = os.getenv("TNFR_MATH_BACKEND")
46
+ backend_choice = backend.strip() if backend else "numpy"
47
+ _BASE_FLAGS = MathFeatureFlags(
48
+ enable_math_validation=_parse_env_flag(
49
+ "TNFR_ENABLE_MATH_VALIDATION", False
50
+ ),
51
+ enable_math_dynamics=_parse_env_flag("TNFR_ENABLE_MATH_DYNAMICS", False),
52
+ log_performance=_parse_env_flag("TNFR_LOG_PERF", False),
53
+ math_backend=backend_choice or "numpy",
54
+ )
55
+ return _BASE_FLAGS
56
+
57
+
58
+ def get_flags() -> MathFeatureFlags:
59
+ """Return the currently active feature flags."""
60
+
61
+ if _FLAGS_STACK:
62
+ return _FLAGS_STACK[-1]
63
+ return _load_base_flags()
64
+
65
+
66
+ @contextmanager
67
+ def context_flags(**overrides: bool) -> Iterator[MathFeatureFlags]:
68
+ """Temporarily override math feature flags."""
69
+
70
+ invalid = set(overrides) - set(MathFeatureFlags.__annotations__)
71
+ if invalid:
72
+ invalid_names = ", ".join(sorted(invalid))
73
+ raise TypeError(f"Unknown flag overrides: {invalid_names}")
74
+
75
+ previous = get_flags()
76
+ next_flags = replace(previous, **overrides)
77
+ _FLAGS_STACK.append(next_flags)
78
+ try:
79
+ yield next_flags
80
+ finally:
81
+ _FLAGS_STACK.pop()
@@ -0,0 +1,16 @@
1
+ from contextlib import contextmanager
2
+ from dataclasses import dataclass
3
+ from typing import Iterator
4
+
5
+ __all__ = ["MathFeatureFlags", "get_flags", "context_flags"]
6
+
7
+ @dataclass(frozen=True)
8
+ class MathFeatureFlags:
9
+ enable_math_validation: bool = ...
10
+ enable_math_dynamics: bool = ...
11
+ log_performance: bool = ...
12
+ math_backend: str = ...
13
+
14
+ def get_flags() -> MathFeatureFlags: ...
15
+ @contextmanager
16
+ def context_flags(**overrides: bool) -> Iterator[MathFeatureFlags]: ...
@@ -0,0 +1,31 @@
1
+ """Shared alias constants for TNFR attributes."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from . import get_aliases
6
+
7
+ ALIAS_VF = get_aliases("VF")
8
+ ALIAS_THETA = get_aliases("THETA")
9
+ ALIAS_DNFR = get_aliases("DNFR")
10
+ ALIAS_EPI = get_aliases("EPI")
11
+ ALIAS_EPI_KIND = get_aliases("EPI_KIND")
12
+ ALIAS_SI = get_aliases("SI")
13
+ ALIAS_DEPI = get_aliases("DEPI")
14
+ ALIAS_D2EPI = get_aliases("D2EPI")
15
+ ALIAS_DVF = get_aliases("DVF")
16
+ ALIAS_D2VF = get_aliases("D2VF")
17
+ ALIAS_DSI = get_aliases("DSI")
18
+
19
+ __all__ = [
20
+ "ALIAS_VF",
21
+ "ALIAS_THETA",
22
+ "ALIAS_DNFR",
23
+ "ALIAS_EPI",
24
+ "ALIAS_EPI_KIND",
25
+ "ALIAS_SI",
26
+ "ALIAS_DEPI",
27
+ "ALIAS_D2EPI",
28
+ "ALIAS_DVF",
29
+ "ALIAS_D2VF",
30
+ "ALIAS_DSI",
31
+ ]
tnfr/config/init.py ADDED
@@ -0,0 +1,77 @@
1
+ """Core configuration helpers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections.abc import Mapping
6
+ from pathlib import Path
7
+ from typing import TYPE_CHECKING, Any
8
+
9
+ from ..utils import read_structured_file
10
+
11
+ if TYPE_CHECKING: # pragma: no cover - only for type checkers
12
+ import networkx as nx
13
+
14
+ __all__ = ("load_config", "apply_config")
15
+
16
+
17
+ def load_config(
18
+ path: str | Path,
19
+ *,
20
+ base_dir: str | Path | None = None,
21
+ ) -> Mapping[str, Any]:
22
+ """Read a JSON/YAML file and return a mapping with parameters.
23
+
24
+ Parameters
25
+ ----------
26
+ path : str | Path
27
+ Path to the configuration file.
28
+ base_dir : str | Path | None, optional
29
+ Base directory to restrict config file access. If provided, the
30
+ resolved path must stay within this directory (prevents path traversal).
31
+
32
+ Returns
33
+ -------
34
+ Mapping[str, Any]
35
+ Configuration parameters as a mapping.
36
+
37
+ Raises
38
+ ------
39
+ ValueError
40
+ If the configuration file is invalid or contains unsafe patterns.
41
+ PathTraversalError
42
+ If path traversal is detected when base_dir is provided.
43
+ StructuredFileError
44
+ If the file cannot be read or parsed.
45
+ """
46
+ path_obj = path if isinstance(path, Path) else Path(path)
47
+ data = read_structured_file(path_obj, base_dir=base_dir)
48
+ if not isinstance(data, Mapping):
49
+ raise ValueError("Configuration file must contain an object")
50
+ return data
51
+
52
+
53
+ def apply_config(
54
+ G: "nx.Graph",
55
+ path: str | Path,
56
+ *,
57
+ base_dir: str | Path | None = None,
58
+ ) -> None:
59
+ """Inject parameters from ``path`` into ``G.graph``.
60
+
61
+ Uses inject_defaults from this module to keep canonical default
62
+ semantics.
63
+
64
+ Parameters
65
+ ----------
66
+ G : nx.Graph
67
+ The graph to configure.
68
+ path : str | Path
69
+ Path to the configuration file.
70
+ base_dir : str | Path | None, optional
71
+ Base directory to restrict config file access.
72
+ """
73
+ # Import inject_defaults locally to avoid circular import
74
+ from . import inject_defaults
75
+
76
+ cfg = load_config(path, base_dir=base_dir)
77
+ inject_defaults(G, cfg, override=True)
tnfr/config/init.pyi ADDED
@@ -0,0 +1,8 @@
1
+ from typing import Any
2
+
3
+ __all__: Any
4
+
5
+ def __getattr__(name: str) -> Any: ...
6
+
7
+ apply_config: Any
8
+ load_config: Any
@@ -0,0 +1,254 @@
1
+ """Canonical operator name constants and physics-derived operator sets.
2
+
3
+ This module defines operator names and derives valid start/end operator sets
4
+ from TNFR physical principles rather than arbitrary lists.
5
+
6
+ Physics-Based Derivation
7
+ ------------------------
8
+ The sets VALID_START_OPERATORS and VALID_END_OPERATORS are derived from the
9
+ fundamental TNFR nodal equation:
10
+
11
+ ∂EPI/∂t = νf · ΔNFR(t)
12
+
13
+ Where:
14
+ - EPI: Primary Information Structure (coherent form)
15
+ - νf: Structural frequency (reorganization rate, Hz_str)
16
+ - ΔNFR: Internal reorganization operator/gradient
17
+
18
+ Start Operators (Activation)
19
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20
+ An operator can START a sequence if it can either:
21
+
22
+ 1. **Generate EPI from null state** (νf=0, EPI=0):
23
+ - emission: Creates outward coherence pulse, generates νf > 0 and ΔNFR > 0
24
+
25
+ 2. **Activate latent EPI** (νf≈0, but EPI>0):
26
+ - recursivity: Replicates/echoes existing patterns across scales
27
+ - transition: Activates node from another phase/regime
28
+
29
+ Physical justification: Only operators that can create or activate structural
30
+ capacity (νf > 0) from dormant/null states can initiate reorganization.
31
+
32
+ End Operators (Closure)
33
+ ~~~~~~~~~~~~~~~~~~~~~~~~
34
+ An operator can END a sequence if it can either:
35
+
36
+ 1. **Stabilize reorganization** (∂EPI/∂t → 0):
37
+ - silence: Forces νf → 0, causing ∂EPI/∂t → 0 while preserving EPI
38
+
39
+ 2. **Achieve operational closure**:
40
+ - transition: Hands off to next phase (completes current cycle)
41
+ - recursivity: Fractal echo creates self-similar closure
42
+ - dissonance: Postponed conflict / contained tension (questionable)
43
+
44
+ Physical justification: Terminal operators must either freeze evolution
45
+ (νf → 0) or complete an operational cycle with clear boundary.
46
+
47
+ For detailed physics derivation logic, see:
48
+ tnfr.config.physics_derivation
49
+
50
+ References
51
+ ----------
52
+ - TNFR.pdf: Section 2.1 (Nodal Equation)
53
+ - AGENTS.md: Section 3 (Canonical Invariants)
54
+ """
55
+
56
+ from __future__ import annotations
57
+
58
+ from typing import Any
59
+
60
+ # Canonical operator identifiers (English tokens)
61
+ EMISSION = "emission"
62
+ RECEPTION = "reception"
63
+ COHERENCE = "coherence"
64
+ DISSONANCE = "dissonance"
65
+ COUPLING = "coupling"
66
+ RESONANCE = "resonance"
67
+ SILENCE = "silence"
68
+ EXPANSION = "expansion"
69
+ CONTRACTION = "contraction"
70
+ SELF_ORGANIZATION = "self_organization"
71
+ MUTATION = "mutation"
72
+ TRANSITION = "transition"
73
+ RECURSIVITY = "recursivity"
74
+
75
+ # Canonical collections -------------------------------------------------------
76
+
77
+ CANONICAL_OPERATOR_NAMES = frozenset(
78
+ {
79
+ EMISSION,
80
+ RECEPTION,
81
+ COHERENCE,
82
+ DISSONANCE,
83
+ COUPLING,
84
+ RESONANCE,
85
+ SILENCE,
86
+ EXPANSION,
87
+ CONTRACTION,
88
+ SELF_ORGANIZATION,
89
+ MUTATION,
90
+ TRANSITION,
91
+ RECURSIVITY,
92
+ }
93
+ )
94
+
95
+ ALL_OPERATOR_NAMES = CANONICAL_OPERATOR_NAMES
96
+ ENGLISH_OPERATOR_NAMES = CANONICAL_OPERATOR_NAMES
97
+
98
+ # Physics-derived operator sets (derived from TNFR canonical principles)
99
+ # Import here to avoid issues, but actual derivation is in physics_derivation module
100
+ # These are computed at module load time from TNFR physical principles
101
+ VALID_START_OPERATORS = frozenset({EMISSION, RECURSIVITY, TRANSITION})
102
+ INTERMEDIATE_OPERATORS = frozenset({DISSONANCE, COUPLING, RESONANCE})
103
+ VALID_END_OPERATORS = frozenset({SILENCE, TRANSITION, RECURSIVITY, DISSONANCE})
104
+ SELF_ORGANIZATION_CLOSURES = frozenset({SILENCE, CONTRACTION})
105
+
106
+ # R4 Bifurcation control: operators that enable structural transformations
107
+ # Legacy single-level destabilizers (for backward compatibility)
108
+ DESTABILIZERS = frozenset({DISSONANCE, TRANSITION, EXPANSION}) # OZ, NAV, VAL
109
+ TRANSFORMERS = frozenset({MUTATION, SELF_ORGANIZATION}) # ZHIR, THOL
110
+ BIFURCATION_WINDOW = 3 # Legacy: Search window for destabilizer precedent
111
+
112
+ # R4 Extended: Graduated destabilizer classification by intensity
113
+ DESTABILIZERS_STRONG = frozenset({DISSONANCE}) # OZ: explicit dissonance
114
+ DESTABILIZERS_MODERATE = frozenset({TRANSITION, EXPANSION}) # NAV, VAL: indirect
115
+ DESTABILIZERS_WEAK = frozenset({RECEPTION}) # EN: latent potential
116
+
117
+ # All destabilizers (union of all levels)
118
+ DESTABILIZERS_ALL = DESTABILIZERS_STRONG | DESTABILIZERS_MODERATE | DESTABILIZERS_WEAK
119
+
120
+ # R4 Extended: Bifurcation windows by destabilizer intensity
121
+ # These define how many operators can separate a destabilizer from a transformer
122
+ BIFURCATION_WINDOWS = {
123
+ "strong": 4, # OZ permits ZHIR/THOL within 4 operators
124
+ "moderate": 2, # NAV/VAL permit ZHIR/THOL within 2 operators
125
+ "weak": 1, # EN requires ZHIR/THOL as immediate successor
126
+ }
127
+
128
+
129
+ def canonical_operator_name(name: str) -> str:
130
+ """Return the canonical operator token for ``name``."""
131
+
132
+ return name
133
+
134
+
135
+ def operator_display_name(name: str) -> str:
136
+ """Return the display label for ``name`` (currently the canonical token)."""
137
+
138
+ return canonical_operator_name(name)
139
+
140
+
141
+ __all__ = [
142
+ "EMISSION",
143
+ "RECEPTION",
144
+ "COHERENCE",
145
+ "DISSONANCE",
146
+ "COUPLING",
147
+ "RESONANCE",
148
+ "SILENCE",
149
+ "EXPANSION",
150
+ "CONTRACTION",
151
+ "SELF_ORGANIZATION",
152
+ "MUTATION",
153
+ "TRANSITION",
154
+ "RECURSIVITY",
155
+ "CANONICAL_OPERATOR_NAMES",
156
+ "ENGLISH_OPERATOR_NAMES",
157
+ "ALL_OPERATOR_NAMES",
158
+ "VALID_START_OPERATORS",
159
+ "INTERMEDIATE_OPERATORS",
160
+ "VALID_END_OPERATORS",
161
+ "SELF_ORGANIZATION_CLOSURES",
162
+ "DESTABILIZERS",
163
+ "TRANSFORMERS",
164
+ "BIFURCATION_WINDOW",
165
+ "DESTABILIZERS_STRONG",
166
+ "DESTABILIZERS_MODERATE",
167
+ "DESTABILIZERS_WEAK",
168
+ "DESTABILIZERS_ALL",
169
+ "BIFURCATION_WINDOWS",
170
+ "canonical_operator_name",
171
+ "operator_display_name",
172
+ "validate_physics_derivation",
173
+ ]
174
+
175
+
176
+ def validate_physics_derivation() -> dict[str, Any]:
177
+ """Validate that operator sets are consistent with TNFR physics derivation.
178
+
179
+ This function verifies that VALID_START_OPERATORS and VALID_END_OPERATORS
180
+ match what would be derived from first principles using the physics_derivation
181
+ module.
182
+
183
+ Returns
184
+ -------
185
+ dict[str, Any]
186
+ Validation report with keys:
187
+ - "start_operators_valid": bool
188
+ - "end_operators_valid": bool
189
+ - "start_operators_expected": frozenset
190
+ - "start_operators_actual": frozenset
191
+ - "end_operators_expected": frozenset
192
+ - "end_operators_actual": frozenset
193
+ - "discrepancies": list of str
194
+
195
+ Notes
196
+ -----
197
+ This function is primarily for testing and validation. It ensures that
198
+ any manual updates to VALID_START_OPERATORS or VALID_END_OPERATORS remain
199
+ consistent with TNFR canonical physics.
200
+
201
+ If discrepancies are found, the function logs warnings but does not raise
202
+ exceptions, allowing for intentional overrides with clear audit trail.
203
+ """
204
+ from .physics_derivation import (
205
+ derive_start_operators_from_physics,
206
+ derive_end_operators_from_physics,
207
+ )
208
+
209
+ expected_starts = derive_start_operators_from_physics()
210
+ expected_ends = derive_end_operators_from_physics()
211
+
212
+ discrepancies = []
213
+
214
+ start_valid = VALID_START_OPERATORS == expected_starts
215
+ if not start_valid:
216
+ missing = expected_starts - VALID_START_OPERATORS
217
+ extra = VALID_START_OPERATORS - expected_starts
218
+ if missing:
219
+ discrepancies.append(
220
+ f"VALID_START_OPERATORS missing physics-derived operators: {missing}"
221
+ )
222
+ if extra:
223
+ discrepancies.append(
224
+ f"VALID_START_OPERATORS contains non-physics operators: {extra}"
225
+ )
226
+
227
+ end_valid = VALID_END_OPERATORS == expected_ends
228
+ if not end_valid:
229
+ missing = expected_ends - VALID_END_OPERATORS
230
+ extra = VALID_END_OPERATORS - expected_ends
231
+ if missing:
232
+ discrepancies.append(
233
+ f"VALID_END_OPERATORS missing physics-derived operators: {missing}"
234
+ )
235
+ if extra:
236
+ discrepancies.append(
237
+ f"VALID_END_OPERATORS contains non-physics operators: {extra}"
238
+ )
239
+
240
+ return {
241
+ "start_operators_valid": start_valid,
242
+ "end_operators_valid": end_valid,
243
+ "start_operators_expected": expected_starts,
244
+ "start_operators_actual": VALID_START_OPERATORS,
245
+ "end_operators_expected": expected_ends,
246
+ "end_operators_actual": VALID_END_OPERATORS,
247
+ "discrepancies": discrepancies,
248
+ }
249
+
250
+
251
+ def __getattr__(name: str) -> Any:
252
+ """Provide a consistent ``AttributeError`` when names are missing."""
253
+
254
+ raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
@@ -0,0 +1,36 @@
1
+ from typing import Any
2
+
3
+ __all__: Any
4
+
5
+ def __getattr__(name: str) -> Any: ...
6
+
7
+ ALL_OPERATOR_NAMES: Any
8
+ BIFURCATION_WINDOW: Any
9
+ BIFURCATION_WINDOWS: Any
10
+ CANONICAL_OPERATOR_NAMES: Any
11
+ COHERENCE: Any
12
+ CONTRACTION: Any
13
+ COUPLING: Any
14
+ DESTABILIZERS: Any
15
+ DESTABILIZERS_ALL: Any
16
+ DESTABILIZERS_MODERATE: Any
17
+ DESTABILIZERS_STRONG: Any
18
+ DESTABILIZERS_WEAK: Any
19
+ DISSONANCE: Any
20
+ EMISSION: Any
21
+ ENGLISH_OPERATOR_NAMES: Any
22
+ EXPANSION: Any
23
+ INTERMEDIATE_OPERATORS: Any
24
+ MUTATION: Any
25
+ RECEPTION: Any
26
+ RECURSIVITY: Any
27
+ RESONANCE: Any
28
+ SELF_ORGANIZATION: Any
29
+ SELF_ORGANIZATION_CLOSURES: Any
30
+ SILENCE: Any
31
+ TRANSFORMERS: Any
32
+ TRANSITION: Any
33
+ VALID_END_OPERATORS: Any
34
+ VALID_START_OPERATORS: Any
35
+ canonical_operator_name: Any
36
+ operator_display_name: Any