"""Check T685's unchanged 100-digit values and its first-order relation to T283.

Run with SageMath and numberdb, beside the unchanged attached generate.py:
    sage -python repair-checks-20261109.py
Set NUMBERDB_API_KEY for private draft reads. For the campaign wrapper:
    cat "$NUMBERDB_KEY_FILE" | NUMBERDB_KEY_FROM_STDIN=1 agents/sage.sh repair-checks-20261109.py generate.py

No writes. Integral controls, exact stored-interval containment for all 24
entries, and independent Arb closed forms for both first-order values. This
repair check verifies the provenance correction; it is not a new independent
argument-selection critique. The archived instructions are recorded in
agents/runs/20261109T083553Z-repair-skills/manifest.json, both versions SHA-256
886390324dd1971e381a43cf3b46b822ab0bc67d62f31d8481e29ec79556746b.
"""
import os, sys, json, time, hashlib
from decimal import Decimal
from pathlib import Path
if os.environ.get('NUMBERDB_KEY_FROM_STDIN') == '1':
    key=sys.stdin.read().strip()
    if '=' in key and key.split('=',1)[0].strip().isidentifier():
        key=key.split('=',1)[1].strip().strip('\"\'')
    os.environ['NUMBERDB_API_KEY']=key
import numberdb.sage as numberdb
from sage.rings.rational_field import QQ
from sage.rings.real_mpfi import RealIntervalField
from sage.rings.real_arb import RealBallField
from sage.rings.complex_arb import ComplexBallField
from sage.env import SAGE_VERSION
from generate import MultipleMahler, moment

start=time.monotonic()
a=numberdb.table('T685'); b=numberdb.table('T283')
R=RealBallField(600); C=ComplexBallField(600)
control=C.integral(lambda t,analytic:t*t,0,1).real()
assert control.is_finite() and (QQ(1)/3 in control) and control.accuracy()>550
closed={3:(C(0,1)*C.pi()/3).exp().polylog(2).imag()/R.pi(),4:7*R(3).zeta()/(2*R.pi()**2)}

def decimal_interval(s):
    d=Decimal(s); n,den=d.as_integer_ratio(); center=QQ(n)/den
    ulp=QQ(10)**d.as_tuple().exponent
    return center,ulp

def check_containment(ball,s):
    assert ball.is_finite() and ball.accuracy()>=373
    c,u=decimal_interval(s)
    interval=RealIntervalField(650)(ball)
    lo,hi=interval.lower().exact_rational(),interval.upper().exact_rational()
    assert c-u<=lo<=hi<=c+u
    return {'accuracy_bits':int(ball.accuracy()),'enclosure':str(ball),'stored':s,'contained_in_stored_interval':True}

identities=[(str(n),str(k)) for n,group in a['Numbers'].items() for k in group]
assert [(p['n'],p['k']) for p in MultipleMahler().enumerate()]==identities
rows=[]
for n,k in identities:
    ball=moment(int(n),int(k),digits=100)
    item={'n':n,'k':k,**check_containment(ball,a['Numbers'][n][k]['number'])}
    digits=Decimal(a['Numbers'][n][k]['number']).as_tuple().digits
    assert len(digits)==100
    item['significant_digits']=len(digits)
    if k=='1':
        other=closed[int(n)]
        assert other.is_finite() and other.accuracy()>550 and ball.overlaps(other)
        item['independent_closed_form']=check_containment(other,a['Numbers'][n][k]['number'])
        item['T283_comparison']=check_containment(other,b['Numbers'][n]['number'])
        item['T283_significant_digits']=len(Decimal(b['Numbers'][n]['number']).as_tuple().digits)
        assert item['T283_significant_digits']==50
    rows.append(item)
result={'table':'T685','stage':'repair','skill_manifest':'agents/runs/20261109T083553Z-repair-skills/manifest.json','skill_local_sha256':'886390324dd1971e381a43cf3b46b822ab0bc67d62f31d8481e29ec79556746b','skill_live_sha256':'886390324dd1971e381a43cf3b46b822ab0bc67d62f31d8481e29ec79556746b','generator_sha256':hashlib.sha256(Path(__file__).with_name('generate.py').read_bytes()).hexdigest(),'sage_version':SAGE_VERSION,'python_version':sys.version,'control':{'integral':'integral_0^1 t^2 dt','expected':'1/3','enclosure':str(control),'passed':True},'enumeration_unchanged':True,'checked':len(rows),'all_passed':True,'rows':rows,'elapsed_seconds':time.monotonic()-start,'limitations':'All-entry checks rerun the existing generator. Independent closed forms check only k=1 for n=3,4. No claim of a new independent critique.'}
print(json.dumps(result,indent=2))
