# @extant2000/evidence-record A small vocabulary for checks that have to show their work: four-way determinations, cited evidence, and reports that derive their own verdict. Zero runtime dependencies. Pure functions. Ships ESM and CommonJS. ## Why it exists Automated checks tend to fail their readers in the same few ways. This package gives every check one shared way to avoid them. 1. **A boolean hides the case that matters most.** `passed: true` can mean "we looked and it held" or "there was nothing to look at". Those need to stay apart, so a determination has four values, and three of them are not a pass. 2. Findings that do not say where they came from ask the reader to take them on trust. Every finding here carries `Evidence`: a file and line, a database row, a command, a measurement, or a document. 3. A measurement without its sample count is not evidence. An availability of 100% over zero samples and one over 8,640 samples are different claims, so the sample count travels with the number. 4. A report with zero findings is not a pass unless something was examined. The verdict is computed from the report, and `examined === 0` always gives `not-assessed`. The unflattering outputs stay unflattering. A missing value is not a pass, and nothing in this package turns one into a pass. ## Determinations ```ts type Determination = 'pass' | 'fail' | 'not-applicable' | 'not-assessed' ``` `rollUp` combines several. Any fail wins. An empty list is `not-assessed`, because `[].every(...)` being true is the trap this type closes. One unassessed item keeps the roll-up at `not-assessed`, so healthy items cannot dilute it. ```ts rollUp([]) // 'not-assessed' rollUp(['pass', 'not-assessed']) // 'not-assessed' rollUp(['pass', 'pass', 'fail']) // 'fail' ``` `label(d)` gives a short badge (`MET`, `NOT MET`, `N/A`, `NOT ASSESSED`). `describe(d, subject)` gives a sentence that still makes sense when pasted into an email on its own. ## Evidence ```ts import { evidence, cite, describeMeasurement } from '@extant2000/evidence-record' evidence.file('docker-compose.yml', 42, 'ports: ["2222:22"]') evidence.record('requirements', 'a1b2c3', 'parent_id', 'null') evidence.command('docker compose config', 0) evidence.measurement('uptime', null, 0, { unit: '%', window: '2026-07' }) evidence.document('NIST SP 800-53 Rev 5', 'AC-2') ``` `cite()` renders each kind in the form people already read it in: `path:line` for source, `table#id (field)` for rows, `$ command → exit 0` for commands. `citeVerbose()` adds the excerpt and note. `describeMeasurement()` reads the null case out loud: "No samples for Availability in 2026-07; it cannot be computed." ## Reports ```ts import { evidence, overall, validateReport, formatReport } from '@extant2000/evidence-record' const report = { capability: 'PortCheck', scope: '12 compose services', examined: 12, findings: [ { id: 'f1', summary: 'SSH published on a host port', determination: 'fail', severity: 'critical', evidence: [evidence.file('docker-compose.yml', 42, 'ports: ["2222:22"]')] }, { id: 'f2', summary: 'Admin UI bound to loopback only', determination: 'pass', severity: 'info', evidence: [evidence.file('docker-compose.yml', 88)] }, ], } overall(report) // 'fail', computed from the findings validateReport(report) // [] when every conclusion carries a citation formatReport(report) // worst first, one citation per finding ``` Output of `formatReport(report)`: ``` PortCheck — 12 compose services NOT MET · 12 items examined · 2 findings ✗ CRITICAL SSH published on a host port [NOT MET] evidence: docker-compose.yml:42 ◦ info Admin UI bound to loopback only [MET] evidence: docker-compose.yml:88 ``` The same report with nothing examined: ``` PortCheck — no services found NOT ASSESSED · 0 items examined · 0 findings PortCheck's scope was not assessed. This is not a pass — an unassessed control is not an implemented control. ``` `validateReport` flags a finding that reaches `pass`, `fail` or `not-applicable` with no evidence, plus duplicate ids and empty summaries. A `not-assessed` finding may have no evidence, since having nothing to cite is what it reports. `formatReport` accepts `{ evidence: 'inline' | 'full' | 'none', minSeverity }`. `formatRollUp(reports)` gives one line per report and a combined verdict, where an unrun report pulls the total to `not-assessed`. ## Conformance A check built on this package conforms when its own tests assert that: - `validateReport(report)` is empty for every report it can produce; - an empty input produces `not-assessed`, and the rendered output contains neither `✓` nor the word "clean"; - every `fail` finding carries at least one `Evidence`; - the rendered output of a failure names a file, a row, or a command. ## Install ``` npm install @extant2000/evidence-record ``` ## License MIT. Copyright (c) 2026 Extant 2000 LLC.