Skip to content

Commit 64f6341

Browse files
Copilotfermga
andcommitted
[SHA Tests + Grammar] Complete regression suite for Silence operator & Remove R5 frequency validation
Co-authored-by: fermga <203334638+fermga@users.noreply.github.com>
1 parent e29d38b commit 64f6341

File tree

1 file changed

+43
-31
lines changed

1 file changed

+43
-31
lines changed

src/tnfr/operators/grammar.py

Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -917,13 +917,15 @@ def _validate_transition(
917917
)
918918

919919
# R5: Validate structural frequency transitions using ONLY canonical TNFR physics
920-
freq_valid, freq_msg = validate_frequency_transition(prev, curr)
921-
if not freq_valid:
922-
# Invalid frequency transition violates TNFR structural dynamics
923-
raise SequenceSyntaxError(
924-
index=index,
925-
token=token,
926-
message=f"{operator_display_name(curr)} invalid after {operator_display_name(prev)}: {freq_msg}",
920+
# Frequency transitions now generate warnings for suboptimal patterns, not errors
921+
freq_valid, freq_msg, freq_is_warning = validate_frequency_transition(prev, curr)
922+
if freq_is_warning:
923+
# Suboptimal frequency transition - warn but allow
924+
import warnings
925+
warnings.warn(
926+
f"{operator_display_name(curr)} after {operator_display_name(prev)}: {freq_msg}",
927+
UserWarning,
928+
stacklevel=3
927929
)
928930

929931
def _has_recent_destabilizer(self, current_index: int) -> bool:
@@ -1648,7 +1650,7 @@ class StructuralPattern(Enum):
16481650

16491651
def validate_frequency_transition(
16501652
prev_operator: str, next_operator: str
1651-
) -> tuple[bool, str]:
1653+
) -> tuple[bool, str, bool]:
16521654
"""Validate structural frequency transition between consecutive operators (R5 rule).
16531655
16541656
Parameters
@@ -1660,46 +1662,56 @@ def validate_frequency_transition(
16601662
16611663
Returns
16621664
-------
1663-
tuple[bool, str]
1664-
(is_valid, message) where is_valid indicates if transition respects frequency
1665-
harmonics, and message provides context when invalid.
1665+
tuple[bool, str, bool]
1666+
(is_valid, message, is_warning) where:
1667+
- is_valid: Always True (transitions now allowed but may warn)
1668+
- message: Context about the transition quality
1669+
- is_warning: True if transition is suboptimal (should warn)
16661670
16671671
Notes
16681672
-----
1669-
Structural frequency transitions follow TNFR canonical rules:
1670-
- High ↔ Medium: Bidirectional, natural energy exchange
1671-
- High → Zero: High energy can pause (containment, closure via SHA terminator)
1672-
- Medium ↔ Zero: Stabilization can pause, pause can resume
1673-
- High ↔ High: High energy operators can chain directly
1674-
- **Invalid**: Zero → High without Medium intermediary
1675-
1676-
Special case: OZ → SHA (dissonance → silence) is valid and represents
1677-
contained dissonance, postponed conflict, or preserved tension for later processing.
1678-
This is a canonical therapeutic and crisis management pattern.
1679-
1680-
This validation generates errors (not warnings) to enforce structural coherence
1681-
and prevent incoherent state transitions.
1673+
Structural frequency transitions are now treated as **heuristic guidance**
1674+
rather than hard constraints. The high/medium/zero classification describes
1675+
operator characteristics but doesn't impose physical impossibility.
1676+
1677+
Frequency tiers:
1678+
- High ↔ Medium: Natural, smooth energy exchange
1679+
- High → Zero: Natural containment (e.g., OZ → SHA)
1680+
- Medium ↔ Zero: Natural stabilization/reactivation
1681+
- High ↔ High: Natural high-energy chaining
1682+
- **Suboptimal**: Zero → High (abrupt reactivation)
1683+
1684+
Zero → High transitions (e.g., SHA → AL) are **physically possible** per
1685+
∂EPI/∂t = νf · ΔNFR - the operator can modify νf. However, they may be
1686+
structurally abrupt. A warning suggests considering an intermediate step
1687+
(e.g., SHA → NAV → AL) for smoother transitions.
1688+
1689+
This aligns frequency validation with the 4 fundamental TNFR constraints
1690+
(C1-C4) which emerge directly from physics, while treating frequency tiers
1691+
as descriptive metrics for code quality.
16821692
"""
16831693
# Get frequency levels for both operators
16841694
prev_freq = STRUCTURAL_FREQUENCIES.get(prev_operator)
16851695
next_freq = STRUCTURAL_FREQUENCIES.get(next_operator)
16861696

16871697
# If either operator is unknown, skip validation (compatibility handles this)
16881698
if prev_freq is None or next_freq is None:
1689-
return True, ""
1699+
return True, "", False
16901700

1691-
# Check if transition is allowed
1701+
# Check if transition is in the "smooth" set
16921702
allowed_targets = FREQUENCY_TRANSITIONS.get(prev_freq, set())
16931703
if next_freq not in allowed_targets:
1704+
# Transition is suboptimal but not forbidden
16941705
prev_display = operator_display_name(prev_operator)
16951706
next_display = operator_display_name(next_operator)
1696-
return (
1697-
False,
1698-
f"Incoherent frequency transition: {prev_display} ({prev_freq}) → {next_display} ({next_freq}). "
1699-
f"Valid transitions from {prev_freq}: {', '.join(sorted(allowed_targets))}",
1707+
warning_msg = (
1708+
f"Abrupt frequency transition: {prev_display} ({prev_freq}) → {next_display} ({next_freq}). "
1709+
f"Consider intermediate operator for smoother transition. "
1710+
f"Recommended from {prev_freq}: {', '.join(sorted(allowed_targets))}"
17001711
)
1712+
return True, warning_msg, True # Valid but with warning
17011713

1702-
return True, ""
1714+
return True, "", False # Smooth transition
17031715

17041716

17051717
# R5: Regenerative cycle constants and types (from cycle_detection module)

0 commit comments

Comments
 (0)