The tamper-evident sink: each line carries prev (the prior line's hash; the first carries
the all-zero genesis) and hash over everything before it, the same fixed-preimage
discipline the ledger's own chain uses. Editing, dropping, or reordering any line breaks the
chain at that line for verifyAuditChain. The digest is async while the sink is not,
so records queue on an internal chain that computes and writes strictly in order; flush
awaits it (call before process exit).
const lines: string[] = [];
const audit = hashChainedAuditSink((line) => lines.push(line), ports.digest);
const supervisor = createSupervisor({ ...supervisorPorts, audit });
await supervisor.tick();
await audit.flush();
const report = await verifyAuditChain(lines, ports.digest);
// report.intact === true; edit any line and firstBreak names it
The
./opsentry point: an in-process supervisor over the lab's meter/logger ports. The dependency runs one way — ops imports the core, the core never imports ops (eslint enforces it) — and leaving the supervisor out of the composition is the off switch.See
The supervisor for the tier model, the signal path, and the per-signature runbooks.