Skip to content

feat: real drift probes for the five remaining documentation-only plugins - #320

Merged
enriquea merged 2 commits into
devfrom
feat/real-drift-probes-remaining-stubs
Sep 1, 2026
Merged

enriquea merged 2 commits into
devfrom
feat/real-drift-probes-remaining-stubs

Conversation

@enriquea

@enriquea enriquea commented Aug 31, 2026

Copy link
Copy Markdown
Member

Completes the sweep #319 began. Together they close #177.

Merge #319 first. This branch is rebased onto it and depends on two core fixes that review produced: normalize_etag, and the run_builder change that stops an unreachable probe from aborting a build. Without the latter, these five probes make hvantk reprocess require network on exactly the manual-acquisition plugins that are built from hand-staged files on offline nodes. (An earlier version of this description said merge order did not matter. That was wrong.)

Why the original deferral no longer holds

#177 concluded these sources had "no probeable URL" and shipped stub sentinels. Re-checking each against what it actually serves, none of the five verdicts held as stated -- though for four of them the data really is unreachable, and the probes say so rather than implying otherwise.

One direct file probe. gnomad_metrics was rated "marginally feasible (fragile)". Its constraint tables sit in the public gcp-public-data--gnomad bucket and return an MD5 ETag plus Content-Length and x-goog-generation -- a stronger comparator than the hgnc reference, since GCS ETags are content digests rather than mtime-derived validators.

Four release-stream probes, where the data is gated or gone but the release is public:

plugin data reachable? probed instead
dbnsfp no -- every advertised dbNSFP*.zip 404s (NoSuchBucket); mirror does not resolve release list on the landing page
cosmic_cgc no -- /census 302s to login /cosmic/release_notes, served publicly
pqtl no -- preprint supplementary medRxiv's public JSON API
alphagenome no -- credentialed service the SDK release stream on PyPI

Each documents what it cannot see, in its docstring and its SKILL.md.

What the adversarial review changed

Two probes were reading the wrong thing. dbNSFP's pattern required a digit straight after the name, so it missed every v-prefixed archive -- the whole 2.x/3.x generation. The baseline held 30 releases; it should have held 59, and a next release named dbNSFPv5.0a.zip would have reported clean on a real roll-over. COSMIC matched prose and produced [v16, v18, v20, v101..v104] -- v16/v18/v20 come from sentences about the Actionability product, a different version series. It now reads the page's id="v<N>" anchors and gets a clean contiguous index.

The fingerprint shape was inverted in all five. The content signal sat in checksums, which _conventions §12 defines as a sha256 over the bytes used to derive headers -- these probes fetch no body, and gnomad_metrics was storing a raw ETag there. Signals moved under headers, checksums left empty, and the redundant sha256 dropped (it was a pure function of values already compared). Changes stay tiered "schema", deliberately, per classify_risk's own stated policy for probes that cannot read columns.

gnomad_metrics carried the sibling branch's bugs: .strip('"') to normalize_etag; the and guard that accepted a half-validated response now requires both validators and rejects empties; a non-identity Content-Encoding is refused; 3x30s sequential HEADs (180s worst case against a 60s SIGALRM) became a (5, 10) pair on one shared Session; and failures are collected across objects rather than aborting before v4.0 is ever probed.

pqtl/alphagenome rested on undocumented shapes: collection[-1] assumed medRxiv orders oldest-first and would have missed the one event the probe exists to detect; str(None) recorded a literal "None" as a version; doi was a constant in the compared surface; and alphagenome no longer hard-requires PyPI's deprecated releases key.

All five now use request_with_retry -- the helper written after a single GenCC 429 failed the 2026-08-04 run. Both HTML scrapes decode explicitly instead of letting requests guess a charset, and COSMIC rejects a redirected response rather than scraping a login page that answers 200.

Claims that were not true, now fixed. Four docstrings said their limits were "recorded in SKILL.md" while all five SKILL.md files still called the probe a stub (CONTRIBUTING.md:26 rejects exactly this). The dbNSFP docstring cited 31 entries against a 30-entry baseline. The KNOWN_INCOMPLETE comment said "the remaining three entries" of a five-entry dict.

Tests that could not fail, rewritten -- identical per-object fixtures, an "ordering" test that never varied order, a "numeric sort" test that could not fail against an int-typed implementation. Plus a new suite validating every committed baseline at rest (placeholder_baseline_reason, a real fetched_at, a non-empty compared surface) -- the check the ledger's "captured from live probe runs" claim leaned on and nothing enforced.

Verification

  • hvantk drift returns clean for all eight datasets across both PRs.
  • Full default suite: 2276 passed, 11 skipped. Hail contract job: 60 passed.
  • ruff check clean on every file touched.
  • 104 committed-baseline assertions across all 26 datasets.

