diff --git a/paperforge/worker/ocr_render.py b/paperforge/worker/ocr_render.py index 461b6999..440ab465 100644 --- a/paperforge/worker/ocr_render.py +++ b/paperforge/worker/ocr_render.py @@ -707,9 +707,22 @@ def render_fulltext_markdown( for i, block in enumerate(structured_blocks): old_role = block.get("role") new_role = new_blocks[i].get("role") if i < len(new_blocks) else old_role - # Never demote backmatter/reference headings — those are explicit + # Never demote tail/candidate roles — those are explicit # test-level decisions, not normalization targets. - if old_role in ("backmatter_heading", "backmatter_boundary_heading", "reference_heading"): + _PROTECTED = frozenset({ + "backmatter_heading", + "backmatter_boundary_heading", + "backmatter_body", + "reference_heading", + "reference_item", + "figure_caption_candidate", + "backmatter_heading_candidate", + "backmatter_boundary_candidate", + "non_body_insert", + "subsection_heading", + "sub_subsection_heading", + }) + if old_role in _PROTECTED: continue if old_role != new_role: block["role"] = new_role diff --git a/tests/test_ocr_render_stabilization.py b/tests/test_ocr_render_stabilization.py index e2ac4e4c..f3b02b35 100644 --- a/tests/test_ocr_render_stabilization.py +++ b/tests/test_ocr_render_stabilization.py @@ -846,6 +846,27 @@ def test_stabilize_tail_zone_references_kept_separate() -> None: assert "