"""Exhaustive assumed-input policy table; no real authentication or hardware."""
import csv,json,itertools
from pathlib import Path
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
import numpy as np
P=Path(__file__).resolve().parent
FIELDS=['known','authorized','fresh','interlock','confirmation_required','confirmed']
def decide(known,authorized,fresh,interlock,confirmation_required,confirmed):
 failed=[name for name,value in zip(['unknown_command','unauthorized','stale_request','interlock_failed'],[known,authorized,fresh,interlock]) if not value]
 if failed:return 'deny',failed[0],';'.join(failed)
 if confirmation_required and not confirmed:return 'await_confirmation','confirmation_missing',''
 return 'permit','all_required_conditions_met',''
rows=[]
for case,values in enumerate(itertools.product([False,True],repeat=6),1):
 out,reason,failures=decide(*values);rows.append(dict(case=case,**dict(zip(FIELDS,values)),outcome=out,priority_reason=reason,all_failed_prerequisites=failures))
with (P/'policy.csv').open('w',newline='') as f:w=csv.DictWriter(f,fieldnames=rows[0]);w.writeheader();w.writerows(rows)
counts={k:sum(r['outcome']==k for r in rows) for k in ['deny','await_confirmation','permit']};assert counts=={'deny':60,'await_confirmation':1,'permit':3}
for r in rows:
 prerequisites=all(r[k] for k in FIELDS[:4]);permit=prerequisites and(not r['confirmation_required'] or r['confirmed']);wait=prerequisites and r['confirmation_required'] and not r['confirmed']
 assert (r['outcome']=='permit')==permit and(r['outcome']=='await_confirmation')==wait
 assert (r['outcome']=='deny')==(not prerequisites)
assert len({tuple(r[k] for k in FIELDS) for r in rows})==64
# Matrix: 16 prerequisite combinations by four confirmation combinations.
m=np.array([{'deny':0,'await_confirmation':1,'permit':2}[r['outcome']] for r in rows]).reshape(16,4)
plt.rcParams.update({'font.family':'DejaVu Sans','font.size':10,'svg.fonttype':'none','pdf.fonttype':42})
fig,ax=plt.subplots(figsize=(9,8.5));ax.imshow(m,cmap=ListedColormap(['#e9d6dc','#f2e4b8','#b9ded9']),vmin=0,vmax=2,aspect='auto')
for i in range(16):
 for j in range(4):ax.text(j,i,['DENY','WAIT','PERMIT'][m[i,j]],ha='center',va='center',fontsize=9,color='#18202e')
ax.set_xticks(range(4),['No / No','No / Yes','Yes / No','Yes / Yes']);ax.xaxis.tick_top();ax.xaxis.set_label_position('top');ax.set_xlabel('Confirmation required / confirmation present',labelpad=12)
ax.set_yticks(range(16),[' / '.join('1' if x else '0' for x in v) for v in itertools.product([False,True],repeat=4)]);ax.set_ylabel('Known / authorized / fresh / interlock\n(1 = assumed true, 0 = assumed false)',labelpad=12)
ax.set_xticks(np.arange(-.5,4,1),minor=True);ax.set_yticks(np.arange(-.5,16,1),minor=True);ax.grid(which='minor',color='white',lw=2);ax.tick_params(which='minor',bottom=False,left=False)
fig.suptitle('An exact decision table: 64 assumed input combinations',fontsize=15,y=.985)
fig.text(.5,.05,'60 deny • 1 await confirmation • 3 permit. Counts describe this complete Boolean table, not event probabilities or safety rates.',ha='center',fontsize=8)
fig.text(.5,.023,'No recognition, authentication, freshness sensor or physical interlock is implemented. The table evaluates supplied flags only.',ha='center',fontsize=8)
fig.tight_layout(rect=[0,.08,1,.93])
for ext in ['png','svg','pdf']:fig.savefig(P/f'policy-truth-matrix.{ext}',dpi=190)
meta={'title':'Exact assumed-input command policy','status':'Exhaustive logical enumeration, not observed machine events or probabilities','rows':64,'fields':FIELDS,'ordering':'False then True lexicographic product; confirmed changes fastest','policy':'known AND authorized AND fresh AND interlock AND (NOT confirmation_required OR confirmed)','deny_reason_priority':['unknown_command','unauthorized','stale_request','interlock_failed'],'outcome_counts':counts,'checks':{'all_pass':True,'unique_combinations':64,'independent_boolean_expression_parity':True,'no_permit_on_failed_prerequisite':True,'expected_counts_60_1_3':True},'limitations':['All six Boolean inputs are supplied assumptions. Recognition, authentication, authority, freshness and physical state sensing are not implemented.','The displayed first failure follows an assigned priority; all failed prerequisites are also exported.','No time evolution, bound pending-request identity, cancellation, timeout or execution-time recheck is modeled by this static table.','Confirmation is ignored when explicitly not required, but never bypasses a failed prerequisite.','Counts over logical combinations are not calibrated occurrence probabilities, false-accept rates, accident rates or standards certification.','Permit is a policy output for a virtual action, not proof that any physical actuation is safe.']}
(P/'study.json').write_text(json.dumps(meta,indent=2)+'\n');(P/'validation.json').write_text(json.dumps(meta['checks'],indent=2)+'\n');print(counts)