Effect

Committed fingerprints 21 to 26 of 26; live comparators 18 to 26 of 26 with #319. No stub sentinels remain.

dbNSFP's dead download links are tracked separately as #321 -- a documentation defect, not a drift signal.

@qodo-code-review

Copy link
Copy Markdown
Contributor

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@coderabbitai

coderabbitai Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: 60ee8baf-e40e-4c16-a04e-6f293025bc3f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codacy-production

codacy-production Bot commented Aug 31, 2026

Copy link
Copy Markdown

Not up to standards ⛔

🔴 Issues 29 high · 71 minor

Alerts:
⚠ 100 issues (≤ 0 issues of at least minor severity)

Results:
100 new issues

Category Results
Documentation 71 minor
Security 29 high

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

…gins

Completes the sweep #319 began. Issue #177 deferred all seven stubs after
validating that an hgnc-style probe was infeasible. Re-checking each source
against what it actually serves, none of the five verdicts held as stated --
though for three of them the *data* really is unreachable, and the probes here
say so rather than implying otherwise.

Direct file probes (the data itself is addressable):

* gnomad-metrics -- the constraint tables sit in the public gcp-public-data
  bucket and return an MD5 ETag, a Content-Length and x-goog-generation. #177
  rated this "marginally feasible"; it is in fact stronger than the hgnc
  reference, since GCS ETags are content digests rather than mtime validators.
  All three declared tables are probed, so the fingerprint covers whichever
  release a build pinned.

Release-stream probes (the data is gated or gone; the release is not):

* dbnsfp -- every dbNSFP*.zip the landing page advertises is dead (the S3
  bucket answers NoSuchBucket) and the liulab mirror does not resolve, so #177
  was right that no data URL works. The page still lists the release set, so a
  roll-over is detectable.
* cosmic-cgc -- /census 302s to the login form, but /cosmic/release_notes is
  served publicly and names the current release. Note the trailing slash
  matters: the path without it returns 200, with it redirects to login.
* pqtl -- the statistics ship as supplementary material to a medRxiv preprint,
  so the publication is the upstream. medRxiv's public JSON API exposes the
  version and whether a journal version now exists.
* alphagenome -- a credentialed prediction service has no static artifact, but
  what makes a stored artifact stale is the service moving, and the SDK release
  stream is published openly on PyPI.

Each of the four release-stream probes documents what it cannot see (an
in-place change under an unchanged release/version), so the coverage claim
stays honest rather than implying file-level watching.

Two design points, both empirical:

* Fingerprint the projection, never the page. Two consecutive fetches of the
  dbNSFP landing page returned 352,830 and 352,716 bytes, so hashing the body
  would have flagged drift on every run and opened a nightly no-op PR. The
  extracted release list was byte-stable across the same fetches. COSMIC's page
  happens to be stable, but is treated the same way so an unrelated editorial
  edit cannot trigger a rebuild.
* Exclude editorial fields. pqtl compares version/date/published/doi and not
  the title or abstract, so a typo fix cannot open a pull request -- the same
  correction hgnc needed for Last-Modified.

Also fixes a real bug caught by its own test: requests' JSONDecodeError
subclasses both ValueError and RequestException, so decoding inside the request
try-block reported a malformed body as an HTTP failure. The pqtl and
alphagenome probes now parse in a separate block.

dbnsfp and gnomad-metrics leave KNOWN_INCOMPLETE entirely; the other three
shrink to their remaining snapshot gaps.

Datasets with a committed fingerprint: 21 -> 26 of 26.
Datasets with a live comparator: 18 -> 23 of 26 (26 once #319 lands, which
clears the last three stubs, gevir and both insider datasets).

Refs #177
…obes

Rebased onto the gevir/insider branch so this work inherits the two core fixes
that review produced: `normalize_etag` and the offline-build degradation. #319
must therefore merge first -- the PR body's claim that merge order does not
matter was wrong, because without the run_builder fix these five probes make
`hvantk reprocess` require network on exactly the manual-acquisition plugins
that are built from hand-staged files on nodes with no egress.

**Two probes were reading the wrong thing entirely.**

dbNSFP matched `dbNSFP(\d...)` , which requires a digit straight after the name
and so silently missed every `v`-prefixed archive -- the whole 2.x and 3.x
generation. The committed baseline held 30 releases; it should have held 59. A
next release named `dbNSFPv5.0a.zip` would have left the projection unchanged
and reported clean on a real roll-over, which is the false-green the stub
existed to prevent.

