Skip to content

A reversal draws shapes pgb refuses, and it refuses the whole document #52

Description

@turner

What

tubemap.js can draw a reversal — the corners and vertical rectangles that render an inverted strand. pgb's parseBands.ts cannot read any of those shapes, and because its whole-document gate compares drawables counted against drawables matched, one unreadable shape does not degrade the picture: it refuses the entire document, and the researcher sees an error card instead of a tube map.

Found on 2026-08-28 while verifying #22 against pgb's real parser. This predates #22 and #22 did not change it in either direction — the pre- and post-#22 documents are byte-identical modulo three removed attributes, and pgb recovers bit-identical arrays from both.

Why the grammar misses them

pgb matches every band with one pattern (parseBands.ts, FILL / RECT / PATH). A reversal is off it in three independent ways:

shape what the grammar wants what the layout emits
corner trackName="...", non-empty no trackName — the layout builds a corner without one
corner M x y C ... V ... C ... Z (cubics) M x y Q ... H ... Q ... Z (quadratics, tubemap.js:3052-3070)
corner and vertical rect the literal fill-opacity: 1; inside style no fill-opacity at all — the document has never painted one on these

Any one of the three is enough. pgb then throws NonConformingDocument: "Of the N drawables in g.track, M are not bands this renderer recognises."

How live is it

Latent, not live, as far as anything committed can show. Across all five real subgraphs in tests/fixtures/seqtubemap/: zero corners, and every band carries fill-opacity: 1.

fixture rect curve corner bands with no opacity
chr8 90 bp 518 74 0 0
chr1 600 bp 3,725 4,364 0 0
chr8 1.4 kb 6,542 6,704 0 0
chr1 8.0 kb 16,422 18,598 0 0
chr1 4.2 kb 19,482 25,313 0 0

But that is a property of five regions, not of the layout. tests/node/document-conformance.test.mjs now contains a synthetic reversal — one strand sent backwards through three segments of the smoke fixture — which draws corners and which the transcribed grammar refuses. So the shape is reachable; what is unknown is whether any real region produces one.

pgb's own ADR 0004 records that a chr8p23.1 document containing an inversion was refused whole once before, for a different over-strict rule that was then withdrawn. Same failure shape, second cause.

Worth deciding, not obvious

Three possible readings, and they are not equivalent:

  1. The client is needlessly strict. fill-opacity is required as a literal and then never used — it is not in ParsedMap at all. A pattern that accepted an optional opacity would cost nothing and would take one of the three causes off the table. Likewise trackName is required on every band but only read from the first band carrying each id.
  2. The server should not draw shapes it cannot describe. Corners are a drawing artifact of the layout, and #24's band format has to say something about them regardless.
  3. It genuinely never happens and the right move is to find out, by looking for a region that inverts.

(1) and (2) are cheap; (3) is the one that says whether either is urgent.

Note for #23 / #24

Increment C is where this stops being a regex problem. ?format=bands publishes numbers rather than a drawing, and the band data already carries corners as a first-class kind with the strand they belong to — so the client would receive them as data instead of failing to match them as a path. Worth deciding what a corner means on that route before it ships.

Acceptance criteria

  • Established whether any real region produces a reversal — a region named, or the search recorded as having found none
  • A decision recorded on which side changes: the client's grammar, the server's shapes, or neither
  • If the client changes, the change is made in pgb and its own fixtures cover a reversal
  • tests/node/document-conformance.test.mjs's reversal test updated to assert whatever the decision makes true

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triageMaintainer needs to evaluate this issue

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions