@@ -793,10 +793,19 @@ def _consume(self, token: str, index: int) -> None:
793793 if canonical == DISSONANCE :
794794 self ._found_dissonance = True
795795
796- # Track THOL state: Use balanced nesting to allow SILENCE/CONTRACTION inside THOL
797- # TNFR Physical Principle: THOL applies as operator, bifurcates if d2_epi > tau
798- # Empty THOL valid (no bifurcation), non-empty must be grammatically coherent
799- # Closure: First SILENCE/CONTRACTION at nesting depth 0 closes THOL
796+ # Track THOL state: Structural time with automatic closure
797+ #
798+ # TNFR Structural Time Principle: THOL closure emerges from bifurcation completion,
799+ # not from operator detection. Internal sequences are equivalent to external ones.
800+ #
801+ # Implementation for static validation:
802+ # - THOL opens a nested context
803+ # - Operators inside THOL are treated as normal sequence (can include SILENCE, etc.)
804+ # - THOL closes automatically at sequence end or parent THOL closure
805+ # - Nested THOL are supported (operational fractality)
806+ #
807+ # This allows internal sequences to be identical to external ones, including
808+ # having their own THOL blocks and using any valid end operators.
800809 if canonical == SELF_ORGANIZATION :
801810 # THOL opening: push to stack and initialize subsequence
802811 self ._thol_stack .append (index )
@@ -805,32 +814,9 @@ def _consume(self, token: str, index: int) -> None:
805814 elif self ._open_thol and self ._thol_stack :
806815 current_thol = self ._thol_stack [- 1 ]
807816
808- # Check if this operator closes THOL BEFORE adding to subsequence
809- # This allows SILENCE/CONTRACTION inside THOL as sequence operators
810- if canonical in SELF_ORGANIZATION_CLOSURES :
811- # Count nested THOL blocks to determine nesting depth
812- subseq = self ._thol_subsequences [current_thol ]
813- nested_thol_count = 0
814- for op in subseq :
815- if op == SELF_ORGANIZATION :
816- nested_thol_count += 1
817- elif op in SELF_ORGANIZATION_CLOSURES :
818- nested_thol_count -= 1
819-
820- # Close THOL if we're at depth 0 (no unclosed nested THOL)
821- if nested_thol_count == 0 :
822- thol_start = self ._thol_stack .pop ()
823- final_subseq = self ._thol_subsequences [thol_start ]
824-
825- # Validate THOL subsequence
826- # Empty THOL valid (no bifurcation), non-empty must be coherent
827- self ._validate_thol_subsequence (final_subseq , thol_start , index , token )
828-
829- # Update _open_thol based on stack state (supports nested THOL)
830- self ._open_thol = bool (self ._thol_stack )
831- return # Don't add closure operator to subsequence
832-
833- # Add operator to current THOL subsequence
817+ # All operators inside THOL are added to subsequence
818+ # No operator-based closure detection - THOL closes structurally
819+ # This allows internal sequences to be identical to external ones
834820 self ._thol_subsequences [current_thol ].append (canonical )
835821
836822 # Validate sequential compatibility if not first token
@@ -1272,13 +1258,32 @@ def _finalize(self, names: Sequence[str]) -> None:
12721258 message = f"C3: missing stabilizer ({ operator_display_name (COHERENCE )} or { operator_display_name (SELF_ORGANIZATION )} ) - integral divergence (BOUNDEDNESS constraint)" ,
12731259 )
12741260
1275- # Self-organization block closure
1261+ # Self-organization block closure (structural time)
1262+ # THOL closes automatically at sequence end - validates all captured subsequences
12761263 if self ._open_thol :
1277- raise SequenceSyntaxError (
1278- index = len (names ) - 1 ,
1279- token = names [- 1 ],
1280- message = f"C3: { operator_display_name (SELF_ORGANIZATION )} block without closure" ,
1281- )
1264+ # Close all open THOL blocks from innermost to outermost
1265+ while self ._thol_stack :
1266+ thol_start = self ._thol_stack .pop ()
1267+ thol_subseq = self ._thol_subsequences [thol_start ]
1268+
1269+ # Validate subsequence (allows empty THOL - no bifurcation case)
1270+ if len (thol_subseq ) > 0 :
1271+ try :
1272+ self ._validate_thol_subsequence (
1273+ thol_subseq ,
1274+ thol_start ,
1275+ len (names ) - 1 ,
1276+ names [- 1 ] if names else ""
1277+ )
1278+ except SequenceSyntaxError as e :
1279+ # Re-raise with THOL context
1280+ raise SequenceSyntaxError (
1281+ index = e .index ,
1282+ token = e .token ,
1283+ message = f"Invalid THOL subsequence (opened at position { thol_start } ): { e .message } "
1284+ ) from e
1285+
1286+ self ._open_thol = False
12821287
12831288 # ═══════════════════════════════════════════════════════════════════
12841289 # C2: CONTINUITY & C4: THRESHOLD PHYSICS
0 commit comments