Skip to content

NCBI Web BLAST parity wave — 8 code fixes + 12 documented gaps

Date: 2026-05-31

Motivation

A focused audit of the BLAST submit / result experience against https://blast.ncbi.nlm.nih.gov/Blast.cgi catalogued 20 concrete gaps. Some were silent scientific data loss (reading frames dropped from translated BLAST output), some were UX gaps (no Copy / Download FASTA on the Alignment viewer, no Frame indicator on the Descriptions table), and some were Charter §9 hardening gaps with no regression test guarding them. The longer list mixes "cheap to ship" with "needs a new tree-builder library" — the wave deliberately ships only the cheap-and-impactful items and documents the rest so a future session can pick them up without re-doing the audit.

User-facing change

Translated programs now show reading frames

blastx, tblastn, and tblastx runs surface Hsp_query-frame / Hsp_hit-frame from BLAST XML and the query frame / subject frame columns from -outfmt 6 / 7 tabular output. The Descriptions table renders a Frame badge (qframe/sframe) next to the Query Range column and the Alignment viewer footer shows Query frame: N · Subject frame: N when the program actually emitted them. Nucleotide-only programs (blastn, blastp) that emit 0 are filtered out so users do not see a misleading "Frame: 0".

Alignment viewer Copy / Download FASTA

The Alignment viewer gained three buttons mirroring NCBI's per-hit actions:

  • Copy alignment — copies a pairwise text block in NCBI's Query/Sbjct positional layout, wrapped at 60 columns.
  • Copy FASTA — copies a two-record FASTA (query + subject) with gaps stripped.
  • Download FASTA — downloads the same two-record FASTA as <qseqid>__<sseqid>.fasta, with non-alphanumeric characters sanitised to underscores for cross-OS safety.

Each action shows a 2 s feedback message inline so screen readers and visual users both see confirmation.

NCBI Advanced submit flags accepted via OpenAPI today

The BLAST submit option whitelist _BLAST_SUBMIT_OPTION_KEYS grew from ~40 to ~60 keys, adding every algorithm / filter / output flag the NCBI Web BLAST Advanced submit form exposes: matrix, threshold, comp_based_stats, culling_limit, best_hit_overhang, best_hit_score_edge, qcov_hsp_perc, perc_identity, gilist, negative_gilist, seqidlist, xdrop_gap, xdrop_gap_final, xdrop_ungap, window_size, parse_deflines, soft_masking, lcase_masking, ungapped, num_alignments, num_descriptions. OpenAPI callers can use these today via the top-level submit body or the options sub-dict. UI controls (dropdowns / sliders) for these flags are deferred to a follow-up wave and tracked in the Stage 11 plan matrix.

Charter §9 regression test

A new regression test (test_blast_results_routes_never_emit_sas_tokens) walks the JSON responses from every BLAST result route the browser actually consumes (/results, /results/aggregate, /results/alignments) and asserts that no Storage SAS marker (?sig=, &sig=, ?sv=, skoid=, sktid=, AccountKey=, …) ever appears. This locks in the existing "no SAS tokens in the browser" contract so any future regression that re-introduces generate_blob_sas or returns a raw signed URL fails loudly here instead of in production telemetry.

API / IaC diff summary

Surface Change
api/services/blast/submit_payload.py Whitelist grew from ~40 to ~60 keys (NCBI Advanced flags).
api/services/blast/results_parser.py qframe / sframe added to _INT_COLUMNS; query frame / subject frame / frame added to _FIELD_LABEL_TO_COLUMN; _build_hit_row extracts <Hsp_query-frame> and <Hsp_hit-frame> and drops 0.
web/src/api/blast.ts BlastHit interface gained optional qframe / sframe fields.
web/src/pages/blastResults/analytics/AlignmentViewer.tsx Footer renders Query frame / Subject frame; new AlignmentExportActions component with Copy alignment / Copy FASTA / Download FASTA; new helpers buildPairwiseAlignmentText, buildAlignmentFasta, wrapFasta.
web/src/pages/blastResults/analytics/BlastHitsTable.tsx Conditional Frame badge (qframe/sframe) next to Query Range column with tooltip.
api/tests/test_blast_submit_route_options.py +2 tests covering the new whitelist via top-level body and options sub-dict.
api/tests/test_blast_results_parser.py +3 tests covering qframe / sframe extraction (XML + tabular) and zero-drop.
api/tests/test_blast_results_routes.py +2 tests covering the no-SAS contract on every browser-facing result route.
docs/research/web-blast-compatibility-plan.md New Stage 11 section with the 20-gap matrix, Critique Hardening Loop pass 1, and updated Stage Progress Board entry.

No infrastructure (Bicep / Container App template) changes.

Validation evidence

uv run pytest -q api/tests
2225 passed, 3 skipped in 33.85s
# baseline 2218 → +7 new tests, no regressions

uv run ruff check api
All checks passed!

cd web && npm test -- --run
Test Files  56 passed (56)
     Tests  433 passed (433)

cd web && npm run build
✓ built in 8.07s
# existing large-chunk warning unchanged

No redeployment was performed (Charter §13 "Do NOT redeploy for ordinary code changes"): the changes are entirely backend api/, frontend web/, and docs — no sidecar layout, no Container App template, no Bicep, no terminal/Dockerfile*, no exec_server.py.

Stage 11 plan-doc critique log

The full 20-gap matrix (severity + status + cost estimate per item) and the Critique Hardening Loop pass 1 record live in docs/research/web-blast-compatibility-plan.md under the new "Stage 11: NCBI Web BLAST Parity Wave (2026-05-31)" section. The 12 remaining items are split across:

  • 4 Planned Medium items (NCBI 5-band bit-score legend on Graphic Summary, Distance Tree tab, Karlin–Altschul header parameters, Reformat results re-render route).
  • 4 Planned UI-only items for whitelist entries 1–5 (matrix dropdown, comp_based_stats dropdown, qcov_hsp_perc / perc_identity sliders, etc.).
  • 4 Planned Low items (multi-query effective search space, masking defaults doc surface, phase-aware cancel, result pagination, FASTA log sanitisation, MSA viewer deep-link).

Wave 2 is scheduled to cover the UI controls for whitelist entries 1–5 plus the four Planned Medium items.