Skip to content

Commit e6b8838

Browse files
Copilotfermga
andcommitted
Implement ZHIR threshold verification (∂EPI/∂t > ξ) - core implementation
Co-authored-by: fermga <203334638+fermga@users.noreply.github.com>
1 parent f8205f9 commit e6b8838

File tree

4 files changed

+399
-3
lines changed

4 files changed

+399
-3
lines changed

src/tnfr/operators/definitions.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3121,14 +3121,34 @@ class Mutation(Operator):
31213121
random variation, ZHIR is controlled transformation that preserves structural identity
31223122
while shifting operational regime. Critical for adaptation and evolution.
31233123
3124+
**Canonical Threshold Requirement (∂EPI/∂t > ξ)**:
3125+
3126+
According to TNFR physics (AGENTS.md §11, TNFR.pdf §2.2.11), ZHIR requires sufficient
3127+
structural change velocity to justify phase transformation. The threshold ξ (default 0.1)
3128+
represents the minimum rate of reorganization needed for meaningful mutation.
3129+
3130+
- **∂EPI/∂t ≥ ξ**: Mutation validated, phase transformation proceeds
3131+
- **∂EPI/∂t < ξ**: Warning logged, mutation may lack structural justification
3132+
- **Insufficient history**: Warning logged, threshold cannot be verified
3133+
3134+
Configuration: Set ``G.graph["ZHIR_THRESHOLD_XI"]`` to customize threshold (default: 0.1).
3135+
3136+
Metrics: Threshold verification included in mutation_metrics() telemetry:
3137+
- ``depi_dt``: Computed structural change velocity
3138+
- ``threshold_met``: Boolean flag indicating threshold status
3139+
- ``threshold_ratio``: Ratio of velocity to threshold
3140+
31243141
Use Cases: Paradigm shifts, strategic pivots, adaptive responses, regime transitions,
31253142
identity transformation while maintaining continuity.
31263143
31273144
Typical Sequences: IL → ZHIR → IL (stabilize-mutate-stabilize), OZ → ZHIR (dissonance
31283145
enables mutation), ZHIR → NAV → IL (mutate-transition-stabilize).
31293146
3130-
Preconditions: Requires stable base (often IL), sufficient ΔNFR for phase change,
3131-
network support for new phase.
3147+
Preconditions:
3148+
- Minimum νf for phase transformation capacity (ZHIR_MIN_VF, default: 0.05)
3149+
- **Structural velocity threshold (∂EPI/∂t > ξ)** - validated with EPI history
3150+
- Stable base (often IL) validated by grammar U4b
3151+
- Network support for new phase
31323152
31333153
Examples
31343154
--------

src/tnfr/operators/metrics.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1546,6 +1546,9 @@ def mutation_metrics(
15461546
) -> dict[str, Any]:
15471547
"""ZHIR - Mutation metrics: phase transition, structural regime change.
15481548
1549+
Collects mutation-specific metrics including canonical threshold verification
1550+
(∂EPI/∂t > ξ) as per TNFR physics (AGENTS.md §11, TNFR.pdf §2.2.11).
1551+
15491552
Parameters
15501553
----------
15511554
G : TNFRGraph
@@ -1560,19 +1563,46 @@ def mutation_metrics(
15601563
Returns
15611564
-------
15621565
dict
1563-
Mutation-specific metrics including phase change indicators
1566+
Mutation-specific metrics including:
1567+
- Phase change indicators (theta_shift, phase_change)
1568+
- EPI change (delta_epi)
1569+
- **Threshold verification**: depi_dt, threshold_met, threshold_ratio
1570+
- Structural justification flags
15641571
"""
15651572
theta_after = _get_node_attr(G, node, ALIAS_THETA)
15661573
epi_after = _get_node_attr(G, node, ALIAS_EPI)
15671574

1575+
# Compute ∂EPI/∂t from history
1576+
epi_history = G.nodes[node].get("epi_history") or G.nodes[node].get("_epi_history", [])
1577+
if len(epi_history) >= 2:
1578+
depi_dt = abs(epi_history[-1] - epi_history[-2])
1579+
else:
1580+
depi_dt = 0.0
1581+
1582+
# Check threshold
1583+
xi = float(G.graph.get("ZHIR_THRESHOLD_XI", 0.1))
1584+
threshold_met = depi_dt >= xi
1585+
threshold_ratio = depi_dt / xi if xi > 0 else 0.0
1586+
15681587
return {
15691588
"operator": "Mutation",
15701589
"glyph": "ZHIR",
1590+
# Existing metrics
15711591
"theta_shift": abs(theta_after - theta_before),
15721592
"theta_final": theta_after,
15731593
"delta_epi": epi_after - epi_before,
15741594
"epi_final": epi_after,
15751595
"phase_change": abs(theta_after - theta_before) > 0.5, # Configurable threshold
1596+
# NEW: Threshold verification metrics
1597+
"depi_dt": depi_dt,
1598+
"threshold_xi": xi,
1599+
"threshold_met": threshold_met,
1600+
"threshold_ratio": threshold_ratio,
1601+
"threshold_exceeded_by": max(0.0, depi_dt - xi),
1602+
# Structural justification flags from preconditions
1603+
"threshold_warning": G.nodes[node].get("_zhir_threshold_warning", False),
1604+
"threshold_validated": G.nodes[node].get("_zhir_threshold_met", False),
1605+
"threshold_unknown": G.nodes[node].get("_zhir_threshold_unknown", False),
15761606
}
15771607

