AnasSarkiz/usb-c-pd-brushed-motor
USB-C PD-powered motor controller with protected input, selectable 5/9/12 V buck supply, MCU qualification, PWM H-bridge drive, overvoltage sensing, regenerative energy-dump resistors, and safety interlocks.
- Version
- 0.0.1-a48-cloud-pipeline9-unrouted-c41d79a-305b1e7a
- License
- unset
- Stars
- 0
scripts/audit-thermal-via-policy.ts
import { readFile, writeFile } from "node:fs/promises"
import { createHash } from "node:crypto"
import { any_circuit_element } from "circuit-json"
import { z } from "zod"
const previousAudit = z
.object({
parts: z.array(z.object({ code: z.string(), sourceSha256: z.string() })),
})
.parse(
JSON.parse(await readFile("evidence/active-import-audit-A7.json", "utf8")),
)
const manifest = z
.array(
z.object({
code: z.string(),
ref: z.string(),
import_path: z.string(),
}),
)
.parse(
JSON.parse(
await readFile(
"evidence/active-supplier-inspection-manifest-A7.json",
"utf8",
),
),
)
const issues: string[] = []
const reviewedVias = []
for (const code of ["C1849461", "C44377", "C1855818"]) {
const part = manifest.find((entry) => entry.code === code)
if (!part) throw new Error(`Supplier manifest missing ${code}`)
const importedSha256 = createHash("sha256")
.update(await readFile(part.import_path))
.digest("hex")
if (
importedSha256 !==
previousAudit.parts.find((entry) => entry.code === code)?.sourceSha256
)
issues.push(`${code}: supplier model changed`)
const elements = z
.array(any_circuit_element)
.parse(
JSON.parse(
await readFile(
`dist/tests/supplier-audit/${code}/circuit.json`,
"utf8",
),
),
)
const board = elements.find((entry) => entry.type === "pcb_board")
if (board?.type !== "pcb_board" || board.is_via_in_pad_allowed !== true)
issues.push(`${code}: checker permission not serialized`)
const ep = elements.find(
(entry) =>
entry.type === "source_port" &&
(entry.name === "EP" || entry.port_hints?.includes("EP")),
)
if (ep?.type !== "source_port") throw new Error(`${code}: EP absent`)
const vias = elements.filter((entry) => entry.type === "pcb_via")
if (vias.length !== 4)
issues.push(`${code}: expected four existing imported vias`)
for (const via of vias) {
const trace = elements.find(
(entry) =>
entry.type === "source_trace" &&
entry.source_trace_id === via.source_trace_id,
)
if (
trace?.type !== "source_trace" ||
!trace.connected_source_port_ids.includes(ep.source_port_id)
)
issues.push(`${code} ${via.pcb_via_id}: EP connectivity missing`)
}
reviewedVias.push({ code, ref: part.ref, importedSha256, vias })
const source = await readFile(
`tests/supplier-audit/${code}.circuit.tsx`,
"utf8",
)
if (
!source.includes("routingDisabled") ||
!source.includes("autorouter={{ allowViaInPad: false }}")
)
issues.push(`${code}: disabled routing / router prohibition missing`)
}
const mainSource = await readFile("index.circuit.tsx", "utf8")
if (
!mainSource.includes("routingDisabled") ||
!mainSource.includes("isViaInPadAllowed={true}") ||
!mainSource.includes("autorouter={{ allowViaInPad: false }}")
)
issues.push("Main board policy mismatch")
const report = {
revision: "A11",
issues,
reviewedVias,
limitation:
"Board-wide checker permission, not a per-via exception. No routing executed; assembler process and thermal copper still require review.",
}
await writeFile(
"evidence/thermal-via-policy-A11.json",
JSON.stringify(report, null, 2) + "\n",
)
console.log(
JSON.stringify(
{
issues,
reviewedImportedViaCount: reviewedVias.reduce(
(count, part) => count + part.vias.length,
0,
),
},
null,
2,
),
)
if (issues.length) process.exitCode = 1