Spaces:
Running
Running
R6A-R4-R2 quote translation ledger identity type safety
#41
by GuXiaopeng - opened
- core/generation_runner.py +56 -7
core/generation_runner.py
CHANGED
|
@@ -608,6 +608,41 @@ class GenerationRunner:
|
|
| 608 |
and str(item.get("quote") or "").strip()
|
| 609 |
}
|
| 610 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 611 |
@classmethod
|
| 612 |
def _prepare_qualitative_translation_source(cls, source, quote_sources, quote_ledger):
|
| 613 |
"""Use one task-level target rendering for every frozen qualitative quote.
|
|
@@ -953,20 +988,34 @@ class GenerationRunner:
|
|
| 953 |
english_commit_text=english_commit_text,
|
| 954 |
)
|
| 955 |
updated_sections = dict(translation_sections or {})
|
| 956 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 957 |
current_quote_hashes = {
|
| 958 |
tag: hashlib.sha256(re.sub(r"\s+", " ", quote).strip().encode("utf-8")).hexdigest()
|
| 959 |
for tag, quote in getattr(self, "_qualitative_quote_sources", {}).items()
|
| 960 |
}
|
| 961 |
current_request_hash = str(getattr(self, "request_hash", "") or "")
|
| 962 |
-
|
| 963 |
-
ledger_identity_ok = (
|
| 964 |
-
quote_ledger_record
|
| 965 |
-
|
| 966 |
-
|
|
|
|
|
|
|
|
|
|
| 967 |
)
|
|
|
|
| 968 |
quote_ledger = (
|
| 969 |
-
dict(
|
|
|
|
|
|
|
| 970 |
)
|
| 971 |
translation_source, pending_quote_tags, reused_quote_tags = self._prepare_qualitative_translation_source(
|
| 972 |
source, getattr(self, "_qualitative_quote_sources", {}), quote_ledger
|
|
|
|
| 608 |
and str(item.get("quote") or "").strip()
|
| 609 |
}
|
| 610 |
|
| 611 |
+
@staticmethod
|
| 612 |
+
def _qualitative_quote_ledger_identity_ok(
|
| 613 |
+
record, *, target_lang: str, request_hash: str, source_quote_hashes: dict,
|
| 614 |
+
task_id: str = "", translation_contract_version: str = TRANSLATION_CONTRACT_VERSION,
|
| 615 |
+
) -> bool:
|
| 616 |
+
"""Type-safe identity gate for task-level target-language Quote reuse.
|
| 617 |
+
|
| 618 |
+
Missing scalar identity fields remain backward-compatible with pre-R4
|
| 619 |
+
checkpoints. Present fields must be strings and match exactly. Quote
|
| 620 |
+
hashes must be a mapping and match the current frozen English evidence.
|
| 621 |
+
execution_epoch is deliberately not part of logical identity so a newer
|
| 622 |
+
epoch can reuse the same QA-passed target rendering for the same task.
|
| 623 |
+
"""
|
| 624 |
+
if not isinstance(record, dict) or not isinstance(source_quote_hashes, dict):
|
| 625 |
+
return False
|
| 626 |
+
|
| 627 |
+
def scalar_matches(stored, current: str) -> bool:
|
| 628 |
+
if stored is None or stored == "":
|
| 629 |
+
return True
|
| 630 |
+
return isinstance(stored, str) and stored == str(current or "")
|
| 631 |
+
|
| 632 |
+
stored_hashes = record.get("source_quote_hashes")
|
| 633 |
+
if stored_hashes is None or stored_hashes == "":
|
| 634 |
+
hashes_match = True
|
| 635 |
+
else:
|
| 636 |
+
hashes_match = isinstance(stored_hashes, dict) and stored_hashes == source_quote_hashes
|
| 637 |
+
|
| 638 |
+
return (
|
| 639 |
+
scalar_matches(record.get("task_id"), task_id)
|
| 640 |
+
and scalar_matches(record.get("target_lang"), target_lang)
|
| 641 |
+
and scalar_matches(record.get("request_hash"), request_hash)
|
| 642 |
+
and scalar_matches(record.get("translation_contract_version"), translation_contract_version)
|
| 643 |
+
and hashes_match
|
| 644 |
+
)
|
| 645 |
+
|
| 646 |
@classmethod
|
| 647 |
def _prepare_qualitative_translation_source(cls, source, quote_sources, quote_ledger):
|
| 648 |
"""Use one task-level target rendering for every frozen qualitative quote.
|
|
|
|
| 988 |
english_commit_text=english_commit_text,
|
| 989 |
)
|
| 990 |
updated_sections = dict(translation_sections or {})
|
| 991 |
+
raw_quote_ledger_record = updated_sections.get("__quote_ledger__")
|
| 992 |
+
if raw_quote_ledger_record is not None and not isinstance(raw_quote_ledger_record, dict):
|
| 993 |
+
logging.warning(
|
| 994 |
+
"Qualitative quote translation ledger ignored malformed record type=%s",
|
| 995 |
+
type(raw_quote_ledger_record).__name__,
|
| 996 |
+
)
|
| 997 |
+
quote_ledger_record = (
|
| 998 |
+
dict(raw_quote_ledger_record) if isinstance(raw_quote_ledger_record, dict) else {}
|
| 999 |
+
)
|
| 1000 |
current_quote_hashes = {
|
| 1001 |
tag: hashlib.sha256(re.sub(r"\s+", " ", quote).strip().encode("utf-8")).hexdigest()
|
| 1002 |
for tag, quote in getattr(self, "_qualitative_quote_sources", {}).items()
|
| 1003 |
}
|
| 1004 |
current_request_hash = str(getattr(self, "request_hash", "") or "")
|
| 1005 |
+
current_task_id = str(getattr(getattr(self, "task_dir", None), "name", "") or "")
|
| 1006 |
+
ledger_identity_ok = self._qualitative_quote_ledger_identity_ok(
|
| 1007 |
+
quote_ledger_record,
|
| 1008 |
+
task_id=current_task_id,
|
| 1009 |
+
target_lang=target_lang,
|
| 1010 |
+
request_hash=current_request_hash,
|
| 1011 |
+
translation_contract_version=TRANSLATION_CONTRACT_VERSION,
|
| 1012 |
+
source_quote_hashes=current_quote_hashes,
|
| 1013 |
)
|
| 1014 |
+
stored_translations = quote_ledger_record.get("translations")
|
| 1015 |
quote_ledger = (
|
| 1016 |
+
dict(stored_translations)
|
| 1017 |
+
if ledger_identity_ok and isinstance(stored_translations, dict)
|
| 1018 |
+
else {}
|
| 1019 |
)
|
| 1020 |
translation_source, pending_quote_tags, reused_quote_tags = self._prepare_qualitative_translation_source(
|
| 1021 |
source, getattr(self, "_qualitative_quote_sources", {}), quote_ledger
|