[Changelog] Fix orphan paragraph in 5.2.0 entry and gate future fragments#5611
Conversation
…ents The 2026-05-14 auto-version-bump compiled fragment ``jichuanh-ik-newton-compat-mvp.minor.rst`` verbatim, embedding a flush-left paragraph inside the Added bullet list. Sphinx ``-W`` rejects this with ``Unexpected indentation [docutils]``, breaking ``Build Latest Docs`` on every open PR. Repromote the orphan paragraph to a top-level ``*`` bullet so the list stays well-formed, and teach ``Fragment.validate()`` to reject the same shape in future fragments: any non-blank line inside a section body that is neither a bullet start nor a continuation now fails the ``changelog-check`` PR gate with a descriptive error pointing back at the exact offending line. Verified against all 131 historical RST fragments — only the one that caused this incident is flagged; zero false positives elsewhere.
Greptile SummaryThis PR fixes a Sphinx doc-build failure introduced by the 2026-05-14 version-bump commit, which spliced a flush-left paragraph verbatim into
Confidence Score: 5/5Safe to merge — the CHANGELOG.rst fix directly unblocks every open PR's doc build, the new validator rule is narrow and well-tested, and no production code paths are touched. All changes are either a one-line RST formatting correction or a new validation predicate exercised by a dedicated fixture test. The validator logic correctly handles blank lines, continuation lines, and bullet lines using the same format assumptions as the pre-existing checks. No files require special attention. Important Files Changed
Sequence DiagramsequenceDiagram
participant Contributor
participant PRGate as Changelog Fragment Check (CI)
participant Validate as Fragment.validate()
participant Sphinx as Sphinx doc build
Contributor->>PRGate: Open PR with fragment file
PRGate->>Validate: validate() each fragment
Validate->>Validate: check filename
Validate->>Validate: check non-empty
Validate->>Validate: check section headings present
Validate->>Validate: check each section has at least 1 bullet
Validate->>Validate: NEW: check no orphan paragraphs
alt orphan paragraph found
Validate-->>PRGate: error message with offending line
PRGate-->>Contributor: Gate fails — fix before merge
else all checks pass
Validate-->>PRGate: None (valid)
PRGate-->>Contributor: Gate passes
Contributor->>Sphinx: compile() merges fragment into CHANGELOG.rst
Sphinx-->>Contributor: Doc build succeeds
end
Reviews (1): Last reviewed commit: "[Changelog] Fix orphan paragraph in 5.2...." | Re-trigger Greptile |
There was a problem hiding this comment.
Code Review Summary
This PR fixes a documentation build failure caused by malformed RST structure in CHANGELOG.rst and adds validation to prevent similar issues in the future.
✅ Assessment: Ship it
The fix is clean, well-scoped, and the validation logic is correct.
Design & Architecture
Approach: The two-part fix (immediate repair + future prevention) is the right approach. Fixing just the symptom without adding validation would leave the codebase vulnerable to the same issue recurring.
File placement: Correct. The validation logic belongs in Fragment.validate() since that's the single point where fragment content is validated during the PR gate.
Self-contained: This change has no cross-module impact. The changelog tooling is isolated infrastructure code.
Implementation Review
tools/changelog/cli.py (lines 299-320)
The orphan paragraph detection logic is sound:
for section, lines in sections.items():
for offset, line in enumerate(lines):
if not line.strip():
continue
if line[0].isspace() or line.lstrip().startswith("*"):
continue
# ... rejectThe algorithm correctly identifies:
- ✅ Blank lines (skip)
- ✅ Continuation lines (leading whitespace)
- ✅ Bullet starts (
*after stripping leading whitespace) - ✅ Orphan paragraphs (column-0 non-blank, non-bullet)
Note: The check line.lstrip().startswith("*") is slightly looser than line.startswith("* ") — it would accept *text without a space. However, this is acceptable because:
- RST parsers also accept
*itemas a bullet (space not strictly required) - Being lenient here avoids false positives
- The existing
emptycheck already validates bullets exist
source/isaaclab/docs/CHANGELOG.rst
The fix correctly promotes the orphan paragraph to a top-level bullet with proper indentation of continuation lines. The semantic content is preserved.
Test Coverage
✅ Adequate for this change:
- New test
test_validate_rejects_orphan_paragraph_from_fixture()exercises the exact failure mode - Fixture
3004.rstis a realistic reproduction of the problematic pattern - The PR description confirms validation was run against 131 historical fragments with zero false positives
No additional tests needed — this is a validation rule addition with a matching regression test.
Minor Observations
🔵 Info: The error message is excellent — it explains the RST mechanics and points to the exact offending line. This will help contributors fix their fragments quickly.
Verdict
Ship it. The fix is correct, the validation is well-designed, and the test coverage is appropriate. The doc build should pass once this merges.
Summary
Build Latest Docsis failing on every open PR with:(failing job: https://github.com/isaac-sim/IsaacLab/actions/runs/25847575509/job/75946304877)
The 2026-05-14 auto-version-bump (
b65a1ac2b73) compiled fragmentsource/isaaclab/changelog.d/jichuanh-ik-newton-compat-mvp.minor.rstverbatim into the new5.2.0block. That fragment contained a flush-left paragraph inside theAddedbullet list, which Sphinx-Wrejects.Fix
*bullet insource/isaaclab/docs/CHANGELOG.rstso the bullet list underAddedstays well-formed.Fragment.validate()now scans every section body and rejects any non-blank line that is neither a*bullet start nor a continuation (leading whitespace). The error message points back at the exact offending line so the contributor sees it in theChangelog Fragment CheckPR gate output before merge.Replayed the new check against all 131 historical fragments — it flags exactly one, the one that caused this incident. Zero false positives elsewhere.
Test plan
pytest tools/changelog/test/— 83 pass (24 prior validate tests + 1 new orphan-paragraph fixture test).pre-commit runon all touched files — clean.Build Latest Docswill pass on this PR (theUnexpected indentationline is gone).Files
source/isaaclab/docs/CHANGELOG.rst— bullet-prefix the orphan paragraph.tools/changelog/cli.py— orphan-paragraph rejection inFragment.validate().tools/changelog/test/test_validate.py+test/invalid_content/3004.rst— fixture + test for the new rule.source/isaaclab/changelog.d/jichuanh-fix-docs-changelog-indentation.skip— satisfies the gate (CHANGELOG-only edit, no user-visible entry needed).