DR Runbook
Disaster-recovery runbook executor — composes pre-recorded regulatory steps, operator confirmation gates, and the framework's audit chain into a posture-appropriate Markdown runbook a regulator can read alongside b.audit.
b.drRunbook.emit walks the operator's posture (one of hipaa, pci-dss, gdpr, soc2, dora), pulls breach-disclosure deadlines from the operator-supplied b.budr registry, summarizes b.backup configuration, captures b.cluster topology, and writes a single Markdown file under outDir. Each emit also records a dr.runbook.emitted audit event with the posture, the output path, and the section count — so the operator confirmation chain has an immutable record of which runbook version was last produced.
Posture-driven citations:
- hipaa — 45 CFR §164.308(a)(7) contingency plan + §164.310(a)(2)(i) facility-recovery checklist - pci-dss — PCI DSS v4.0.1 Req. 12.10 (containment / eradication / recovery) - gdpr — Regulation (EU) 2016/679 Art. 32, 33 (72h notification), 34 - soc2 — AICPA TSC CC7.4 / CC9.1 (recovery objectives + change control) - dora — Regulation (EU) 2022/2554 Art. 11, 12, 24
The runbook is plain Markdown — operators commit it under docs/dr/ and version it with their service. Re-emitting overwrites the file in place via atomicFile.writeSync, so an operator-supplied template change ships through git review before the runbook lands.
b.drRunbook.emit(opts) #
{
outDir: string, // directory to write into (required)
posture: "hipaa"|"pci-dss"|"gdpr"|"soc2"|"dora",
services: Array<{name, rtoMs, rpoMs}>,
rtoMs: number, // service-level RTO in ms
rpoMs: number, // service-level RPO in ms
contacts: object, // role -> contact string
budr: object, // b.budr-shaped registry
cluster: object, // b.cluster handle
backup: object, // b.backup handle
audit: boolean, // default: true
filename: string, // override `runbook-.md`
}
Render and write the posture-specific runbook. Returns { paths, posture, sectionCount } after the file lands at outDir/ (default filename: runbook-).
Service-level recovery objectives are emitted as a Markdown table keyed off services[].rtoMs and services[].rpoMs; values are formatted via b.constants.TIME granularity (hours / minutes / seconds). Optional bindings (budr, cluster, backup) populate matching sections when wired and surface a _No placeholder otherwise so the runbook never silently drops a required section.
Throws DrRunbookError("dr-runbook/unknown-posture") when posture is not in the supported list.
var report = await b.drRunbook.emit({
outDir: "/tmp/blamejs-runbook-demo",
posture: "hipaa",
services: [
{ name: "api-edge", rtoMs: b.constants.TIME.minutes(15), rpoMs: b.constants.TIME.minutes(5) },
],
rtoMs: b.constants.TIME.hours(4),
rpoMs: b.constants.TIME.minutes(15),
contacts: { incidentCommander: "alice@example.com" },
audit: false,
});
report.posture; // → "hipaa"
report.sectionCount; // → 9
report.paths.length; // → 1
Last updated 2026-08-08T16:39:49.652Z by seeder.