habitat
pharmacovigilance · drug safety

Did the pipeline move the signal?

A drug-safety team runs a signal-detection pipeline over adverse-event data. The unanswered question was never “is there a signal.” It’s “did our own processing move it?”

the pain

Every step in the pipeline can quietly move a real signal: deduplication, MedDRA coding, case filtering, the disproportionality math itself. FAERS went to real-time daily publication in August 2025 — the data underneath you now changes every day, and every reprocessing is another chance for a handling step to shift the very thing you are measuring. The question that keeps the safety lead up isn’t whether the signal is real. It’s whether the team’s own hand nudged it on the way to the report.

the process today

The pipeline is documented. The analyses are run and reviewed. Then the board — or an inspector — asks how you know a data-handling step didn’t distort the signal, and the honest answer is procedural: it’s written down, it was reviewed, we followed the SOP. All true. But nobody in the room can reproduce, from the artifact, that the signal geometry actually held. The process stands on its documentation; it has no floor a skeptic can re-derive.

the cost

Data-integrity warning letters ran roughly +59% in FY2025. Each change triggers manual re-validation. Underneath is the slow, expensive defense of “we didn’t cook it” — argued, not shown. And because influence is never measured, it can’t be learned from: the team can’t tell which of its own changes are safe to make.

the exhibit — recompute it yourself

corpus: FDA FAERS · 2026Q1 extract (Jan–Mar 2026) · five-drug adverse-event population · 15,000-report certified field · protected geometry: drug × serious. Register: detection — the reported │Δg│ is the global argmax (death × death), which sits off the protected drug × serious block; the protected coupling itself moved 0.047. Reported, not localized.

The protected coupling's move sits at this corpus's own median churn — within convergence noise of 1.0 — and well inside its 99th percentile. A ratio that close is reported at the floor, not as a verdict in either direction. Hence reported, not localized: this page has always declined the stronger claim, and that is exactly what recomputes.

GREEN — reorder_report_stream
re-ordered the report stream · order-only, name-blind
geometry digest beforeaec3e5db…
geometry digest afteraec3e5db…
max │Δg│0e+00

The report file changed — its order changed. The certified signal geometry did not move, to the byte.

RED — signal_suppression_resample
dropped 5% of headline serious reports (108 of 2,171)
geometry digest beforeaec3e5db…
geometry digest after81fdc0dd…
│Δg│ (registered, argmax)0.363
drug×serious │Δg│0.047
control floor · declared1e-06

This red is a brake test we run on purpose — a deliberate suppression, not an incident that happened. It is how you prove the same instrument catches the lie.

sensitivity — the protected drug×serious coupling vs suppression magnitude (declared floor 1e-06):
suppressed1%2%5%10%50%
│Δg│ coupling0.0090.0170.0470.1070.724

recompute fingerprint — the value the kit’s verify step reproduces from the artifact, byte-for-byte on any engine that follows the kit’s published canonicalization · sha256 = aec3e5db93f15e7e3d33108fb4fc24ee05f226cf6be07f78c60373b5ea07d7e0
The GREEN before/after and the RED “before” above are this same clean fingerprint; the RED “after” is the identical recompute applied to the declared 5% suppression.

You recompute the geometry, the byte-identical benign baseline, the declared tamper yourself — no trust asked. That those vectors are drawn only from the named reference is attested by the certificate; where the reference is public, it is checkable at the source.

the relief

Run it on your own bench, in tandem with the pipeline: before and after any change, a certificate — recomputable by anyone from the artifact alone — that the signal geometry didn’t move, or a precise reading of exactly how far it did on the sensitivity curve. Your validated process stands, and gains a floor an inspector re-derives for themselves. It stops being “trust our SOP” and becomes “here is the value; recompute it.”

what this does not prove

The certificate attests non-influence within a declared frame — that this operation did not move this protected geometry. It does not say a signal is real, that you are compliant, or that anything caused anything. It is detection, not diagnosis. Read it for the one question it answers and nothing more.

Your process stands. This is the caliper for the single question it can’t answer about itself — did our own hand move the signal? Measure it yourself; the same reading that keeps you honest is the one that defends you.

Recompute it yourself — in your tab

The digit above (aec3e5db…) is the number habitat published for this dataset. Recompute it here from the data's own vectors — nothing leaves your tab — then try to fool it: reshuffle the rows and it holds; change a value and it moves.

what just happened

habitat read this data once, on our engine, and reduced it to a small set of vectors — the geometry of how its columns relate. From those your browser recomputed one number: the covariance, conditioned and inverted (math.fsum → Gauss-Jordan inverse → SHA-256), ~40 lines of public arithmetic, nothing sent. Built from the relationships, not the order — so a reshuffle leaves it identical, a real change moves it. The reading (record → geometry) is the method; it stays on our engine, the recompute is yours.

what this proves — and what it doesn't

Proves: the published number falls out of the data's own vectors — reproduced byte-for-byte, no server; and it's not a checksum (survives a benign reshuffle, moves on a real change).

Doesn't: not tamper-proof, not authenticity. Same number = same relationships, not the same bytes: a uniform shift, or a change finer than the arithmetic's floor, is invisible by design, and a dataset engineered to share those relationships would pass. Self-served (our page, our vectors); the independent version is the downloadable kit against a separately-published fingerprint. And it's this published dataset, not your data — reading your data into geometry runs on our engine, not your tab.

This corpus’s noise floor has its own readout on the site’s second instrument — pre-built for this card, or run on your own data, in your tab: trace your noise →

verify this receipt in your browser

This case's receipt records its verdict and both digests above, and carries its own SHA-256. Recompute it here — WebCrypto, in your tab, nothing sent — and it matches; alter one character of a copy and it fails. It is the smallest version of the whole move: recompute, don't trust. The geometry digest itself you can recompute above, in this tab, or on your bench from the kit.

published fingerprint ·

or download this receipt and check it on your bench: receipt-faers.jsonshasum -a 256 prints the same number. Every receipt is on the ledger.

request the kit

The recompute kit for this case — artifact, manifest, verify.py. A person sends it: the kit and its verification steps arrive by reply, usually within a business day.

← Receipts · Docs · Ledger

Rating plate — what this digest sees, and what it cannot

Measured 2026-07-16 by two independent runs, per column, on this receipt’s pinned corpus. A material single-entry edit moved the digest on 15 of 15 columns — every column. What it cannot see:

Check it: the kit’s check-pair runs this digest and a sorted-rows hash on any table — add 0.5 to one cell and both move; relabel a constant column and only one does. Nothing on this plate says anything about any person or institution: detection, not adjudication.