95 lines
5.1 KiB
Python
95 lines
5.1 KiB
Python
#!/usr/bin/env python3
|
||
"""exp15 — BLIND reading packets for the owner (§D3 human endpoint: metrics NOMINATE, blind read RATIFIES,
|
||
planка = <=2 claims/chapter). Presents the SAME opening source passage translated 3 ways — flat-A0-30
|
||
(blind-greedy baseline), oracle-30 (seam-aligned), q3a-src (source-carryover arm) — under SHUFFLED neutral
|
||
labels (V1/V2/V3), with a separate key. The owner reads without knowing which is which and counts claims.
|
||
|
||
Deterministic shuffle (fixed seed). Outputs to exp15/monitor/ (blind packet + key, key kept separate).
|
||
Run: python blind_packets.py
|
||
"""
|
||
from __future__ import annotations
|
||
import json
|
||
import random
|
||
import sqlite3
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
||
from chunker import greedy_chunks
|
||
|
||
SD = Path("/home/ubuntu/books/gu-zhenren/exp15")
|
||
AH = SD / "anchors"
|
||
MON = SD / "monitor"
|
||
N_CHUNKS = 6 # ~first 3-4 节 of the opening (readable passage)
|
||
|
||
|
||
def db_finals(db):
|
||
con = sqlite3.connect(db)
|
||
out = {}
|
||
for ck, txt in con.execute("SELECT chunk_idx, response_text FROM checkpoints WHERE stage='edit' ORDER BY chunk_idx, attempt"):
|
||
out[ck] = txt
|
||
con.close()
|
||
return out
|
||
|
||
|
||
def main():
|
||
MON.mkdir(parents=True, exist_ok=True)
|
||
flat_src = greedy_chunks((SD / "S2prime_big_flat.txt").read_text(encoding="utf-8"))
|
||
oracle_src = greedy_chunks((SD / "S2prime_big_blanklines.txt").read_text(encoding="utf-8"))
|
||
flat_fin = db_finals(AH / "flat_a0_30.db")
|
||
oracle_fin = db_finals(AH / "oracle_30.db")
|
||
|
||
# source span covered by the first N flat chunks (used for oracle coverage matching AND now shown as
|
||
# the fidelity reference — the reader compares each version against this original for omissions/errors)
|
||
src_span = "".join(flat_src[:N_CHUNKS])
|
||
src_display = "\n\n".join(flat_src[:N_CHUNKS]) # paragraph-joined for readability
|
||
# flat + q3a-src share flat chunking; oracle differs -> take oracle chunks until it covers ~the same source len
|
||
flat_text = "\n\n".join(flat_fin[i] for i in range(N_CHUNKS) if i in flat_fin)
|
||
arm_dir = SD / "arms" / "q3a-src"
|
||
src_arm = "\n\n".join((arm_dir / f"{i:02d}.final.txt").read_text(encoding="utf-8")
|
||
for i in range(N_CHUNKS) if (arm_dir / f"{i:02d}.final.txt").exists())
|
||
# oracle: chunks whose cumulative source length ~covers src_span
|
||
cov, oi, otexts = 0, 0, []
|
||
target = len(src_span)
|
||
while oi < len(oracle_src) and cov < target:
|
||
if oi in oracle_fin:
|
||
otexts.append(oracle_fin[oi])
|
||
cov += len(oracle_src[oi]); oi += 1
|
||
oracle_text = "\n\n".join(otexts)
|
||
|
||
arms = {"flat-A0-30 (blind greedy baseline)": flat_text,
|
||
"oracle-30 (seam-aligned)": oracle_text,
|
||
"q3a-src (source-carryover)": src_arm}
|
||
labels = ["V1", "V2", "V3"]
|
||
keys = list(arms.keys())
|
||
rnd = random.Random("exp15-blind-2026-07-18")
|
||
rnd.shuffle(keys)
|
||
mapping = dict(zip(labels, keys)) # V1->arm, ...
|
||
|
||
# blind packet (no arm names) — original source at top for FIDELITY comparison, then the 3 versions
|
||
pkt = [f"# exp15 — СЛЕПОЙ ПАКЕТ для чтения (открывающий фрагмент 蛊真人, ~{N_CHUNKS} чанков)",
|
||
"",
|
||
"Три версии перевода ОДНОГО фрагмента под нейтральными метками (V1/V2/V3, перемешаны; ключ отдельно).",
|
||
"Оцени: (а) художественность/связность и (б) ВЕРНОСТЬ — сверяя каждую версию с китайским ОРИГИНАЛОМ",
|
||
"ниже (ничего не потеряно; смысл/род/референт/порядок событий переданы). Планка: ≤2 претензии на главу.",
|
||
"Примечание: V1/V2/V3 переводились с разной нарезкой на чанки, поэтому у одной из версий хвост",
|
||
"фрагмента может слегка отличаться по границе — это часть эксперимента, не ошибка перевода.",
|
||
"", "---", "",
|
||
"## ОРИГИНАЛ — китайский исходник (эталон для сверки верности)",
|
||
"",
|
||
src_display,
|
||
"", "---", ""]
|
||
for lab in labels:
|
||
pkt += [f"## {lab}", "", arms[mapping[lab]], "", "---", ""]
|
||
(MON / "blind_read_packet.md").write_text("\n".join(pkt), encoding="utf-8")
|
||
(MON / "blind_read_KEY.json").write_text(json.dumps(
|
||
{"_warning": "KEY — не показывать читающему до вынесения вердикта",
|
||
"mapping_label_to_arm": mapping, "n_chunks": N_CHUNKS,
|
||
"source_span_runes": len(src_span)}, ensure_ascii=False, indent=2), encoding="utf-8")
|
||
print(f"blind packet -> {MON}/blind_read_packet.md (key -> blind_read_KEY.json)")
|
||
print(f" labels: {mapping}")
|
||
print(f" lengths: flat {len(flat_text)}c, oracle {len(oracle_text)}c, q3a-src {len(src_arm)}c")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|