Skip to content

fix(ci): preserve code while normalizing issue media - #1270

Draft
Ingwannu wants to merge 1 commit into
devfrom
agent/fix-1196-media-normalization
Draft

fix(ci): preserve code while normalizing issue media#1270
Ingwannu wants to merge 1 commit into
devfrom
agent/fix-1196-media-normalization

Conversation

@Ingwannu

@Ingwannu Ingwannu commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Summary

  • treat exact placeholder fallback text inside HTML media as empty
  • preserve fenced and indented code with ordered restoration tokens
  • avoid positional restoration after multiline media stripping changes line count

Root cause

The issue-quality normalizer protected every indented line before it identified HTML media blocks. Indented <source> and <img> children were therefore preserved as Markdown code, keeping otherwise media-only blocks substantive. Restoration also depended on original line indexes even though stripping a multiline media block can remove lines. Separately, placeholder fallback text such as <video>No response</video> was treated as a real caption.

The fix distinguishes indented children of an active HTML media block from literal Markdown code, protects fenced and indented examples with collision-resistant ordered tokens, and restores those tokens independently of line count. Only exact placeholder fallback values are removed; real captions remain substantive.

Validation

  • node --test .github/scripts/issue-quality.test.cjs — 112 passed
  • related issue-quality / PR-quality / target-enforcement tests — 211 passed
  • bun run typecheck — passed
  • bun run privacy:scan — passed
  • git diff --check — passed

Closes #1196

Summary by CodeRabbit

  • Bug Fixes
    • Improved handling of media markup in issue content, including nested picture, audio, and video elements.
    • Removes media blocks with placeholder-only fallback text while preserving meaningful captions and prose.
    • Correctly preserves fenced and indented code examples, including media-like markup.
    • Prevents formatting artifacts when content is processed.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The issue-quality normalizer now protects fenced and indented code during media stripping, tracks HTML media nesting, restores protected content by token, and removes media blocks containing only recognized placeholders.

Changes

Media normalization

Layer / File(s) Summary
Protected code handling
.github/scripts/issue-quality-core.cjs:69-140, .github/scripts/issue-quality.test.cjs:417-437
stripMediaTokens protects fenced and indented code with indexed tokens. Indented media content inside HTML media blocks is treated as media content. Tests verify fenced code, indented Markdown, surrounding protected lines, and absence of null-byte markers.
Placeholder media cleanup
.github/scripts/issue-quality-core.cjs:167-169, .github/scripts/issue-quality.test.cjs:399-415
stripHtmlMedia removes empty and placeholder-only video or audio blocks. Tests cover nested picture markup, fallback captions, clean, and isMediaOnly.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested reviewers: wibias, lidge-jun

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the primary change: preserving code during CI issue-media normalization.
Linked Issues check ✅ Passed The changes address all coding objectives in #1196, including placeholder handling, protected-code preservation, media nesting, and safe token restoration.
Out of Scope Changes check ✅ Passed The code and test changes remain focused on the issue-quality media-normalization defects described in #1196.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/fix-1196-media-normalization

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the bug Something isn't working label Aug 8, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/scripts/issue-quality-core.cjs:
- Around line 127-133: Update htmlMediaDepthDelta and its caller to preserve
media-tag scanning state across lines, counting a picture, video, or audio
opening tag once its eventual closing “>” is encountered even when attributes
span lines, while retaining correct closing-tag handling. Add a regression test
covering a multiline opening tag with indented children and verify media-only
normalization still succeeds.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 7dbdba0a-744e-4249-92fe-1b6334f5bb1d

📥 Commits

Reviewing files that changed from the base of the PR and between fdc47db and 03b0511.

📒 Files selected for processing (2)
  • .github/scripts/issue-quality-core.cjs
  • .github/scripts/issue-quality.test.cjs

Comment on lines +127 to +133
function htmlMediaDepthDelta(line) {
let delta = 0;
for (const match of line.matchAll(/<(\/)?(picture|video|audio)\b[^>]*>/gi)) {
if (match[1]) delta -= 1;
else if (!/\/\s*>$/.test(match[0])) delta += 1;
}
return delta;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Handle HTML media start tags that span multiple lines.

htmlMediaDepthDelta only detects a media tag when its closing > is on the same line. A valid block with a multiline opening tag leaves mediaDepth at zero.

<video
    src="clip.mp4">
    <source src="clip.mp4">
</video>

The indented attribute and child lines are then masked as Markdown code. stripHtmlMedia cannot remove the resulting tokenized block. isMediaOnly returns false, so media-only issue content bypasses normalization.

Track media-tag state across lines. Set media depth when the scanner sees an opening <picture>, <video>, or <audio> tag. Add a regression test for a multiline opening tag with indented children.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/scripts/issue-quality-core.cjs around lines 127 - 133, Update
htmlMediaDepthDelta and its caller to preserve media-tag scanning state across
lines, counting a picture, video, or audio opening tag once its eventual closing
“>” is encountered even when attributes span lines, while retaining correct
closing-tag handling. Add a regression test covering a multiline opening tag
with indented children and verify media-only normalization still succeeds.

@lidge-jun

Copy link
Copy Markdown
Owner

Thanks for this — the token-based restoration is the right shape, and it fixes the line-position fragility properly.

One blocker before it can land, and it is the same one that stopped my own attempt at this: the placeholder check is too broad for media fallback text.

isPlaceholderOnlyValue is a whole-form-field predicate. Inside a media element it also matches TBD, N/A, None, and Todo, not just the generated No response:

                     dev            this PR
<video>TBD</video>   preserved   ->  ""
<video>N/A</video>   preserved   ->  ""
<video>None</video>  preserved   ->  ""

That flips a legitimate submission. A feature request whose example is <video src="...">TBD</video> is currently accepted and becomes media-only with this change, so the section reads empty and enforce-issue-quality closes it. Silencing a real report is worse than the placeholder leak we are fixing.

What I would suggest instead: a media-specific predicate limited to the serialization GitHub actually emits for an unanswered field — No response, plus its _..._ and *...* markdown wrappers — rather than reusing the form-field vocabulary. Or an explicit mode on the shared helper so the two contexts stay distinguishable.

Worth adding negative tests for TBD, N/A, None, a non-English caption, an emoji, a bare filename, and a URL — those are the shapes that separate "the form said nothing" from "the reporter wrote something short".

The restoration half I have no concerns about. It is only the one predicate.

@lidge-jun

Copy link
Copy Markdown
Owner

One more, found while verifying the first: the depth scanner only recognises a media tag once its > lands on the same line.

htmlMediaDepthDelta matches /<(\/)?(picture|video|audio)\b[^>]*>/, so an opening tag split across lines never increments the depth, the children are not treated as inside HTML, and their indentation gets protected as code. Reproduced on this branch:

<video src="https://x/a.mp4">        <video
    <source srcset="a.webm">           src="https://x/a.mp4"
    <img src="a.png">                  controls
</video>                             >
                                         <source srcset="a.webm">
                                         <img src="a.png">
                                     </video>

isMediaOnly -> true                  isMediaOnly -> false

Same content, same indentation; only the opening tag is wrapped. GitHub wraps attributes like this when a reporter pastes an embed from an editor that formats HTML, so it is not a contrived shape.

Carrying opening-tag state across lines would cover it. Worth a regression alongside the two-space / four-space / tab cases.

Neither this nor the predicate issue touches the restoration work, which is the substantial part of the PR and looks right to me.

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

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants