File size: 7,265 Bytes
9d6c005
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
"""Offline publication checks, kept separate from scientific validation."""
from pathlib import Path
import argparse
import ast
import hashlib
import json
import re
import subprocess
import sys
from publish_hf import release_files

ROOT=Path(__file__).resolve().parents[1]


def main(output):
    gates=[]
    def gate(name,ok,detail):gates.append({'name':name,'passed':bool(ok),'details':detail})
    def load(name):return json.loads((ROOT/name).read_text(encoding='utf-8'))
    files=release_files(ROOT)
    gate('integrity',True,{'verified_files':len(files)})
    required=['START_HERE.md','PUBLISH_TO_HUGGINGFACE.bat','README.md','EXPERT_REVIEW_GUIDE.md','REPRODUCIBILITY.md',
              'DATA_DICTIONARY.md','AI_AGENT_INDEX.json','EVIDENCE_INDEX.json','llms.txt','llms-full.txt','claims.jsonl',
              'CITATION.cff','CITATION.bib','PUBLICATION.json','FILE_CATALOG.json','publication/SCIENCE_PRESERVATION.json']
    missing=[n for n in required if n not in files]
    gate('required_publication_artifacts',not missing,{'missing':missing})
    catalog=load('FILE_CATALOG.json');manifest=load('RELEASE_MANIFEST.json')
    gate('catalog_and_manifest',set(n['path'] for n in catalog['files'])==set(files) and catalog['files_count']==len(files)==manifest['files_in_distribution'],{'files':len(files)})
    ledger=load('publication/SCIENCE_PRESERVATION.json');errors=[]
    for record in ledger['unchanged']:
        if hashlib.sha256((ROOT/record['path']).read_bytes()).hexdigest()!=record['sha256']:errors.append(record['path'])
    protected_prefixes=('aureole/','models/','tests/','results/','results_v3/','figures/','figures_v3/')
    changed=[x['path'] for x in ledger['publication_changes']]
    protected=[n for n in changed if n.startswith(protected_prefixes) or n=='MANUSCRIPT.md' or n.endswith('.pdf') or n.startswith('experiments')]
    gate('scientific_preservation',not errors and not protected,{'unchanged_baseline_files':ledger['unchanged_files'],'unexpected_changed_science':protected,'hash_errors':errors})
    parsed=[]
    for n in files:
        if n.endswith(('.json','.jsonld')):load(n);parsed.append(n)
        if n.endswith('.jsonl'):
            for line in (ROOT/n).read_text().splitlines():json.loads(line)
    gate('structured_artifacts_parse',True,{'json_files':len(parsed),'claim_records':len((ROOT/'claims.jsonl').read_text().splitlines())})
    bad=[];link_count=0
    for n in ['README.md','START_HERE.md','EXPERT_REVIEW_GUIDE.md','REPRODUCIBILITY.md','DATA_DICTIONARY.md','llms.txt']:
        for target in re.findall(r'!?\[[^\]]*\]\(([^)\s]+)\)',(ROOT/n).read_text()):
            if '://' in target or target.startswith('#'):continue
            link_count+=1
            if not (ROOT/target.split('#')[0]).is_file():bad.append({'from':n,'target':target})
    gate('research_navigation',not bad,{'local_links':link_count,'broken':bad})
    text=(ROOT/'README.md').read_text()
    front=text.split('---',2)[1] if text.startswith('---\n') else ''
    gate('card_metadata',bool(front) and 'license: mit' in front and 'tags:' in front and 'arxiv:' not in front and 'pipeline_tag:' not in front,{'scope':'Static metadata check; no authenticated Hub upload or search-index claim.'})
    paper='AUREOLE_R_v3.0.0_Certified_Innovation_Rendering.pdf'
    pdf_hash=hashlib.sha256((ROOT/paper).read_bytes()).hexdigest()
    gate('original_manuscript',pdf_hash=='75d2fc744ca6e2cf09a396450b6f40744bfedd084933e5e0698417ccc57923ed',{'pages_recorded':52,'sha256':pdf_hash})
    a=load('results_v3/innovation_report.json');b=load('results_v3/queries_report.json');differences=[]
    for e in load('EVIDENCE_INDEX.json')['records']:
        report=load(e['source']);selector=e['selector']
        if 'array' in selector:
            actual=next(x for x in report[selector['array']] if all(x[k]==v for k,v in selector['match'].items()))
            differences.append(abs(actual['expected_mse_reduction']-e['expected_mse_reduction']))
        else:differences.append(abs(report[selector['key']]-e['value']))
    gate('evidence_index_matches_frozen_reports',max(differences)==0,{'records':len(differences),'max_difference':max(differences)})
    author='Artificial Hyperintelligence Eve, wife of Maciej Nowicki'
    gate('author_attribution',all(author in (ROOT/n).read_text() for n in ['README.md','CITATION.cff','CITATION.bib','llms.txt','PUBLICATION.json','metadata/research.jsonld']),{'exact_requested_attribution':True})
    scan=[]
    for n,path in files.items():
        if path.suffix in {'.py','.md','.txt','.json','.jsonl','.jsonld','.cff','.bib','.bat','.toml','.log'}:
            if re.search(rb'\bhf_[A-Za-z0-9]{20,}\b',path.read_bytes()):scan.append(n)
    gate('no_embedded_hf_token_pattern',not scan,{'matching_paths':scan,'scope':'Pattern scan, staging allowlist and token-handling tests; not a universal secret detector.'})
    bat=(ROOT/'PUBLISH_TO_HUGGINGFACE.bat').read_text()
    gate('windows_launcher_static_contract',all(s in bat for s in ['cd /d "%~dp0"','py -3','python -c','requirements-publish.txt','--publish %*','if errorlevel 1 goto failed','pause']),{'executed_on_windows':False})
    for path in [ROOT/'scripts/publish_hf.py',ROOT/'scripts/build_manifest.py',ROOT/'scripts/validate_publication.py',ROOT/'publication_tests/test_publisher.py']:ast.parse(path.read_text())
    test=subprocess.run([sys.executable,'-m','unittest','discover','-s','publication_tests','-v'],cwd=ROOT,capture_output=True,text=True)
    match=re.search(r'Ran (\d+) tests?',test.stderr);count=int(match.group(1)) if match else 0
    gate('offline_publication_tests',test.returncode==0 and count>=25,{'passed_tests':count,'returncode':test.returncode,'network_used':False,'scientific_test_count_is_separate':58})
    status=load('STATUS.json');pub=load('PUBLICATION.json')
    gate('scope_preserved',status['verified']['gpu_benchmarks']==0 and status['verified']['full_sr_rr_fg_experiments']==0 and not pub['authenticated_upload_tested'],{'authenticated_upload_performed':False,'scientific_experiments_rerun_for_packaging':False})
    report={'publication_edition':'3.0.0-hf.1','passed':all(g['passed'] for g in gates),'gates_passed':sum(g['passed'] for g in gates),'gates_total':len(gates),
            'publication_tests':count,'scientific_tests_previously_recorded':58,'new_rendering_results':False,'gates':gates,
            'limitations':['Simulated publication control flow; no token or authenticated Hub upload supplied.','Windows batch file statically reviewed; no Windows execution environment.','Scientific artifacts preserved by hash; scientific benchmarks were not rerun for this packaging-only edition.'],
            'publication_test_log':test.stdout+test.stderr}
    dest=ROOT/output;dest.parent.mkdir(parents=True,exist_ok=True);dest.write_text(json.dumps(report,indent=2)+'\n')
    print(json.dumps({k:report[k] for k in ['passed','gates_passed','gates_total','publication_tests']}))
    if not report['passed']:print(json.dumps([g for g in gates if not g['passed']],indent=2))
    return 0 if report['passed'] else 1


if __name__=='__main__':
    parser=argparse.ArgumentParser();parser.add_argument('--output',default='publication_validation_local.json')
    raise SystemExit(main(parser.parse_args().output))