Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,49 @@ All notable changes to TransTrack are documented in this file.
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
This project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Fixed

- **Support bundle log tail no longer loses a race with log rotation.**
`readLogTail()` checked a path for existence and size and then opened it.
`logger.cjs` rotates those same files, so the log could be renamed in
between — costing a section of the diagnostics, or pairing one file's size
with another's bytes. It now opens once and measures the descriptor.
- **`supportBundle.test.cjs` no longer requires an installed Electron
binary.** It loaded `logger.cjs`, which destructures `app` at module scope,
so the suite passed locally and failed in CI, where the binary download is
skipped. It now stubs `electron` the way the neighbouring suites do.

### Changed — validation package

- **Chart filing requirements renumbered TT-R137–R142 → TT-R150–R155.** The
original numbering collided with the pre-existing cross-cutting
requirements TT-R140–R142. Corrected before any site executes an OQ against
these ids.
- **SDS extended** with §11 migration safety, §12 diagnostics and PHI
redaction, §13 the IOTA notification pipeline, §14 chart filing, §15
dependency vulnerability exceptions, and §16 renderer bridge integrity.
Sections are appended rather than interleaved so existing §-references stay
valid.
- **OQ protocol extended** with 32 executable test cases covering the IOTA
pipeline, chart filing, migration safety, and support bundles — including
the adversarial one that matters: plant a patient name in free text, export
a default bundle, and search the file for it.
- **Risk register extended** with R-020 to R-027 (missed notification
deadline, duplicate or misfiled chart document, bundle PHI leakage, notice
altered after filing, template missing a statutory element, stale
vulnerability exception, feature unwired in the packaged build). R-013's
mitigation was revised: transactional rollback does not cover a
multi-migration sequence that fails partway, which the pre-migration copy
now does.
- **`scripts/check-compliance-docs.mjs`** — the cross-references between
these documents are now machine-verified and run in the standard test
suite. The requirement-id collision above survived review of both documents
because neither is wrong when read alone; this is the check that catches
that class of defect. It also found four requirements with no matrix row,
now traced.

## [1.2.1] - 2026-08-01

Pilot-readiness release. Apart from the IOTA notification pipeline below,
Expand Down
9 changes: 9 additions & 0 deletions docs/compliance/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ requirements.
| [`SOFTWARE_DESIGN_SPECIFICATION.md`](SOFTWARE_DESIGN_SPECIFICATION.md) | High-level design and architecture mapped to requirements. |
| [`TRACEABILITY_MATRIX.md`](TRACEABILITY_MATRIX.md) | Requirement → design → test traceability. |
| [`RISK_REGISTER.md`](RISK_REGISTER.md) | ISO 14971-style risk register and mitigations. |
| `scripts/check-compliance-docs.mjs` | Automated consistency gate over the documents above: unique requirement ids, a matrix row per requirement, a verification artifact for every Mandatory requirement, and resolvable SDS, OQ and risk references. Runs in the standard test suite. |
| [`VALIDATION_SUMMARY_REPORT_TEMPLATE.md`](VALIDATION_SUMMARY_REPORT_TEMPLATE.md) | Template for the deploying organization to sign after IQ/OQ/PQ are executed. |

### Qualification protocols (templates to execute on the customer site)
Expand Down Expand Up @@ -72,3 +73,11 @@ The presence and quality of these artifacts is itself a buying signal. A reviewe
should expect to find: numbered requirements traced to tests, a risk register with
mitigations, executable IQ/OQ/PQ templates, and explicit policy documents that map
to HIPAA Administrative Safeguards. All of those exist here.

Two things are worth checking, because they are where validation packages usually
decay. First, the traceability is machine-verified rather than asserted:
`scripts/check-compliance-docs.mjs` runs in the standard test suite and fails the
build on a duplicate requirement id, an untraced requirement, or a dangling OQ or
risk reference. Second, requirements that are *not* implemented are listed in the
matrix with their status rather than omitted, so the gaps are visible on the page
instead of having to be inferred from an absence.
20 changes: 18 additions & 2 deletions docs/compliance/RISK_REGISTER.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,16 @@
| Document control | |
|---|---|
| Document ID | TT-RISK-001 |
| Version | 1.0 |
| Version | 1.1 |
| Status | Baseline — to be extended by deploying organization |
| Applies to software version | 1.2.1 |

## Revision history

| Ver | Change | Rationale |
|---|---|---|
| 1.0 | Baseline. | Initial issue. |
| 1.1 | Added R-020 to R-027. Revised the mitigation for R-013. | New hazards arising from the IOTA notification pipeline, chart filing, and diagnostics export added in software version 1.2.1. R-013 was revised because its original mitigation — transactional rollback — does not cover a multi-migration sequence that fails partway, which is now addressed by a verified pre-migration copy. |

## Severity scale