15781608

src/tnfr/operators/preconditions/__init__.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,12 @@ def _record_destabilizer_context(
990990
def validate_mutation(G: "TNFRGraph", node: "NodeId") -> None:
991991
"""ZHIR - Mutation requires node to be in valid structural state.
992992
993+
Implements canonical TNFR requirements for mutation (AGENTS.md §11, TNFR.pdf §2.2.11):
994+
995+
1. Minimum νf for phase transformation capacity
996+
2. **∂EPI/∂t > ξ: Structural change velocity exceeds threshold**
997+
3. Stable base (IL precedence validated by grammar U4b)
998+
993999
Also detects and records the destabilizer type that enabled this mutation
9941000
for telemetry and structural tracing purposes.
9951001
@@ -1007,6 +1013,16 @@ def validate_mutation(G: "TNFRGraph", node: "NodeId") -> None:
10071013
10081014
Notes
10091015
-----
1016+
**Canonical threshold verification (∂EPI/∂t > ξ)**:
1017+
1018+
ZHIR is a phase transformation that requires sufficient structural reorganization
1019+
velocity to justify the transition. The threshold ξ represents the minimum rate
1020+
of structural change needed for a phase shift to be physically meaningful.
1021+
1022+
- If ∂EPI/∂t < ξ: Logs warning (soft check for backward compatibility)
1023+
- If ∂EPI/∂t ≥ ξ: Logs success, sets validation flag
1024+
- If insufficient history: Logs warning, cannot verify
1025+
10101026
This function implements R4 Extended telemetry by analyzing the glyph_history
10111027
to determine which destabilizer (strong/moderate/weak) enabled the mutation.
10121028
The destabilizer context is stored in node metadata for structural tracing.
@@ -1024,6 +1040,41 @@ def validate_mutation(G: "TNFRGraph", node: "NodeId") -> None:
10241040
f"Structural frequency too low for mutation (νf={vf:.3f} < {min_vf:.3f})",
10251041
)
10261042

1043+
# NEW: Threshold crossing validation (∂EPI/∂t > ξ)
1044+
# Get EPI history - check both keys for compatibility
1045+
epi_history = G.nodes[node].get("epi_history") or G.nodes[node].get("_epi_history", [])
1046+
1047+
if len(epi_history) >= 2:
1048+
# Compute ∂EPI/∂t (discrete approximation using last two points)
1049+
# For discrete operator applications with Δt=1: ∂EPI/∂t ≈ EPI_t - EPI_{t-1}
1050+
depi_dt = abs(epi_history[-1] - epi_history[-2])
1051+
1052+
# Get threshold from configuration
1053+
xi_threshold = float(G.graph.get("ZHIR_THRESHOLD_XI", 0.1))
1054+
1055+
# Verify threshold crossed
1056+
if depi_dt < xi_threshold:
1057+
# Allow mutation but log warning (soft check for backward compatibility)
1058+
logger.warning(
1059+
f"Node {node}: ZHIR applied with ∂EPI/∂t={depi_dt:.3f} < ξ={xi_threshold}. "
1060+
f"Mutation may lack structural justification. "
1061+
f"Consider increasing dissonance (OZ) first."
1062+
)
1063+
G.nodes[node]["_zhir_threshold_warning"] = True
1064+
else:
1065+
# Threshold met - log success
1066+
logger.info(
1067+
f"Node {node}: ZHIR threshold crossed (∂EPI/∂t={depi_dt:.3f} > ξ={xi_threshold})"
1068+
)
1069+
G.nodes[node]["_zhir_threshold_met"] = True
1070+
else:
1071+
# Insufficient history - cannot verify threshold
1072+
logger.warning(
1073+
f"Node {node}: ZHIR applied without sufficient EPI history "
1074+
f"(need ≥2 points, have {len(epi_history)}). Cannot verify threshold."
1075+
)
1076+
G.nodes[node]["_zhir_threshold_unknown"] = True
1077+
10271078
# R4 Extended: Detect and record destabilizer type for telemetry
10281079
# This provides structural traceability for bifurcation events
10291080
_record_destabilizer_context(G, node, logger)

0 commit comments

Comments
 (0)