Read, measure, compare, sign — and trust what is on screen.
A reading workstation in the browser, on synthetic CT: an in-house WebGPU renderer for slices, MPR and slabs, priors and nodule tracking, AI findings a human has to settle, structured reports with pre-sign checks, and an audit trail nobody can rewrite.
Demo — not a medical device — synthetic data only. Work in progress.

Many studies, one reader, no room for doubt.
A radiologist reads study after study through a session, and signs each one. Three things decide whether what they sign is right: the patient, the image, the numbers.
The right patient
Name, ID, date of birth and sex on every viewport, and a prior compared only once its Patient ID and issuer match. Similar names and identical birth dates are a known wrong-patient pattern.
The whole image
A slice still on its way is drawn as hatched no-data, never as the previous image; a partial series says how many slices it holds, and is not used as evidence.
Numbers to trust, a human who signs
Measurements in millimetres only when the spacing says so; AI findings that wait for the reader; a report signed by a person, kept as signed, corrected by addendum.
What the workstation holds to.
A few rules every screen keeps, because a viewer that is wrong quietly is worse than one that says it cannot show.
Identity before pixels
A prior is matched on Patient ID and issuer before a single pixel of it is fetched. A mismatch blocks the comparison, with no override, and lands in the audit trail.
Nothing auto-accepted
Every AI finding stays pending until a human accepts, edits or rejects it. Signing is disabled while any is pending, and the AI has no signing identity at all.
Measurements that say what they are
In pixels, marked UNCALIBRATED, when pixel spacing is missing; disabled on slabs and on incomplete series, where a length would mean nothing.
A demo, and it says so
Not a medical device, no compliance claimed, synthetic data only: generated studies, invented demographics, zero external calls, and a banner on every screen.
Built and running.
Stills of the live workstation on its synthetic studies: the viewer, the worklist, a prior compared, a wrong patient refused, a report before signing, the audit trail.






Weighed, chosen, and why.
Each key decision, with the alternatives, the choice and its reason. Each one is written down as a decision record in the repository.
- 01
Drawing the volumes
- Weighed
- Cornerstone3D / OHIF · vtk.js · in-house WebGL2 · in-house WebGPU
- Chosen
- An in-house WebGPU renderer: one r16sint 3D texture per volume, one WGSL shader for slices, MPR and MIP / MinIP / average slabs.
- Because
- Compute shaders for histograms, ROI statistics and slabs, and the rendering is the part worth showing. The industry's viewers run on WebGL2 for conservative workstations: Tomos says so on an explicit unsupported screen, and the WebGL2 fallback is next.
- 02
Reading DICOM
- Weighed
- dicom-parser · dcmjs · an in-house reader
- Chosen
- An in-house Part 10 reader of about 250 lines in a worker pool: explicit and implicit VR little endian, uncompressed 16-bit greyscale.
- Because
- It refuses by name — no DICM magic, compressed, big-endian, truncated — and the viewer turns each refusal into a state on the viewport instead of a guess.
- 03
Keeping a signed report signed
- Weighed
- Checks in the API · constraints in the database
- Chosen
- PostgreSQL triggers: a signed report cannot be updated; a correction is a signed addendum.
- Because
- The rule holds whatever code reaches the table, not only the code that remembers it.
- 04
Recording who did what
- Weighed
- An ordinary log table · an append-only, hash-chained trail
- Chosen
- Each audit event stores the SHA-256 of the previous one; the API's database role can only INSERT and SELECT it.
- Because
- Any edit or deletion breaks the chain, and the workstation verifies it on screen.
- 05
Where the images come from
- Weighed
- Public patient datasets · a procedural generator
- Chosen
- A dependency-free CT generator: 17 studies, 3,048 DICOM files, realistic HU, noise per kernel, nodules planted with their ground truth.
- Because
- No patient data anywhere, a known truth to test against, and the edge cases on demand: partial, corrupted, uncalibrated, non-uniform spacing, a wrong-patient prior.
From the generated scanner to the signed report.
A generator that stands in for the scanner, an API that stands in for the PACS and the AI, and a viewer that draws on the GPU: the boundaries a real department would draw.
Generator
Node, no dependencies: anatomy with vascular and bronchial trees, lung ≈ −840 HU, fat ≈ −100, contrast aorta ≈ 205, written as DICOM Part 10 with its ground truth.
API
NestJS 12 on PostgreSQL: a simulated DICOMweb PACS, mock AI inference, measurements recomputed server-side, nodule tracking and Lung-RADS, reports, the audit chain.
Viewer
Next 16 and React 19: DICOM parsed in a worker pool, volumes on the GPU, frames drawn outside React from a zustand store; first image in 899 ms against a 1 s budget.
Server
PM2 and nginx on my own server, DICOM served from disk, Let's Encrypt; deploys gated by the full verify suite, registered in Zeus, watched by Iknos.
What is built, and what is next.
Live as a demo, built ticket by ticket, each decision written down as it is taken.
Built · reading
- ViewerSlices, axial / sagittal / coronal MPR and MIP / MinIP / average slabs on WebGPU, window/level presets, the HU probe, measurements.
- Worklist and priorsPriority and SLA ordering, study locks, prior comparison with linked scroll, the wrong-patient block.
- Nodule trackingVolume from three diameters, volume-doubling time, a Lung-RADS v2022 rule engine the reader confirms.
Built · signing
- AI reviewMock inference whose findings stay pending until a human accepts, edits or rejects them.
- ReportsA structured template, pre-sign checks, immutable signed reports and signed addenda.
- Audit and regulatoryThe hash-chained trail verified on screen, and a page on what a real device would have to satisfy.
Next
- WebGL2 fallbackFor workstations without WebGPU, behind the same renderer shape.
- Key imagesMarked in the viewer, cited as evidence in the report.
- More templates, volume renderingReport templates beyond the chest CT, and a 3D rendering of the volume.
Read a study,
on a synthetic chest CT.
Scroll the MPR, measure a nodule, compare it with last year's scan, then try to sign with an AI finding still pending. Then open the wrong patient's prior and watch it refuse.