Expand Down Expand Up @@ -53,10 +61,18 @@ Mitigations move risk to **Acceptable** when residual risk is **Low** or
| R-010 | Vulnerable bundled component (Electron, SQLite, Node) | 2 | A | Quarterly dependency scan; security-advisory monitoring; release notes call out CVE remediations. | C | Med (Acceptable) | Engineering |
| R-011 | Insider exfiltration via export | 2 | B | Every export logs file path, user, request_id; admin can disable exports per role. | D | Low | Engineering + Customer |
| R-012 | Power loss during write corrupts database | 2 | C | SQLite WAL + synchronous=FULL; integrity check at startup; automatic backup. | D | Low | Engineering |
| R-013 | Migration fails mid-way leaving DB in inconsistent state | 2 | D | Migrations wrapped in transactions; failed migration rolled back atomically. | E | Low | Engineering |
| R-013 | Migration fails mid-way leaving DB in inconsistent state | 2 | D | Migrations wrapped in transactions; failed migration rolled back atomically. A verified pre-migration copy is taken before any pending migration runs, and migration is refused outright if that copy cannot be written, so a sequence that fails after an earlier migration has already committed is still recoverable. The failure reports the schema version reached and the copy's path. | E | Low | Engineering |
| R-014 | Cross-org data leak in multi-tenant deployment | 1 | D | All queries scoped by `org_id`; UNIQUE constraints include `org_id`. | E | Low | Engineering |
| R-015 | Brute-force online password attack | 2 | B | Account lockout after 5 failed attempts × 15 min; rate-limit middleware on auth IPC. | D | Low | Engineering |
| R-016 | Phishing of MFA TOTP code | 2 | B | TOTP step skew limited to ±1; backup codes single-use; admin notified on backup-code use. | D | Med (Acceptable) | Customer training |
| R-017 | OPTN-style export mistakenly submitted to UNet | 2 | C | Export filename and CSV header carry "DO_NOT_SUBMIT" watermark; in-app modal warns. | D | Low | Product |
| R-018 | Living donor follow-up windows missed (OPTN Policy 14) | 2 | B | Follow-up tasks auto-generated at 6 / 12 / 24 months; overdue tasks escalate. | D | Low | Engineering |
| R-019 | TransTrack mistakenly classified by FDA as a device | 2 | C | `FDA_DEVICE_RATIONALE.md` documents non-device positioning; UI labels and disclaimers reinforce. | D | Med (Acceptable) | Product + Legal |
| R-020 | Statutory IOTA notification deadline missed, leaving a patient unaware they cannot receive organ offers | 2 | B | The obligation is created in the same operation as the status transition, so it cannot be forgotten; the due date derives from the transition's effective timestamp rather than the generation time; overdue obligations are surfaced on the compliance summary. Where configuration is incomplete the transition is still recorded and reported as unmet. | D | Med (Acceptable) | Customer Admin + Engineering |
| R-021 | Duplicate copy of the same notice filed into the patient's chart, causing clinician confusion about which is current | 3 | C | Idempotency key identifies the obligation (transition + notice kind + revision), not the rendered content, so a retry cannot produce a second document; `UNIQUE(org_id, idempotency_key)` enforces it at the database. Superseding requires an explicit revision increment. A notice already filed is not filed again. | E | Low | Engineering |
| R-022 | Notice filed to the wrong patient's chart, disclosing PHI into another patient's record | 1 | D | The DocumentReference subject is derived from the notification's own patient reference rather than from UI selection state; filing re-verifies the notice body against its recorded content hash before transmission; dry-run mode allows the resource to be inspected before any live filing is enabled at a site. | E | Low | Engineering |
| R-023 | Support bundle carries PHI out of the safeguarded environment via a support ticket | 2 | B | Free-text values are withheld rather than filtered, because a name in prose cannot be reliably detected; structured PHI is redacted by key and by pattern; the no-PHI claim is tested adversarially against deliberately PHI-laden input. Including free text requires an explicit request, is recorded inside the bundle, and relabels it as requiring PHI handling. Export is admin-only and audit-logged. | D | Low | Engineering + Customer |
| R-024 | Notice content altered after filing, so the record no longer matches what the patient received | 2 | D | The rendered body and its content hash are frozen at generation by database trigger; reprint verifies body against hash and reports any mismatch. | E | Low | Engineering |
| R-025 | Hospital-authored notice template omits a content element required by § 512.442(d) | 2 | B | Templates are validated at configuration time against all five required elements and rejected if any is missing or an unrecognised placeholder is used. The organ-offer-eligibility statement is system-supplied and not editable through template configuration. | D | Low | Engineering |
| R-026 | A documented dependency-vulnerability exception becomes a permanent, unreviewed suppression | 2 | C | Exceptions carry a `reviewBy` date and the release gate fails once it passes; the gate also fails on an undocumented finding, on a severity increase beyond what the exception assessed, and on an exception that no longer matches any real finding. | D | Med (Acceptable) | Engineering |
| R-027 | A feature works in development but is unwired in the packaged build, failing first in front of a clinician | 3 | B | Every `api.<namespace>.<method>()` call in the renderer is checked against the real preload surface by automated test; the source entry point is guarded against being overwritten by a build artifact; the release gate verifies the installer version matches the source version. | D | Low | Engineering |
Loading
Loading