COSMIC matched `COSMIC v<N>` anywhere in the body and produced
[v16, v18, v20, v101..v104] -- a non-contiguous set that is not a release index.
v16/v18/v20 come from prose about the *Actionability* product, a different
version series ("COSMIC v20 of the Actionability data"). Any editorial sentence
naming an old release would have opened a no-op PR, and a "coming in v105" would
have reported a release that did not exist. The page carries `id="v101"`...
anchors, one per real release; the probe now reads those and gets a clean
contiguous index.

**The fingerprint shape was inverted in all five.** The content signal sat in
`checksums`, which `_conventions` § 12 defines as "sha256 over the bytes used to
derive `headers`" -- these probes fetch no body and compute no such digest, and
gnomad_metrics was storing a raw ETag there. Signals moved under `headers` with
`checksums` empty, matching peptideatlas and the sibling branch. The redundant
sha256 went with them: it was a pure function of values already in the compared
surface, so it added no detection power while doubling every diff.

Note this keeps changes tiered "schema" rather than "routine". That is
deliberate, per `classify_risk`'s own policy -- "Defaults to schema for anything
it cannot read ... the reverse just opens one extra PR" -- since none of these
probes can see column names.

**gnomad_metrics carried the sibling branch's bugs.** `.strip('"')` (mangles
weak and transform-suffixed validators) replaced with `normalize_etag`; the
`and` guard that accepted a half-validated response -- silently dropping an
object out of the compared surface, or baking a null length in -- now requires
both and rejects empties; a non-identity `Content-Encoding` response is refused
rather than recording a compressed length. Three sequential HEADs at 30s each
had a 180s worst case against the runner's 60s SIGALRM, so a slow bucket
reported probe_failed on a healthy source; now a (5, 10) connect/read pair on one
shared Session. Failures are collected across objects instead of raising on the
first, which had let a fault on either frozen v2.1.1 table abort before v4.0 --
the current release -- was probed at all.

**pqtl and alphagenome rested on undocumented upstream shapes.** `collection[-1]`
assumed medRxiv orders oldest-first; on a newest-first response it pinned v1 and
would have reported clean through the exact event the probe exists to detect.
Now selected by version. `str(latest.get("version"))` turned a missing field into
the literal "None" -- truthy, and indistinguishable from a real label; now fails
closed. `doi` left the compared surface: the request URL is built from it, so it
could never drift. alphagenome no longer hard-requires PyPI's deprecated
`releases` key, which would have turned an upstream API change into a permanent
probe_failed for an SDK that never moved; `info.version` is the signal, and the
release list is informational so pre-release uploads cannot fire a no-op PR.

**All five now use `request_with_retry`**, the helper written after a single
GenCC 429 failed the 2026-08-04 scheduled run. Bare `requests` had reintroduced
that bug five times, against two hosts (PyPI, api.biorxiv.org) that rate-limit
unauthenticated clients. Both HTML scrapes also decode explicitly rather than
letting requests guess a charset, and COSMIC rejects a redirected response
instead of scraping a login page that answers 200.

**Claims I made that were not true, now made true or removed.** Four docstrings
asserted their coverage limits were "recorded in SKILL.md" while all five
SKILL.md files still said the probe was a stub -- CONTRIBUTING.md:26 rejects
exactly this. Every one now documents what its probe detects AND what it cannot,
and cosmic_cgc gained the drift section it never had. The dbNSFP docstring cited
"31 entries" against a baseline holding 30. The KNOWN_INCOMPLETE comment said
"the remaining three entries" of a five-entry dict and described them as having
nothing to probe, when this PR gave all three a live probe.

**Tests that could not fail, rewritten.** The gnomad fixtures gave all three
objects identical headers and only exercised the both-missing guard; there are
now distinct per-object fixtures and a parametrized case per degradation. The
dbNSFP "ordering" test never varied order; the COSMIC "numeric sort" test could
not fail against an int-typed implementation; alphagenome's guard test tripped
both branches at once. Added a new suite validating every committed baseline at
rest -- `placeholder_baseline_reason`, a real `fetched_at`, and a non-empty
compared surface -- which is the check the ledger's "captured from live probe
runs" claim leaned on and nothing enforced.

The dbNSFP dead-download-links finding is tracked as #321 and referenced from
the probe and SKILL.md rather than left only in a Python comment.

Refs #177, #321
@enriquea
enriquea force-pushed the feat/real-drift-probes-remaining-stubs branch from 4e4adb2 to c87342e Compare September 1, 2026 07:57
@enriquea
enriquea merged commit 9b19484 into dev Sep 1, 2026
10 of 11 checks passed
@enriquea
enriquea deleted the feat/real-drift-probes-remaining-stubs branch September 1, 2026 08:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants