# CertPack Generates a NIST 800-53 control document (a System Security Plan section with a remediation plan) from automated verification checks, with the evidence for each check attached. It is used in Hitt Hosting products. ## What it does and why An accreditation package that lists results without the scan output behind them is a set of claims. **CertPack attaches the evidence to each check and labels any check without evidence as a claim.** It does not drop the check or leave the cell blank, because a blank cell reads as "nothing to report" and a missing check is worse than a weak one. You pass a control (document number, title, control family, the gap, the fix) and a list of checks, each with a status and optional evidence in the `@extant2000/evidence-record` format. `renderControlDoc()` returns HTML and markdown built from one list of seven sections, so the two never drift apart: 1. Document information 2. Purpose and scope, including the gap and the deployments in scope 3. Current implementation status: a table of checks with their evidence, a summary line, and a count of checks with no attached evidence 4. Remediation plan with a target completion time (30 days by default) 5. Evidence: the full citation for every check, or a statement that the result is a claim and not a verified finding 6. References (NIST SP 800-53 Rev. 5, SP 800-53A and the FedRAMP SSP template by default) 7. Approval and sign-off table The rules that keep the document from claiming more than it knows: - A status other than `pass`, `fail` or `warn` is counted as unrecognised and shown in the summary, never folded into another status or dropped. - A control with no checks says that an unassessed control is not an implemented control, instead of printing "0 failing". - Missing fields print "Not specified", never `undefined` or `null`. - The date is a parameter, not read from the clock, so the same input always produces byte-identical output. A document that changes when regenerated is not reproducible evidence. Every value interpolated into the HTML goes through `escapeHtml()`, including titles, table cells and evidence, with no "trusted field" exception. The markdown output decodes entities because markdown is not an HTML context; if you inject that markdown into a page as HTML, escape it there. `toReport()` and `formatControl()` give the same assessment as an evidence-record report, so a control's status can be rolled up without parsing HTML. `pass` passes, `fail` and `warn` fail, and an unrecognised status is not assessed. ## Usage ```ts import { renderControlDoc, formatControl, type ControlDocInput } from '@extant2000/cert-pack' import { evidence } from '@extant2000/evidence-record' const input: ControlDocInput = { docNumber: 'SSP-AC-01', title: 'Access Control', family: 'AC', familyName: 'Access Control', gap: 'Tenant isolation is not documented', fix: 'Document the row-level security policy', date: '2026-09-28', systemName: 'Example App', checks: [ { check: 'Row-level security on every tenant table', status: 'pass', evidence: [evidence.command('psql -c "select relname, relrowsecurity from pg_class ..."', 0, '42 of 42 tables')] }, { check: 'Least privilege enforced', status: 'pass' }, { check: 'MFA for admins', status: 'skipped' }, ], } const { html, markdown, sections } = renderControlDoc(input) console.log(formatControl(input)) ``` In the generated document, section 3 ends with "2 passing, 0 failing, 0 warnings, 1 unrecognised out of 3 checks" and "2 of 3 check(s) carry no attached evidence". The two checks without evidence show NOT ATTACHED. `formatControl()` prints: ``` ✗ HIGH MFA for admins [NOT ASSESSED] Status "skipped" is not recognised. An unrecognised status is not a passing one. ◦ info Row-level security on every tenant table [MET] ◦ info Least privilege enforced [MET] ``` `controlDocSections()`, `renderDocument()`, `table()`, `stripTags()`, `escapeHtml()` and `tally()` are exported for building other documents. ## Install ``` npm install @extant2000/cert-pack ``` ## License MIT. See [LICENSE](LICENSE).