Skip to content

The band payload carries a segment box as numbers, not as a path command - #69

Merged
turner merged 1 commit into
mainfrom
feat/segment-box-as-numbers
Sep 1, 2026
Merged

turner merged 1 commit into
mainfrom
feat/segment-box-as-numbers

Conversation

@turner

@turner turner commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Closes #66.

A segment box travelled as the path command the document draws it with — "M 11 20 Q 11 11 20 11 L 67 11 …" — and every one of them is a rounded rectangle whose five numbers the layout has before it builds the string. Now the numbers travel:

"box": { "left": 11, "top": 11, "right": 76, "bottom": 5564, "radius": 9 }

outline is replaced rather than joined, and version stays 1: a version protects readers and this format has none, so carrying both would have kept the string in the format forever and left the reader pgb is writing now with two ways to find the same rectangle. docs/band-format.md says so, and says when that exception closes.

The change

  • seqtubemap/band-data.mjs — segmentBox, the validating builder, in the same shape as curveBand/rectBand. It refuses a box narrower or shorter than the two corners it is drawn with, where the layout that produced it is still in scope.
  • seqtubemap/tubemap.js — drawNodes loses 60 lines of running-position path assembly and collects the five numbers.
  • seqtubemap/emit-document.mjs — segmentOutline writes the drawing command out of them, which is now the only place a box becomes a drawing.

Measured

On the 8.0 kb region: header 0.35 MB → 0.20 MB, whole response 1.25 MB → 1.10 MB, ratio against the SVG 8.0× → 9.0×. Less than the 0.21 MB the outlines cost, because five keys and five full-precision doubles are 0.06 MB of it. The table in docs/band-format.md is updated for all five regions.

The SVG route's bytes did move — read this before merging

#66 asked for the goldens and the five real subgraphs to stay byte-identical. They did not, and the goldens are re-baselined.

The layout walked the outline as a running position — x += pixelWidth, x += 9, then back down — so it printed the same edge twice, one ulp apart, wherever those steps did not undo each other: 225.85714285714286 along a box's top and 225.8571428571429 along its bottom. A box has one left edge, so no five numbers reproduce both spellings. This is the same defect the issue cites as the reason pgb needs nine tolerant comparisons.

What actually changed:

  • 4–8 numbers per golden document, each within 1.5e-16 relative of what it was, with no command and no element altered.
  • One box of the 1,219 in the five real subgraphs now carries two straight runs 4.5e-13 long where it had none, since (x + 9) - (x - 9) is not exactly 18. Left as it is — a tolerance there would be the first of the comparisons this ticket exists to delete.

Both are written down in segmentOutline's comment, where the next reader will meet them.

Verification

  • Node: 111 pass, 0 fail, 2 skipped. A new test checks every box of all five real subgraphs against the rectangle recovered from the emitted document by a parser that knows nothing about how it was written, with both the two-arc and three-arc spellings present.
  • Python: 37 pass, 5 skipped (vg absent).

🤖 Generated with Claude Code

https://claude.ai/code/session_01Bts5upzYVgcUenvd9byKgw

A segment box travelled as the path command the document draws it with —
`"M 11 20 Q 11 11 20 11 L 67 11 …"` — and every one of them is a rounded
rectangle whose five numbers the layout has before it builds the string. Now
the numbers travel:

    "box": { "left": 11, "top": 11, "right": 76, "bottom": 5564, "radius": 9 }

This is #23's argument one level down, and the last string in the payload a
client had to parse back into numbers. `outline` is replaced rather than joined,
and `version` stays 1: a version protects readers and this format has none, so
carrying both would have kept the string in the format forever and left the
reader `pgb` is writing now with two ways to find the same rectangle.
`docs/band-format.md` says so, and says when that exception closes.

`drawNodes` collects the five numbers through `segmentBox`, which refuses a box
narrower or shorter than the two corners it is drawn with — where the layout
that produced it is still in scope, like every other refusal this format makes.
`emit-document.mjs` writes the drawing command out of them, which is now the
only place a box becomes a drawing.

Measured on the 8.0 kb region: the header goes 0.35 MB -> 0.20 MB, the whole
response 1.25 MB -> 1.10 MB, and the ratio against the SVG 8.0x -> 9.0x. Less
than the 0.21 MB the outlines cost, because five keys and five doubles are
0.06 MB of it.

**The SVG route's bytes did move**, against what #66 asked for, and the goldens
are re-baselined. The layout walked the outline as a running position — `x +=
pixelWidth`, `x += 9`, then back down — so it printed the same edge twice, one
ulp apart, wherever those steps did not undo each other: `225.85714285714286`
along the top of a box and `225.8571428571429` along its bottom. That is the
same defect the ticket cites as the reason `pgb` needs nine tolerant
comparisons, so no five numbers can reproduce those bytes. What changed is 4-8
numbers per golden document, each within 1.5e-16 of what it was, with no command
and no element altered; and one box of the 1,219 in the five real subgraphs now
carries two straight runs 4.5e-13 long where it had none, since `(x + 9) -
(x - 9)` is not exactly 18. Left as it is: a tolerance there would be the first
of the comparisons this ticket exists to delete.

Closes #66

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bts5upzYVgcUenvd9byKgw
@turner
turner merged commit edec8ca into main Sep 1, 2026
2 checks passed
@turner
turner deleted the feat/segment-box-as-numbers branch September 1, 2026 20:19
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.

The band payload carries a segment box as numbers, not as a path command

1 participant