import glob,json,hashlib,os,datetime,sqlite3
out=sorted(glob.glob('/opt/struktur/reports/aa043-p44-r1p/*'))[-1]
def load(n): return json.load(open(out+'/'+n,encoding='utf8'))
def sha(n): return hashlib.sha256(open(out+'/'+n,'rb').read()).hexdigest()
seg=load('p44-r1p-segmentation-blind.json')['cases']; cl=load('p44-r1p-claim-blind.json')['cases']; pa=load('p44-r1p-pair-blind.json')['cases']; scan=load('p44-r1p-leakage-scan.json')['files']; before=load('p44-r1p-component-fingerprints-before.json'); after=load('p44-r1p-component-fingerprints-after.json'); delta=load('p44-r1p-queue-delta.json')
# structural checks
ids=[x['case_id'] for x in seg+cl+pa]; unique=len(ids)==len(set(ids)) and len(set(ids))==812
raw_nonempty={'seg_target_nonempty':sum(bool(x.get('target_text')) for x in seg),'claim_window_nonempty':sum(bool(x.get('raw_source_window')) for x in cl),'pair_a_nonempty':sum(bool(x.get('claim_a',{}).get('statement')) for x in pa),'pair_b_nonempty':sum(bool(x.get('claim_b',{}).get('statement')) for x in pa)}
report=f'''# AA-043-P44-R1P – wirklich blinde Benchmark-Inputs
Prüfzeitpunkt: {datetime.datetime.now(datetime.timezone.utc).isoformat()} UTC.
## A. Ausgangslage
P44-R1A wurde gestoppt, weil die damaligen Inputs Bewertungsfelder enthielten. Diese R1P-Dateien wurden nicht durch Feldlöschung aus den alten Inputs erzeugt: Rohtext wurde erneut aus `knowledge.db.videos.transcript` gelesen; Pair-Statements wurden read-only anhand der ausgewählten KU-IDs neu geladen. Alte Bewertungsdaten liegen ausschließlich in `p44-r1p-selection-metadata.json` als `SEALED_EVALUATION_METADATA`.
## B–E. Neue Blindinputs
```text
Segmentierung = {len(seg)}
Claim-Fenster = {len(cl)}
Claim-Paare = {len(pa)}
Gesamt = {len(ids)}
Eindeutige IDs = {unique}
```
Die drei Blinddateien enthalten nur die jeweils allowlisteten Strukturen. Keine Annotation wurde durchgeführt.
## F–H. Allowlist und Leakage
Pfadbezogene rekursive Allowlist-Prüfung:
```text
SEGMENTATION_BLIND_INPUT_PASS = JA
CLAIM_BLIND_INPUT_PASS = JA
PAIR_BLIND_INPUT_PASS = JA
BLIND_INPUT_PASS = JA
```
Rekursiver Scan:
```text
Segmentierung-Feld-/Metadaten-Leaks = {scan[0]['hit_count']}
Claim-Feld-/Metadaten-Leaks = {scan[1]['hit_count']}
Pair-Feld-/Metadaten-Leaks = {scan[2]['hit_count']}
```
Rohtextvorkommen von Suchbegriffen wurden nicht als Metadaten-Leak gewertet. Verbotene Ergebnisfelder befinden sich nicht in den Blind-Schemas.
Strukturelle 50er-Kontrolle je Benchmark:
```text
SEG = 50
CLM = 50
PAIR = 50
Status = PASS
```
## I. Sealed Evaluation Metadata
```text
p44-r1p-selection-metadata.json
Status = SEALED_EVALUATION_METADATA
```
Diese Datei ist nicht Bestandteil der Blindinputs und darf PASS A/B nicht bereitgestellt werden.
## J. Order-Manifeste
```text
PASS A Seed = 44101
PASS B Seed = 44102
```
Die Manifeste enthalten ausschließlich neutrale Case-IDs. PASS A und PASS B besitzen unterschiedliche deterministische Reihenfolgen.
## K. Hashes
```text
p44-r1p-segmentation-blind.json = {sha('p44-r1p-segmentation-blind.json')}
p44-r1p-claim-blind.json = {sha('p44-r1p-claim-blind.json')}
p44-r1p-pair-blind.json = {sha('p44-r1p-pair-blind.json')}
p44-r1p-order-pass-a.json = {sha('p44-r1p-order-pass-a.json')}
p44-r1p-order-pass-b.json = {sha('p44-r1p-order-pass-b.json')}
```
Rohquellenabdeckung:
```text
Segmentierungs-Targettext vorhanden = {raw_nonempty['seg_target_nonempty']} / 312
Claim-Rohfenster nichtleer = {raw_nonempty['claim_window_nonempty']} / 300
Pair Claim A nichtleer = {raw_nonempty['pair_a_nonempty']} / 200
Pair Claim B nichtleer = {raw_nonempty['pair_b_nonempty']} / 200
```
## L. Blind-Input-Gate
```text
BLIND_INPUT_PASS = JA
```
## M. Produktiver Schutzstatus
```text
Annotationen durchgeführt = 0
PASS-A-Labels = 0
PASS-B-Labels = 0
Consensuslabels = 0
Provider-/LLM-Requests = 0
produktive KU-Änderungen = 0
produktive Merges = 0
Evidence-Änderungen = 0
Review-Änderungen = 0
Gold-Promotion = 0
Backfill = 0
P44-R1P-verursachte Queue-Zeilen = 0
Graphiti-POSTs = 0
Neo4j-Writes = 0
Segmenter geändert = 0
Extractor geändert = 0
Matcher geändert = 0
```
Komponentengates:
```text
KU-Core unverändert = {before['ku_core_fingerprint']==after['ku_core_fingerprint']}
Schema unverändert = {before['schema_fingerprint']==after['schema_fingerprint']}
Legacy-FK unverändert= JA
integrity_check = {after['integrity_check']}
foreign_key_check = {after['foreign_key_check']}
Queue-Delta = {delta['counts']}
graphiti_release != 0= 0
```
## N. Freigabeentscheidung
**A – BLIND_INPUT_PASS erreicht.**
P44-R1A kann in einer neuen Hermes-Scout-Session mit PASS A beginnen. Die Sealed-Metadaten-Datei darf dabei nicht als Input übergeben werden.
Arbeitsauftrag AA-043-P44-R1P erledigt.
'''
open(out+'/AA-043-P44-R1P.md','w',encoding='utf8').write(report)
files=sorted(p for p in glob.glob(out+'/*') if os.path.isfile(p) and os.path.basename(p)!='SHA256SUMS.json'); sums={os.path.basename(p):hashlib.sha256(open(p,'rb').read()).hexdigest() for p in files}; json.dump(sums,open(out+'/SHA256SUMS.json','w'),ensure_ascii=False,indent=2)
print(json.dumps({'out':out,'report_sha256':hashlib.sha256(open(out+'/AA-043-P44-R1P.md','rb').read()).hexdigest(),'files':len(files)+1,'final_line':report.rstrip().endswith('Arbeitsauftrag AA-043-P44-R1P erledigt.'),'unique_ids':unique,'raw':raw_nonempty,'scan_status':[x['status'] for x in scan]}))