Found while validating #81/#82 — distinct from both. Not about the wrap-duplication bug (that's
fixed and verified) and not about a table's total width (that's #82) — this is about a single
column's text-wrap width inside a table where some rows give <Cell width="..."> explicitly and
others don't.
Summary
Per nodes.md: "column widths come from each <Cell width="...">'s explicit width, else an even
split" — the documented behaviour is that a column's width is resolved once, from whichever row(s)
specify it, and applies to the whole column. That resolution is correct for painting: the cell
border/background of a row with no explicit width is drawn at the same width as a sibling row
that does specify one. But the text inside that row is wrapped as if the column were much
narrower than the box it's actually painted in — measurement and layout disagree about the column's
width.
Reproducer
<Document>
<Body margin_left="40" margin_top="20" margin_right="40">
<Table>
<THead><HTitle>N</HTitle><HTitle>Action</HTitle><HTitle>Type</HTitle><HTitle>Owner</HTitle><HTitle>Due</HTitle><HTitle>Status</HTitle></THead>
<TBody>
<Row>
<Cell width="24"><Text font_size="7.5" alignment="center">1</Text></Cell>
<Cell width="230"><Text font_size="7.5">Add a signal-quality confidence indicator to the SpO2 tile, distinguishing "low signal" from a genuine reading</Text></Cell>
<Cell width="54"><Text font_size="7.5" alignment="center">Corrective</Text></Cell>
<Cell width="68"><Text font_size="7.5">Firmware team</Text></Cell>
<Cell width="58"><Text font_size="7.5" alignment="center">2026-04-30</Text></Cell>
<Cell width="58"><Text font_size="7.5" alignment="center">In progress</Text></Cell>
</Row>
<Row>
<!-- no width on any Cell in this row -- should inherit column widths from row 1 -->
<Cell><Text font_size="7.5" alignment="center">2</Text></Cell>
<Cell><Text font_size="7.5">Update risk file RMF-940 to add a runtime detection control for non-validated probes as a design mitigation, not labelling alone</Text></Cell>
<Cell><Text font_size="7.5" alignment="center">Preventive</Text></Cell>
<Cell><Text font_size="7.5">A. Menon</Text></Cell>
<Cell><Text font_size="7.5" alignment="center">2026-03-15</Text></Cell>
<Cell><Text font_size="7.5" alignment="center">Closed</Text></Cell>
</Row>
</TBody>
</Table>
</Body>
</Document>
Rendered output (pdftotext -layout, matches the visual PDF — the column border for row 2's
Action cell is painted at the same ~230pt width as row 1's; only the text wrapping is wrong):
N Action Type Owner Due Status
Add a signal-quality confidence indicator to the SpO2 tile,
1 distinguishing "low signal" from a genuine reading Corrective Firmware team 2026-04-30 In progress
Update risk file
RMF-940 to add a
runtime detection
2 control for Preventive A. Menon 2026-03-15 Closed
non-validated probes
as a design mitigation,
not labelling alone
Row 1's Action text (114 characters) wraps to 2 lines spanning the full column. Row 2's Action text
(129 characters, similar length) wraps to 7 lines of one-to-four words each, as if the
available width were roughly a third of the actual column — while the column's own left/right
border position in the rendered PDF matches row 1's exactly.
A second, simpler 2-column/2-row reproducer (repro-minimal.craft, attached) shows the same effect
at smaller scale; a full 6-column/2-row version matching the case above is repro.craft.
Impact
Any data-driven table where only the header row (or first data row) happens to carry explicit
Cell width, and subsequent rows are written without repeating it — which is a completely natural
way to author a table by hand, since the docs describe width as a column property resolved once
— renders every other row's long-text column absurdly narrow and tall, wasting vertical space and
looking broken, while the short-text columns in the same rows line up perfectly. Easy to miss in
a quick render check because the table looks structurally fine (borders align) and only degrades
on the specific rows/columns holding longer free text.
Suggested area
Given the shape of the bug — layout/paint uses the correctly resolved column width, but text
measurement doesn't — this smells like the same family as #81's fix (the new
docraft_loom_text_wrapper module, or the interaction between it and table column-width
resolution): whatever computes a <Text>'s wrap width for a <Cell> with no explicit width
likely falls back to a per-cell "natural"/un-resolved value instead of reading the column width
that resolve_table_column_widths already settled on for its sibling rows.
Found while validating #81/#82 — distinct from both. Not about the wrap-duplication bug (that's
fixed and verified) and not about a table's total width (that's #82) — this is about a single
column's text-wrap width inside a table where some rows give
<Cell width="...">explicitly andothers don't.
Summary
Per
nodes.md: "column widths come from each<Cell width="...">'s explicit width, else an evensplit" — the documented behaviour is that a column's width is resolved once, from whichever row(s)
specify it, and applies to the whole column. That resolution is correct for painting: the cell
border/background of a row with no explicit
widthis drawn at the same width as a sibling rowthat does specify one. But the text inside that row is wrapped as if the column were much
narrower than the box it's actually painted in — measurement and layout disagree about the column's
width.
Reproducer
Rendered output (
pdftotext -layout, matches the visual PDF — the column border for row 2'sAction cell is painted at the same ~230pt width as row 1's; only the text wrapping is wrong):
Row 1's Action text (114 characters) wraps to 2 lines spanning the full column. Row 2's Action text
(129 characters, similar length) wraps to 7 lines of one-to-four words each, as if the
available width were roughly a third of the actual column — while the column's own left/right
border position in the rendered PDF matches row 1's exactly.
A second, simpler 2-column/2-row reproducer (
repro-minimal.craft, attached) shows the same effectat smaller scale; a full 6-column/2-row version matching the case above is
repro.craft.Impact
Any data-driven table where only the header row (or first data row) happens to carry explicit
Cell width, and subsequent rows are written without repeating it — which is a completely naturalway to author a table by hand, since the docs describe width as a column property resolved once
— renders every other row's long-text column absurdly narrow and tall, wasting vertical space and
looking broken, while the short-text columns in the same rows line up perfectly. Easy to miss in
a quick render check because the table looks structurally fine (borders align) and only degrades
on the specific rows/columns holding longer free text.
Suggested area
Given the shape of the bug — layout/paint uses the correctly resolved column width, but text
measurement doesn't — this smells like the same family as #81's fix (the new
docraft_loom_text_wrappermodule, or the interaction between it and table column-widthresolution): whatever computes a
<Text>'s wrap width for a<Cell>with no explicitwidthlikely falls back to a per-cell "natural"/un-resolved value instead of reading the column width
that
resolve_table_column_widthsalready settled on for its sibling rows.