公開前の確認用サイト
日常訳NICHIJOYAKUEnglish ↗

OPEN SOURCE

software/src/output/repair_review.py

このサイトで読み、必要なファイルを保存できます。

日常訳はAIを用いて作成された翻訳です。人間の聖書学・原語の専門家による全訳の検証は確認されていません。既存の翻訳や原語資料と照らし合わせてお読みください。

← オープンソースの案内へ

software/src/output/repair_review.py70 行このファイルを保存 ↓

ZIPに含まれるものと同じ公開ソースです。行番号から、その行へのリンクを保存できます。

ファイルの確認情報SHA-256 cae40a452628d44985b80c7b904d29e20ce08e73309704784bbb0d39407c6aac
1"""Import complete, text-bound editorial decisions into the alignment manifest."""2from __future__ import annotations34from copy import deepcopy5import hashlib6import json7from pathlib import Path89from src.output.alignment import candidate_hashes, digest, validate_repair101112def indexed(rows):13    result = {row['target']: row for row in rows}14    if len(result) != len(rows):15        raise ValueError('Duplicate review targets')16    return result171819def import_bundle(review_path, bundle_path, out):20    review_path, bundle_path, out = Path(review_path), Path(bundle_path), Path(out).resolve()21    if out in (review_path.resolve(), bundle_path.resolve()):22        raise ValueError('Imported review must not overwrite its evidence inputs')23    original = review_path.read_bytes()24    evidence = bundle_path.read_bytes()25    bundle = json.loads(evidence)26    if hashlib.sha256(original).hexdigest() != bundle['input_review_sha256']:27        raise ValueError('Repair bundle belongs to a different input review')28    review = json.loads(original)29    result = merge_repairs(review, bundle['packets'], bundle['decisions'], bundle['verification'],30                           hashlib.sha256(evidence).hexdigest())31    result['repair_source_files'] = bundle['source_files']32    result['usage'] = {'initial_alignment': review['usage'], 'repair_round': bundle['usage']}33    out.parent.mkdir(parents=True, exist_ok=True)34    out.write_text(json.dumps(result, ensure_ascii=False, indent=2) + '\n')35    return len(result['target_repairs'])363738def merge_repairs(review, packets, decisions, verification, evidence_sha256):39    """Require a passing verification of each exact final text before import."""40    packets, decisions, verification = map(indexed, (packets, decisions, verification))41    if packets.keys() != decisions.keys() or packets.keys() != verification.keys():42        raise ValueError('Incomplete or unexpected repair review targets')43    result = deepcopy(review)44    repairs = result.setdefault('target_repairs', {})45    for target, packet in packets.items():46        decision, check = decisions[target], verification[target]47        if check['status'] != 'pass' or check['text_sha256'] != digest(decision['text']):48            raise ValueError(f'Repair lacks passing verification of final text: {target}')49        if decision.get('boundary_issue') and not check.get('boundary_resolution'):50            raise ValueError(f'Unresolved source boundary: {target}')51        selected = decision['selected_sources']52        choices = {item['source']: item['text'] for item in packet['candidates']}53        if selected and (len(set(selected)) != len(selected) or set(selected) - choices.keys() or54                         ''.join(choices[source] for source in selected) != decision['text']):55            raise ValueError(f'Selected text does not match candidate sources: {target}')56        repair = {'text': decision['text'], 'expected_candidates': candidate_hashes(packet['candidates']),57                  'selected_sources': selected, 'reason': decision['reason'],58                  'evidence_sha256': evidence_sha256, 'verified_by': check['reviewer'],59                  'verification': check, 'original_sources': packet['source_spans']}60        validate_repair(target, repair, packet['candidates'])61        repairs[target] = repair62        for source in packet.get('held_sources', []):63            prior = result['records'][source]64            if prior['mapped_targets'] != [target] or prior['decision'] not in ('mixed', 'unclear'):65                raise ValueError(f'Held record mapping changed: {source}')66            prior['pre_repair_review'] = deepcopy(prior)67            prior.update(decision='mapped', reviewer=check['reviewer'],68                         reason=f'Original ambiguous candidate retained in audit; verified target repair supplies {target}.')69    return result70