// Extract embedded core from shipped v2.6 HTML, verify the new defect fixes
// (F-10, F-42, F-12, PRNG, aliases) behave identically to standalone.
import fs from 'fs';
const html = fs.readFileSync('../blade-agent-hsm-sim.html','utf8');
const s = html.indexOf('<script>')+8, e = html.lastIndexOf('</script>');
let js = html.slice(s,e);
const coreEnd = js.indexOf('/* ═══════════════════════════════════════════════════════════════════════════\n   BUILD_INFO');
const core = js.slice(0, coreEnd);
const mod = core + `
export { hex, hexShort, sha256, concatBytes, AsyncMutex, SeededPRNG, HSM, HSMError, ABI, ABIv2, HostObjectStore, ABI_OPCODES, CAPACITOR_MODEL };
`;
fs.writeFileSync('/tmp/v26-core.mjs', mod);
const C = await import('/tmp/v26-core.mjs?v='+Date.now());
const { HSM, SeededPRNG, hex, sha256 } = C;

let PASS=0, FAIL=0; const fails=[];
function assert(c,n,d=''){ if(c){PASS++;console.log(`  ✓ ${n}${d?'  ['+d+']':''}`);}else{FAIL++;fails.push(n);console.log(`  ✗ ${n}${d?'  ['+d+']':''}`);} }
async function fresh(seed){ const h=new HSM(seed!==undefined?{seed}:{}); await h.provision(); return h; }

console.log('═══ EMBEDDED v2.6 DEFECT-FIX VERIFICATION ═══\n');

// F-12: tamper origin tier
{ const h=await fresh(); await h._transitionTier('T1',{reason:'pre'}); await h.tamper('cut');
  const tr=h.exportTrace().split('\n').map(l=>JSON.parse(l));
  const seal=tr.find(x=>x.type==='pcr_extend'&&x.pcrIndex===0&&x.cause&&x.cause.type==='tier_transition'&&Array.isArray(x.cause.data)&&x.cause.data[1]==='T0');
  assert(seal&&seal.cause.data[0]==='T1','F-12 (embedded): origin tier T1 preserved', seal?`from=${seal.cause.data[0]}`:'none'); }

// F-10: signature verification wired
{ const h=await fresh(); await h.audit_sign({e:'a'},null); await h.audit_sign({e:'b'},null);
  const trace=h.exportTrace();
  const clean=await h.verifyTrace(trace);
  assert(clean.verified===true&&clean.signaturesChecked.valid>=2,'F-10 (embedded): clean trace sigs valid',`${clean.signaturesChecked.valid}/${clean.signaturesChecked.total}`);
  const forged=trace.split('\n').map(l=>{const o=JSON.parse(l);if(o.type==='audit_sign_ok'&&o.sigHex)o.sigHex='ab'.repeat(o.sigHex.length/2);return JSON.stringify(o);}).join('\n');
  const t=await h.verifyTrace(forged);
  assert(t.verified===false&&t.signaturesChecked.invalid>0,'F-10 (embedded): forged sigHex DETECTED'); }

// F-42: anchor defeats truncation
{ const h=await fresh(); for(let i=0;i<4;i++) await h.audit_sign({e:i},null);
  const {traceJsonl,anchor}=await h.exportAnchoredTrace();
  const full=await h.verifyTrace(traceJsonl,anchor);
  assert(full.verified===true&&full.anchor.anchorSigOk===true,'F-42 (embedded): full trace + P-384 anchor verifies');
  const lines=traceJsonl.split('\n');
  const trunc=lines.slice(0,Math.floor(lines.length/2)).join('\n');
  const tr=await h.verifyTrace(trunc,anchor);
  assert(tr.verified===false,'F-42 (embedded): truncated trace FAILS'); }

// PRNG determinism
{ const a=new SeededPRNG(0xCAFEBABE), b=new SeededPRNG(0xCAFEBABE);
  const sa=Array.from({length:6},()=>a.next()), sb=Array.from({length:6},()=>b.next());
  assert(JSON.stringify(sa)===JSON.stringify(sb),'PRNG (embedded): same seed → same stream');
  const h=await fresh(0xBEEF); assert(h.prng.snapshot().initialSeed===0xBEEF,'PRNG (embedded): seed exportable'); }

// hardwareState alias + radiation no-crash
{ const h=await fresh(); h.hardwareState.radiationActive=true;
  assert(h.hardwareState===h.hazardState,'alias (embedded): hardwareState===hazardState');
  for(let i=0;i<10;i++){h.simClockMs+=100;await h.simulateHardwarePhysics();}
  h.hazardState.radiationActive=false;
  assert(Number.isFinite(h.hazardState.seuDetectedCount),'radiation (embedded): no crash, valid state'); }

// (final report consolidated below, after pinning check)

// ── Appended: pinning check from shipped HTML (T-016 equivalent) ──
{
  const C2 = await import('/tmp/v26-core.mjs?v='+Date.now()+'p');
  const { HSM: H2 } = C2;
  const dev = new H2({ seed: 0x1A1A }); await dev.provision();
  for (let i=0;i<3;i++) await dev.audit_sign({event:'op-'+i}, null);
  const { traceJsonl, anchor } = await dev.exportAnchoredTrace();
  const pinned = dev.identityCertHistory[0].attestationPubSpki;
  const genuine = await dev.verifyTrace(traceJsonl, anchor, { pinnedAttestationPubSpki: pinned });
  const att = new H2({ seed: 0x9F9F }); await att.provision();
  const forgedTrace = traceJsonl + '\n' + JSON.stringify({type:'note',injected:'x'});
  const forgedAnchor = await att._buildTraceAnchor(forgedTrace);
  const verifier = new H2();
  const checked = await verifier.verifyTrace(forgedTrace, forgedAnchor, { pinnedAttestationPubSpki: pinned });
  const ok = genuine.verified && genuine.trustModel==='adversarial-forgery-resistant'
    && checked.verified===false && checked.mismatches.some(m=>m.type==='ATTESTATION_IDENTITY_MISMATCH');
  if (ok) { PASS++; console.log('  ✓ pinning (embedded): adversarial re-key detected, genuine resistant'); }
  else { FAIL++; console.log('  ✗ pinning (embedded) FAILED'); fails.push('pinning-embedded'); }
}
console.log(`\n═══ EMBEDDED v2.6 (with pinning): ${PASS} PASS / ${FAIL} FAIL ═══`);
if(FAIL>0) process.exit(1);
