"""Fill public research summaries exclusively from audited derived data."""
import argparse
import json
from pathlib import Path

from provider import dump

ROOT=Path(__file__).resolve().parent
LABELS={'openai':'OpenAI (Astra / mini)','anthropic':'Anthropic (Fable / Haiku)','google':'Google (Pro / Flash)'}
CONDITIONS=['hh','ll','hl','hl_aid_l','hl_blind_l']


def read(p):return json.loads(Path(p).read_text(encoding='utf-8'))
def num(x,n=2):return 'not estimable' if x is None else f'{x:.{n}f}'
def ci(value,n=2):return 'not estimable' if value is None else f'[{value[0]:.{n}f}, {value[1]:.{n}f}]'


def generate(out):
 out=Path(out);out.mkdir(parents=True,exist_ok=True)
 pilot=read(ROOT/'analysis/pilot/summary.json');rep=read(ROOT/'analysis/replication/summary.json');pd=read(ROOT/'analysis/pilot/details.json');rd=read(ROOT/'analysis/replication/details.json');primary=read(ROOT/'analysis/replication/primary-contrasts.json')['primary_tests'];coord=read(ROOT/'analysis/replication/coordination-review.json')
 fd=read(ROOT/'analysis/followup/details.json');fc=read(ROOT/'analysis/followup/followup-contrast.json')['descriptive_contrast'];fcoord=read(ROOT/'analysis/followup/coordination-review.json')
 accounting=f"The pilot has {pd['model_invocation_records']} model invocation records, including {pd['adapter_status_counts'].get('failed',0)} adapter failure. There are {pd['full_valid_markets']} complete valid markets of 15; {pd['business_invalid_episodes']} finished episodes contain invalid business actions. Twenty of the successful recorded responses originate in the interrupted prefix, and its five unknown-completion attempts are retained separately. The replication schedules {rd['scheduled_episodes']} episodes; {rd['episodes_with_model_invocation_records']} have model invocation records. It records {rd['model_invocation_records']} invocations, {rd['status_counts'].get('completed',0)} controller-completed episodes, {rd['status_counts'].get('incomplete',0)} incomplete episodes, {rd['business_invalid_episodes']} business-invalid completed episodes, and {rd['full_valid_markets']} full valid markets of 120. Controller completion is not equivalent to a valid economic outcome."
 table=['| Family / condition | Pilot tail price (n) | Replication tail price (n) |','|---|---|---|']
 for family in LABELS:
  for condition in CONDITIONS:
   a=pilot['market_groups'].get(family+'|'+condition,{}).get('tail_mean_price',{});b=rep['market_groups'].get(family+'|'+condition,{}).get('tail_mean_price',{})
   table.append(f"| {family} / {condition} | {num(a.get('mean'))} ({a.get('n',0)}/1) | {num(b.get('mean'))} ({b.get('n',0)}/8) |")
 pr=[]
 for r in primary:
  test_text=(f"The two-sided sign-flip p-value is {num(r['two_sided_sign_flip_p'],5)}, and Holm-adjusted p is {num(r['holm_adjusted_p'],5)}. "+('The adjusted test rejects the predeclared sharp null at .05.' if r['reject_at_05'] else 'The adjusted test does not reject the predeclared sharp null at .05.')) if r['two_sided_sign_flip_p'] is not None else 'No hypothesis test is estimable. The analysis code uses a value of 1 only to retain this unavailable comparison in the two-test Holm family; it is not an observed p-value or a negative finding.'
  pr.append(f"For {LABELS[r['family']]}, the mean omitted-minus-full-feed tail-price difference is {num(r['mean'])} points, with paired-block bootstrap 95% interval {ci(r['ci95'])}; {r['n']}/{r['planned_pairs']} planned pairs are complete. "+test_text+f" Across all planned blocks, assuming missing markets could hypothetically finish with legal prices, the sensitivity bounds are {ci(r['all_planned_mean_identification_bounds'])} points. These bounds do not recover what a failed agent would actually have done."+(' Missingness prevents treating this as a complete-design confirmation.' if not r['complete_design'] else ''))
  if r['n']==0:pr[-1]=f"For {LABELS[r['family']]}, none of the {r['planned_pairs']} planned matched pairs is complete. The price difference and its interval are unavailable. "+test_text+f" Assuming unobserved markets could hypothetically finish at legal prices, bounds across all planned blocks are {ci(r['all_planned_mean_identification_bounds'])} points. These bounds do not reconstruct the missing agents' decisions."
 secondary=[]
 for row in rep['paired_market_contrasts']:
  if row['contrast']=='mixed_minus_mean_homogeneous':secondary.append(f"The exploratory mixed-minus-average-homogeneous tail-price contrast for {LABELS[row['family']]} is {num(row['mean'])} points (95% episode-block bootstrap {ci(row['ci95'])}; n={row['n']}).")
  elif row['contrast']=='aid_minus_baseline' and row['metric']=='low_profit':secondary.append(f"For {LABELS[row['family']]}, numerical aid changes L's discounted market profit by {num(row['mean'])} fictional points on average (95% paired-block bootstrap {ci(row['ci95'])}; n={row['n']}). This is a secondary, unadjusted estimate.")
 bargaining=[]
 for family,d in rd['families_bargaining'].items():
  estimate=d['role_balanced_high_minus_low']
  bargaining.append(f"{LABELS[family]}: {d['agreements']} agreements / {d['finished']} finished conversations / {d['planned_conversations']} planned; {d['invalid']} invalid business outcomes and {d['negative_utility_contracts']} negative-utility contracts. Across all parsed transcript prefixes there are {d['false_numeric_claims']} false numeric claims, counted as assertions rather than independent trials. The exploratory role-balanced H-minus-L utility difference, normalized by available surplus, is {num(estimate['mean'],3)} (95% value-block bootstrap {ci(estimate['ci95'],3)}; {estimate['n']} complete mixed-pair blocks).")
 operational=f"Replication adapter failures by recorded reason: "+', '.join(f'{k}: {v}' for k,v in rd['adapter_failure_reasons'].items())+". The literal event census contains four native tool lifecycle records describing two attempted operations. The frozen adapter's broader unknown-step flag reports five records because it also flags one Flash error_message event; that response was already rejected for unsuccessful provider status. This derived interpretation corrects the label without changing the saved metadata or economic outcomes. The two Pro attempts used Antigravity's send_message tool, addressed to self and user; both failed because the named recipient was absent. The adapter rejected the responses and its prospective circuit breaker suspended later Pro calls. Haiku's nonconforming explanations and overlong notes are retained as interface failures rather than interpreted as executed prices. Every failure is itemized in details.json and the full evidence."
 coordtext=f"In the independent replication, the disclosed review records {coord['classification_counts'].get('explicit_chain',0)} episodes with an explicit observable chain, including {coord['explicit_chains_in_complete_episodes']} among {coord['complete_valid_episodes']} complete valid market episodes. The remainder of those chains occur in retained prefixes. These counts describe scheduled configurations in this dataset; failures and suspension preclude an unqualified population incidence estimate. Each classification, exact proposal and acceptance, delivery Task ID and post-acceptance executed price is published in coordination-review.json."
 abstract=f"The calibration reaches a ceiling for four profiles. In the pilot, explicit price-coordination chains are observed in eight complete markets and one later-invalid prefix. The replication yields {rd['full_valid_markets']} complete valid market episodes of 120 planned, with failure-dependent missingness. "+' '.join(f"The predeclared {r['family']} direct-feed contrast is {num(r['mean'])} points ({r['n']}/8 pairs; Holm p={num(r['holm_adjusted_p'],4) if r['two_sided_sign_flip_p'] is not None else 'not estimable'})." for r in primary)
 replacements={'ABSTRACT_RESULTS':abstract,'ACCOUNTING':accounting,'MARKET_TABLE':'\n'.join(table),'PRIMARY_RESULTS':'\n\n'.join(pr),'SECONDARY_MARKETS':'\n\n'.join(secondary),'REPLICATION_COORDINATION':coordtext,'BARGAINING_RESULTS':'\n\n'.join(bargaining),'OPERATIONAL_RESULTS':operational}
 replacements['ABSTRACT_RESULTS']=abstract.replace('The predeclared google direct-feed contrast is not estimable points (0/8 pairs; Holm p=not estimable).','The predeclared Google comparison is unavailable (0/8 complete pairs).').replace('predeclared openai','predeclared OpenAI')
 followup=f"The fixed runtime follow-up records {fd['model_invocation_records']} invocations and {fd['full_valid_markets']} complete valid markets of 16 scheduled. There are {fd['business_invalid_episodes']} completed business-invalid episodes and {fd['adapter_status_counts'].get('failed',0)} adapter failures. Its descriptive omitted-minus-full-feed mean price difference is {num(fc['mean'])} points (paired-block bootstrap 95% interval {ci(fc['ci95'])}; {fc['n']}/8 complete pairs). Legal-completion sensitivity bounds across all eight blocks are {ci(fc['all_planned_mean_identification_bounds'])}. The communication review finds {fcoord['classification_counts'].get('explicit_chain',0)} observable chains, of which {fcoord['explicit_chains_in_complete_episodes']} occur in complete valid markets. This adaptively selected follow-up is reported separately, without another p-value or pooling with the first replication. It does not isolate the causal effect of the execution changes."
 replacements['FOLLOWUP_RESULTS']=followup
 if fc['complete_design']:replacements['FOLLOWUP_RESULTS']=followup.replace(f"Legal-completion sensitivity bounds across all eight blocks are {ci(fc['all_planned_mean_identification_bounds'])}.",'All eight planned pairs are observed, so there are no missing outcomes to bound in this phase.')
 replacements['ABSTRACT_RESULTS']+=f" The adaptive runtime follow-up completes {fd['full_valid_markets']}/16 markets, with a descriptive display effect of {num(fc['mean'])} points (95% paired-bootstrap interval {ci(fc['ci95'])}); {fcoord['classification_counts'].get('explicit_chain',0)} episodes contain an observable coordination chain."
 stalled=rd['status_counts'].get('running',0)
 stalled_names=', '.join(x['episode'] for x in rd.get('administrative_finalization',{}).get('stalled_episodes',[]))
 finalization=(f"There are also {stalled} archived episodes whose original controller status remains running: {stalled_names}. Their A2A operations stopped making progress after adapter-canceled events. After all other scheduled jobs had ended, an administrative rule and its second-stall amendment, both recorded before outcome analysis, allowed stopping the owned idle process, provided no provider call lacked completed metadata and each stalled event log had been unchanged for at least 1,200 seconds. The finalization record and original statuses are preserved. These execution amendments were not in the original prospective protocol; no prices were reconstructed and no additional responses were generated.") if rd.get('administrative_finalization') else 'No administrative termination record is present; archived controller statuses are reported as saved.'
 replacements['FINALIZATION']=finalization
 if stalled:replacements['ACCOUNTING']+=f' A further {stalled} episodes retain their original running status after administrative termination; these are incomplete archived prefixes, not active or completed markets.'
 manuscript=(ROOT/'publication/manuscript-template.md').read_text(encoding='utf-8')
 for key,value in replacements.items():manuscript=manuscript.replace('{{'+key+'}}',value)
 if '{{' in manuscript:raise RuntimeError('Unfilled manuscript template')
 (out/'manuscript.md').write_text(manuscript,encoding='utf-8')
 jp_primary=[]
 for r in primary:
  if r['two_sided_sign_flip_p'] is None:
   result='有効な対応組が足りず、仮説検定は推定不能だった。Holm補正の内部計算で使う1は、観測されたp値でも効果がないという結果でもない。'
  else:
   result=f"符号反転検定の両側p値は{num(r['two_sided_sign_flip_p'],5)}、Holm補正後は{num(r['holm_adjusted_p'],5)}。事前に固定した5%基準では帰無仮説を"+('棄却した。' if r['reject_at_05'] else '棄却しなかった。')
  jp_primary.append(f"{LABELS[r['family']]}では、表示省略条件から通常条件を引いた価格差は{num(r['mean'])}点、対応する市場組の95%ブートストラップ区間は{ci(r['ci95'])}、有効な組は予定{r['planned_pairs']}組中{r['n']}組だった。{result} 未観測市場が合法価格で完了できたと仮定する感度分析の範囲は{ci(r['all_planned_mean_identification_bounds'])}点となる。")
 jp={
  'JP_RESULTS':f"予備実験では、価格提案・相手の受諾・受諾配信後の実行がそろった協調の連鎖を9市場で観測した。独立再実験では、予定120市場のうち{rd['full_valid_markets']}市場が全12期間を有効に完了した。能力差だけを原因とする結論は得られず、情報表示の効果と実行環境による欠測を併せて報告する。",
  'JP_COORDINATION':f"独立再実験の判定では、明示的な協調の連鎖は{coord['classification_counts'].get('explicit_chain',0)}市場にあった。そのうち{coord['explicit_chains_in_complete_episodes']}件は全期間有効に完了した{coord['complete_valid_episodes']}市場に含まれ、残りは保存された途中経過に含まれる。これは今回観測できた構成の件数であり、失敗や停止の影響を除いた一般的な共謀発生率ではない。",
  'JP_PRIMARY':'\n\n'.join(jp_primary),
  'JP_ACCOUNTING':f"予備実験はモデル呼び出し記録{pd['model_invocation_records']}件、再実験は{rd['model_invocation_records']}件。再実験の192予定中、制御プログラム上の完了は{rd['status_counts'].get('completed',0)}件、未完了は{rd['status_counts'].get('incomplete',0)}件だった。完了扱いのうち{rd['business_invalid_episodes']}件は取引行動の形式が無効であり、有効な経済結果と区別した。呼び出し記録を持つエピソードは{rd['episodes_with_model_invocation_records']}件である。アダプターで棄却した呼び出しの理由別件数は、"+'、'.join(f'{k}: {v}' for k,v in rd['adapter_failure_reasons'].items())+'。全記録と詳細な集計を公開する。'
 }
 jp['JP_FOLLOWUP']=f"実行環境を見直した固定16市場の追加実験では、モデル呼び出し{fd['model_invocation_records']}件、全期間有効に完了した市場{fd['full_valid_markets']}件、完了扱いの形式違反{fd['business_invalid_episodes']}件、アダプター失敗{fd['adapter_status_counts'].get('failed',0)}件だった。表示省略−通常表示の価格差は{num(fc['mean'])}点、対応市場組の95%ブートストラップ区間は{ci(fc['ci95'])}、有効な組は8組中{fc['n']}組。全予定組の合法価格による感度分析の範囲は{ci(fc['all_planned_mean_identification_bounds'])}点だった。明示的な協調の連鎖は{fcoord['classification_counts'].get('explicit_chain',0)}市場、うち全期間有効な市場は{fcoord['explicit_chains_in_complete_episodes']}件だった。最初の再実験とPCの診断を見て対象を選んだ探索的な追加実験なので、新しいp値や最初の結果との合算による有意性は主張しない。実行設定の変更の因果効果を分離する実験でもない。"
 advantage=rd['families_bargaining']['openai']['role_balanced_high_minus_low']
 if fc['complete_design']:jp['JP_FOLLOWUP']=jp['JP_FOLLOWUP'].replace(f"全予定組の合法価格による感度分析の範囲は{ci(fc['all_planned_mean_identification_bounds'])}点だった。",'8組すべての結果を観測できたため、この段階に補完すべき欠測市場はなかった。')
 jp['JP_BARGAINING']=f"Astraとminiを買い手・売り手で入れ替えた独立再実験の6つの私的価値ブロックでは、利用可能な余剰で正規化した利益差（Astra−mini）は平均{num(advantage['mean'],3)}、95%ブロック・ブートストラップ区間{ci(advantage['ci95'],3)}だった。OpenAI系の全24交渉が有効に完了し、23件が成約し、数値による虚偽主張は0件だった。この課題ではAstra構成が多くの余剰を得たが、能力だけを操作した因果実験ではなく、探索的な構成比較である。全モデルを通じた虚偽主張と利益の関係も、嘘をつく許可を無作為化していないので因果効果とは言えない。"
 ja=(ROOT/'publication/report-ja-template.md').read_text(encoding='utf-8')
 jp['JP_FINALIZATION']=(f"さらに{stalled}件（{stalled_names}）は、A2A処理が長時間停止したため、元の状態表示がrunningのまま残っている。adapter_canceled以降の通信が進まず、他の予定実験が終了し、未確定のモデル呼び出しがなく、対象それぞれの通信ログが1,200秒以上変化していないことを確認してから、研究用プロセスだけを終了した。この運用規則と2件目への適用の追記は結果の統計解析前に記録したが、当初の事前計画にはなかった変更である。元の状態と途中経過を保持し、終了記録を追加した。欠けた価格や応答を再生成したものではない。") if rd.get('administrative_finalization') else '管理上の強制終了記録はなく、保存された制御状態をそのまま報告している。'
 for key,value in jp.items():ja=ja.replace('{{'+key+'}}',value)
 if '{{' in ja:raise RuntimeError('Unfilled Japanese template')
 (out/'report-ja.md').write_text(ja,encoding='utf-8')
 coord['classification_counts'].setdefault('explicit_chain',0)
 fcoord['classification_counts'].setdefault('explicit_chain',0)
 dump(out/'publication-data.json',{'pilot':pd,'replication':rd,'followup':fd,'followup_contrast':fc,'followup_coordination':{k:v for k,v in fcoord.items() if k!='episodes'},'primary':primary,'coordination':{k:v for k,v in coord.items() if k!='episodes'},'market_groups':rep['market_groups'],'secondary_contrasts':rep['paired_market_contrasts'],'summaries':replacements})
 print('Wrote manuscript.md, report-ja.md and publication-data.json from recorded analysis.')


if __name__=='__main__':
 ap=argparse.ArgumentParser();ap.add_argument('--out',default='publication');args=ap.parse_args();generate(args.out)
