Commit ·
bd94153
1
Parent(s): c98b613
debug(punctuation): enhanced lock logging to show which owner blocks punctuation
Browse filesAdded is_locked_by() to StageLocker that returns (start, end, owner).
Logs now show: locked by spelling[59:63] or locked by grammar[73:81]
This helps identify WHY punctuation marks get blocked.
- src/app.py +7 -4
- src/nlp/stage_locker.py +7 -0
src/app.py
CHANGED
|
@@ -1156,21 +1156,24 @@ def analyze_text():
|
|
| 1156 |
for d in diffs:
|
| 1157 |
# StageLocker: skip diffs that overlap with locked ranges
|
| 1158 |
# BUT allow pure punctuation insertions near locked words
|
| 1159 |
-
|
|
|
|
| 1160 |
import re as _re
|
| 1161 |
orig_alpha = _re.sub(r'[^\u0600-\u06FFa-zA-Z]', '', d.get('original', ''))
|
| 1162 |
corr_alpha = _re.sub(r'[^\u0600-\u06FFa-zA-Z]', '', d.get('correction', ''))
|
|
|
|
| 1163 |
if orig_alpha != corr_alpha:
|
| 1164 |
# Diff changes actual words — block it
|
| 1165 |
logger.info(
|
| 1166 |
f"[LOCK] Punctuation blocked on [{d['start']}:{d['end']}] "
|
| 1167 |
-
f"'{d.get('original','')}' \u2014 locked by
|
| 1168 |
)
|
| 1169 |
continue
|
| 1170 |
-
# Arabic text unchanged
|
| 1171 |
logger.info(
|
| 1172 |
f"[LOCK] Punctuation ALLOWED through lock [{d['start']}:{d['end']}] "
|
| 1173 |
-
f"'{d.get('original','')}' \u2192 '{d.get('correction','')}'
|
|
|
|
| 1174 |
)
|
| 1175 |
# Punctuation safety layer: reject non-punctuation changes
|
| 1176 |
if not validate_punctuation_diff(d):
|
|
|
|
| 1156 |
for d in diffs:
|
| 1157 |
# StageLocker: skip diffs that overlap with locked ranges
|
| 1158 |
# BUT allow pure punctuation insertions near locked words
|
| 1159 |
+
lock_info = ctx.stage_locker.is_locked_by(d['start'], d['end'])
|
| 1160 |
+
if lock_info:
|
| 1161 |
import re as _re
|
| 1162 |
orig_alpha = _re.sub(r'[^\u0600-\u06FFa-zA-Z]', '', d.get('original', ''))
|
| 1163 |
corr_alpha = _re.sub(r'[^\u0600-\u06FFa-zA-Z]', '', d.get('correction', ''))
|
| 1164 |
+
ls, le, owner = lock_info
|
| 1165 |
if orig_alpha != corr_alpha:
|
| 1166 |
# Diff changes actual words — block it
|
| 1167 |
logger.info(
|
| 1168 |
f"[LOCK] Punctuation blocked on [{d['start']}:{d['end']}] "
|
| 1169 |
+
f"'{d.get('original','')}' \u2014 locked by {owner}[{ls}:{le}]"
|
| 1170 |
)
|
| 1171 |
continue
|
| 1172 |
+
# Arabic text unchanged — only punctuation added/moved. Allow through.
|
| 1173 |
logger.info(
|
| 1174 |
f"[LOCK] Punctuation ALLOWED through lock [{d['start']}:{d['end']}] "
|
| 1175 |
+
f"'{d.get('original','')}' \u2192 '{d.get('correction','')}' "
|
| 1176 |
+
f"(locked by {owner}[{ls}:{le}])"
|
| 1177 |
)
|
| 1178 |
# Punctuation safety layer: reject non-punctuation changes
|
| 1179 |
if not validate_punctuation_diff(d):
|
src/nlp/stage_locker.py
CHANGED
|
@@ -42,6 +42,13 @@ class StageLocker:
|
|
| 42 |
return True
|
| 43 |
return False
|
| 44 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
def update_via_mapper(self, mapper) -> None:
|
| 46 |
"""
|
| 47 |
Shift all locked spans to match the new CURRENT_TEXT after mutation.
|
|
|
|
| 42 |
return True
|
| 43 |
return False
|
| 44 |
|
| 45 |
+
def is_locked_by(self, start: int, end: int):
|
| 46 |
+
"""Return (locked_start, locked_end, owner) if locked, else None."""
|
| 47 |
+
for ls, le, owner in self.locked_spans:
|
| 48 |
+
if start < le and end > ls:
|
| 49 |
+
return (ls, le, owner)
|
| 50 |
+
return None
|
| 51 |
+
|
| 52 |
def update_via_mapper(self, mapper) -> None:
|
| 53 |
"""
|
| 54 |
Shift all locked spans to match the new CURRENT_TEXT after mutation.
|