0hmX/am3352

This code suite comprises TypeScript scripts that analyze, verify, and assemble complex DDR memory interface hardware, focusing on physical routing, via and pad placement, electrical clearance, and physical constraints, often involving precise geometric calculations and consistent provenance tracking.

Version
1.0.5
License
unset
Stars
0

scripts/audit-ddr-e3-cache-envelopes.ts

/** Read-only cache/contract audit; corrected copies are proposals, never accepted board metadata. */
import {readFileSync,writeFileSync,mkdirSync} from 'node:fs'
import {resolve} from 'node:path'
import {createHash} from 'node:crypto'
import {objectHash} from './improve-ddr-a9-power-launches'
import {verifyDdrCapture} from './ddr-capture-provenance'
const [capture,current,preE3,out]=process.argv.slice(2)
if(!out)throw Error('Usage: capture current-board pre-E3-board output')
const hashes:Record<string,string>={},read=(p:string)=>{p=resolve(p);const b=readFileSync(p);hashes[p]=createHash('sha256').update(b).digest('hex');return JSON.parse(b.toString())}
const {captureHash,snapshot}=verifyDdrCapture(capture),candidate=read(`${current}/candidate.circuit.json`),report=read(`${current}/report.json`)
if(report.captureHash!==captureHash||report.candidateCircuitSha256!==objectHash(candidate))throw Error('Candidate provenance differs')
const bounds=(paths:any[])=>{const q=paths.flatMap(p=>p.route);return {minX:Math.min(...q.map(p=>p.x)),maxX:Math.max(...q.map(p=>p.x)),minY:Math.min(...q.map(p=>p.y)),maxY:Math.max(...q.map(p=>p.y))}}
const copperBounds=(paths:any[])=>{const q=paths.flatMap(p=>p.route).map(p=>{const diameter=p.route_type==='via'?p.via_diameter:p.width;if(!Number.isFinite(diameter)||diameter<=0)throw Error('Missing actual copper width/diameter');return {...p,r:diameter/2}});return {minX:Math.min(...q.map(p=>p.x-p.r)),maxX:Math.max(...q.map(p=>p.x+p.r)),minY:Math.min(...q.map(p=>p.y-p.r)),maxY:Math.max(...q.map(p=>p.y+p.r))}}
mkdirSync(out,{recursive:true});const write=(f:string,v:any)=>writeFileSync(resolve(out,f),JSON.stringify(v,null,2)+'\n')
const bytes=[0,1].map(byte=>{
 const name=`ram-byte${byte}-facing-progress.trace-paths.json`,paths=read(`${current}/${name}`),before=read(`${preE3}/${name}`),frozen=snapshot.pathsByByte[byte]
 if(paths.length!==72||before.length!==72||frozen.length!==72||new Set(paths.map((p:any)=>p.connection)).size!==72)throw Error('Incomplete cache')
 const changed=(base:any[])=>paths.filter((p:any)=>objectHash(base.find(q=>q.connection===p.connection))!==objectHash(p)).map((p:any)=>p.connection.replace('U1.ball_','')).sort()
 const frozenBounds=bounds(frozen),beforeBounds=bounds(before),afterBounds=bounds(paths),padding={left:Math.max(0,frozenBounds.minX-afterBounds.minX),right:Math.max(0,afterBounds.maxX-frozenBounds.maxX),bottom:Math.max(0,frozenBounds.minY-afterBounds.minY),top:Math.max(0,afterBounds.maxY-frozenBounds.maxY)}
 const frozenCopperBounds=copperBounds(frozen),beforeE3CopperBounds=copperBounds(before),afterE3CopperBounds=copperBounds(paths),copperPaddingGrowthMm={left:Math.max(0,frozenCopperBounds.minX-afterE3CopperBounds.minX),right:Math.max(0,afterE3CopperBounds.maxX-frozenCopperBounds.maxX),bottom:Math.max(0,frozenCopperBounds.minY-afterE3CopperBounds.minY),top:Math.max(0,afterE3CopperBounds.maxY-frozenCopperBounds.maxY)}
 const contractName=byte===0?'exit-contract.json':'ram-byte1-exit-contract.json',contract=read(`${current}/${contractName}`),changedBalls=changed(frozen),e3Delta=changed(before)
 if(e3Delta.join(',')!=='E3')throw Error('Unexpected cache change beyond E3')
 const scope=`Nineteen connected signal nets; 31 remain unconnected and 56/60 RAM power launches pass the geometric launch audit. RAM${byte} has ${changedBalls.length} changed paths (${changedBalls.join(', ')}), ${72-changedBalls.length} unchanged, relative to the frozen capture. E3 adopts the current adapter launch. No envelope growth. Full DDR and fabrication qualification remain outstanding.`
 const corrected={...contract,changedBalls,unchangedPaths:72-changedBalls.length,pathCount:72,priorCenterlineBounds:frozenBounds,newCenterlineBounds:afterBounds,paddingChangeBySideMm:padding,paddingChangeMm:Math.max(...Object.values(padding)),scope,candidateCircuitSha256:objectHash(candidate),metadataCorrectionProposal:{authoritative:false,sourceContractObjectSha256:objectHash(contract),cacheObjectSha256:objectHash(paths),candidateCircuitSha256:objectHash(candidate)}}
 write(`${contractName}.proposal.json`,corrected)
 return {byte,frozenCopperBounds,beforeE3CopperBounds,afterE3CopperBounds,copperPaddingGrowthMm,copperEnvelopeScope:'All72 cached trace widths and circular via diameters; excludes unchanged component pads and support copper outside the cache.',pathCount:72,changedBalls,unchangedPaths:72-changedBalls.length,changedSincePreE3:e3Delta,frozenBounds,beforeE3Bounds:beforeBounds,afterE3Bounds:afterBounds,paddingGrowthMm:padding,zeroEnvelopeGrowth:Object.values(padding).every(v=>v<1e-9),cacheObjectSha256:objectHash(paths),sourceContractObjectSha256:objectHash(contract),staleScope:contract.scope,correctedScope:scope}
})
for(const[p,h]of Object.entries(hashes))if(createHash('sha256').update(readFileSync(p)).digest('hex')!==h)throw Error('Input changed')
write('report.json',{captureHash,candidateCircuitSha256:objectHash(candidate),currentReportObjectSha256:objectHash(report),scope:'Read-only metadata audit. Corrected contract copies are proposals until the exporting assembly binds them; no input modified.',bytes,inputFileHashes:hashes})
console.log(JSON.stringify(bytes,null,2))