Skip to content

fix: stop doubling the changelog header newlines - #79

Merged
michen00 merged 4 commits into
mainfrom
fix/changelog-header-newlines
Sep 15, 2026
Merged

michen00 merged 4 commits into
mainfrom
fix/changelog-header-newlines

Conversation

@michen00

@michen00 michen00 commented Sep 15, 2026

Copy link
Copy Markdown
Owner

Fixes the Changelog autoupdate workflow, which has failed on every scheduled run since at least 2026-06-29 — most recently run 34793753205.

Root cause

Every line of the [changelog] header template in cliff.toml ended with a literal \n escape on top of the newline a TOML multi-line basic string already contributes, so each source line emitted two newlines. The rendered header came out as:

<!-- markdownlint-configure-file ... -->   line 1
                                           lines 2, 3, 4 — three blank lines
# Changelog                                line 5

markdownlint's MD012 caps consecutive blank lines at 1, which is exactly the CHANGELOG.md:3 / CHANGELOG.md:4 errors in the run log.

It stayed invisible because the pre-commit markdownlint --fix hook collapses the blanks locally, so the checked-in CHANGELOG.md has always looked correct. The Format CHANGELOG.md step in the workflow only lints (markdownlint-cli2-action defaults to fix: false), so regenerating in CI reintroduced them and the job died before ever reaching the create-PR step. No autoupdate PR has ever been opened.

Fix

  • cliff.toml — blank lines written as blank lines, \n escapes dropped, with a comment recording why so it does not regress.
  • tests/test-cliff-header.sh (new, wired into test-unit.sh) — decodes the header template the way TOML does and asserts the MD012 invariant. It deliberately needs no git-cliff, because CI does not install it and a rendering test would have skipped there silently. It fails on the old template at rendered lines 3 and 4, matching CI's report.

Hardening from review

Bot review of the new test produced three follow-up commits:

  • f624b03 — guard mktemp -d. The script runs without errexit, so a failed temp-dir creation left work empty and the render target resolving to /header.md; as root that writes a stray file into the filesystem root which the cleanup trap cannot remove.
  • ee335df — count a whitespace-only line as blank in both awk checks. markdownlint does; the test did not. A header carrying a line of spaces beside an empty one therefore passed this suite while the workflow's markdownlint run would have rejected it — the exact divergence the test exists to prevent.
  • 998e5f8 — scope the cliff.toml comment to the header template, so it cannot be read as banning the \n escapes the body template deliberately relies on.

One finding was declined with evidence: the strict header = """ anchor stays exact, because tomllib confirms trailing whitespace after the delimiter changes the rendered header rather than being a harmless reformat.

Verification

Run against git-cliff 2.14.1, the version taiki-e/install-action installs in CI (2.14 changed --prepend behavior, so testing on an older local build would not have been conclusive):

old cliff.toml this PR
update-unreleased.sh → markdownlint 2 errors (MD012 at 3, 4) — reproduces CI 0 errors
second run byte-identical idempotent ✓
  • The generated header now matches the committed CHANGELOG.md byte for byte.
  • pre-commit run markdownlint prettier on the generated file: passed, no modifications — so the autoupdate PR this unblocks will also pass its own CI.
  • markdownlint-cli 0.48.0 with the repo's own .markdownlint.yml confirms the rule the test mirrors: a whitespace-only line counts toward MD012.
  • Full suite: 8/8 suites pass. shellcheck, shfmt, and pre-commit clean on all changed files.

Noted, not changed

  • scripts/release/stamp-changelog.sh emits MD032 (blanks-around-lists) in the oldest section, from the body template rather than the header. Pre-existing and harmless — release-pr.yml runs pre-commit run --files CHANGELOG.md, which auto-fixes it. Worth a separate cleanup if the raw output should be canonical.
  • The step named Format CHANGELOG.md does not format. With the root cause fixed it is a correct guard, and adding fix: true would change workflow behavior, so I left it alone.

🤖 Generated with Claude Code


Closes #80 (review-convergence bulletin)

Every line of the [changelog] header template in cliff.toml ended with
a literal \n escape on top of the newline a TOML multi-line string
already contributes, so each line emitted two newlines. The rendered
header carried three blank lines between the markdownlint configure
comment and "# Changelog", which markdownlint rejects as MD012.

Locally the pre-commit markdownlint --fix hook collapsed them before
anything reached a commit, so the checked-in changelog looked fine.
The changelog-autoupdate workflow only lints, so every scheduled run
since at least 2026-06-29 failed on MD012 without ever opening a PR.

Write the blank lines as blank lines. Verified against git-cliff
2.14.1, the version CI installs: regeneration now lints clean and is
idempotent, and the generated header matches the committed changelog
byte for byte.

Add tests/test-cliff-header.sh, which decodes the template the way
TOML does and asserts the MD012 invariant. It needs no git-cliff,
which CI does not install, so a rendering test would have skipped
there silently.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@codecov-commenter

codecov-commenter commented Sep 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 72.72727% with 15 lines in your changes missing coverage. Please review.
✅ Project coverage is 47.93%. Comparing base (d28fc95) to head (998e5f8).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
tests/test-cliff-header.sh 72.22% 15 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #79      +/-   ##
==========================================
+ Coverage   47.23%   47.93%   +0.69%     
==========================================
  Files          30       31       +1     
  Lines        1808     1863      +55     
==========================================
+ Hits          854      893      +39     
- Misses        954      970      +16     
Flag Coverage Δ
integration 1.05% <0.00%> (-0.04%) ⬇️
unit 47.26% <72.72%> (+0.71%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Fix duplicate newlines in generated changelog headers

🐞 Bug fix 🧪 Tests ⚙️ Configuration changes 🕐 10-20 Minutes

Grey Divider

AI Description

• Remove redundant newline escapes from the git-cliff changelog header template.
• Prevent scheduled changelog generation from failing markdownlint's MD012 rule.
• Add portable regression checks for header spacing and trailing blank lines.
Diagram

graph TD
  CLIFF["cliff.toml"] --> GIT["git-cliff"] --> CHANGE["CHANGELOG.md"] --> LINT["markdownlint"] --> PR["Autoupdate PR"]
  RUNNER["Unit runner"] --> TEST["Header test"] --> CLIFF
Loading
High-Level Assessment

The current approach is proportionate: explicit TOML blank lines fix the source of the rendering defect, while a dependency-free test protects CI environments without git-cliff. Running git-cliff directly would provide full integration coverage but would add an unavailable test dependency; using a general TOML parser would be unnecessary for this static, escape-restricted template.

Files changed (3) +112 / -5

Bug fix (1) +14 / -5
cliff.tomlStop changelog header newline duplication +14/-5

Stop changelog header newline duplication

• Replaces trailing literal newline escapes with actual blank lines in the TOML multiline header. Adds guidance explaining how redundant escapes produce markdownlint MD012 violations.

cliff.toml

Tests (2) +98 / -0
test-cliff-header.shAdd changelog header spacing regression tests +97/-0

Add changelog header spacing regression tests

• Adds a portable AWK-based decoder for the static header template. Verifies successful rendering, rejects consecutive blank lines, and requires exactly one trailing blank line without depending on git-cliff.

tests/test-cliff-header.sh

test-unit.shRegister changelog header tests +1/-0

Register changelog header tests

• Adds the new cliff.toml header regression script to the shared unit test runner.

tests/test-unit.sh

@qodo-code-review

qodo-code-review Bot commented Sep 15, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Failed temp setup targets the root 📘
Description
work="$(mktemp -d)" does not check the command's status even though the script enables no
errexit behavior. When temporary-directory creation fails, rendered becomes /header.md and the
remaining checks attempt to operate on that root-level path.
Code

tests/test-cliff-header.sh[59]

+work="$(mktemp -d)"
Evidence
Compliance rule 406873 requires shell commands whose success matters to be covered by errexit or
explicit status handling. The new script enables only nounset and pipefail, then uses an
unchecked mktemp result to construct the rendered-file path.

Rule 406873: Do not silently ignore exit codes in shell scripts
tests/test-cliff-header.sh[4-5]
tests/test-cliff-header.sh[59-61]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test continues after `mktemp -d` fails, causing its output path to resolve to `/header.md`.

## Fix Focus Areas
- tests/test-cliff-header.sh[59-61]

## Recommended Fix
Guard the `mktemp -d` assignment with an explicit failure branch that prints an error and exits non-zero before constructing paths or installing the cleanup trap.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. New header test requires Bash 📘
Description
test-cliff-header.sh declares #!/usr/bin/env bash and uses Bash-only features including
BASH_SOURCE, pipefail, and arithmetic commands. Direct execution therefore depends on Bash and
cannot satisfy environments or tooling that invoke repository shell scripts as POSIX sh.
Code

tests/test-cliff-header.sh[1]

+#!/usr/bin/env bash
Evidence
Rules 406876 and 406892 require the exact /bin/sh shebang and prohibit Bash-specific constructs.
The new file instead selects Bash and contains multiple constructs unavailable in strictly POSIX
shells.

Rule 406876: Enforce POSIX-compliant shell scripts (no bashisms, use #!/bin/sh)
Rule 406892: Standardize shell script shebang to /bin/sh
tests/test-cliff-header.sh[1-5]
tests/test-cliff-header.sh[16-27]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new test targets Bash despite the checklist requiring shell scripts to use `/bin/sh` and POSIX syntax.

## Fix Focus Areas
- tests/test-cliff-header.sh[1-27]

## Recommended Fix
Change the shebang to `#!/bin/sh`, replace `BASH_SOURCE` with a POSIX `$0`-based path, replace arithmetic commands with POSIX arithmetic assignments, use `printf` instead of `echo -e`, and remove the unsupported `pipefail` option.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Header test omits an explicit exit 📘
Description
test-cliff-header.sh ends with [ "$FAILED" -eq 0 ] rather than an explicit exit command. Both
successful and failed runs therefore fall off the end with the test command's status instead of
documenting each main-path exit code directly.
Code

tests/test-cliff-header.sh[97]

+[ "$FAILED" -eq 0 ]
Evidence
Rule 406878 requires an explicit exit command on every main execution path and identifies falling
off the end as a violation. The new script's last line is a test expression, with no exit 0 or
non-zero exit branch.

Rule 406878: Shell scripts must use explicit exit codes
tests/test-cliff-header.sh[95-97]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new executable test relies on the status of its final test expression instead of explicitly exiting on its success and failure paths.

## Fix Focus Areas
- tests/test-cliff-header.sh[95-97]

## Recommended Fix
Replace the final expression with an `if` statement that calls `exit 0` when no assertions failed and `exit 1` otherwise.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Header checks pass after tool errors 📘
Description
The assignments invoking awk at lines 73 and 86 are not checked, while set -uo pipefail leaves
errexit disabled. If either invocation fails, its result is empty and the following conditional
reaches a pass call instead of recording the unavailable check.
Code

tests/test-cliff-header.sh[73]

+	offenders="$(awk 'BEGIN { run = 0 } { if ($0 == "") { run++; if (run > 1) print NR } else run = 0 }' "$rendered")"
Evidence
Rules 406873 and 406886 require non-trivial shell command failures to be propagated or handled
explicitly. The script enables only nounset and pipefail, then uses unchecked awk command
substitutions whose empty output selects successful assertion branches.

Rule 406873: Do not silently ignore exit codes in shell scripts
Rule 406886: Shell scripts must not ignore exit codes and must handle errors explicitly
tests/test-cliff-header.sh[4-4]
tests/test-cliff-header.sh[73-86]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The header assertions can report success when their `awk` commands fail because command-substitution exit statuses are ignored.

## Fix Focus Areas
- tests/test-cliff-header.sh[4-4]
- tests/test-cliff-header.sh[59-59]
- tests/test-cliff-header.sh[73-86]

## Recommended Fix
Explicitly check `mktemp` and both `awk` assignments, recording a failed assertion or exiting non-zero when they fail. If enabling `errexit`, also replace arithmetic post-increments with forms that return success when incrementing from zero.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Two test counters use uppercase names 📘
Description
The mutable PASSED and FAILED counters use all-uppercase names and are incremented by pass and
fail. They are not constants or externally supplied environment variables, so later readers cannot
distinguish them from the file's actual constants.
Code

tests/test-cliff-header.sh[R13-14]

+PASSED=0
+FAILED=0
Evidence
Rule 406880 requires script-defined mutable variables to use lowercase letters and underscores.
Lines 13–14 define uppercase counters, while their increments prove that neither value is constant.

Rule 406880: Use lowercase_with_underscores for shell variable names
tests/test-cliff-header.sh[13-27]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The mutable pass and failure counters use uppercase names reserved by the checklist exception for constants or public environment variables.

## Fix Focus Areas
- tests/test-cliff-header.sh[13-27]
- tests/test-cliff-header.sh[95-97]

## Recommended Fix
Rename `PASSED` and `FAILED` to `passed` and `failed`, then update every increment, summary interpolation, and final status check.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
✅ Compliance rules (platform): 26 rules
Review mode: 🚀 Fast: This is a small, localized changelog-template and shell-test adjustment with contained impact and no security, API, schema, or other high-risk behavior.

Grey Divider

Tip of the day
💡 Did you know, you can reply 'qodo' on any finding to push back, ask questions, or dig deeper

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Previous reviews

Review updated until commit 998e5f8

Results up to commit f5656e7 ⚖️ Balanced


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Remediation recommended
1. New header test requires Bash 📘
Description
test-cliff-header.sh declares #!/usr/bin/env bash and uses Bash-only features including
BASH_SOURCE, pipefail, and arithmetic commands. Direct execution therefore depends on Bash and
cannot satisfy environments or tooling that invoke repository shell scripts as POSIX sh.
Code

tests/test-cliff-header.sh[1]

+#!/usr/bin/env bash
Evidence
Rules 406876 and 406892 require the exact /bin/sh shebang and prohibit Bash-specific constructs.
The new file instead selects Bash and contains multiple constructs unavailable in strictly POSIX
shells.

Rule 406876: Enforce POSIX-compliant shell scripts (no bashisms, use #!/bin/sh)
Rule 406892: Standardize shell script shebang to /bin/sh
tests/test-cliff-header.sh[1-5]
tests/test-cliff-header.sh[16-27]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new test targets Bash despite the checklist requiring shell scripts to use `/bin/sh` and POSIX syntax.

## Fix Focus Areas
- tests/test-cliff-header.sh[1-27]

## Recommended Fix
Change the shebang to `#!/bin/sh`, replace `BASH_SOURCE` with a POSIX `$0`-based path, replace arithmetic commands with POSIX arithmetic assignments, use `printf` instead of `echo -e`, and remove the unsupported `pipefail` option.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Header test omits an explicit exit 📘
Description
test-cliff-header.sh ends with [ "$FAILED" -eq 0 ] rather than an explicit exit command. Both
successful and failed runs therefore fall off the end with the test command's status instead of
documenting each main-path exit code directly.
Code

tests/test-cliff-header.sh[97]

+[ "$FAILED" -eq 0 ]
Evidence
Rule 406878 requires an explicit exit command on every main execution path and identifies falling
off the end as a violation. The new script's last line is a test expression, with no exit 0 or
non-zero exit branch.

Rule 406878: Shell scripts must use explicit exit codes
tests/test-cliff-header.sh[95-97]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new executable test relies on the status of its final test expression instead of explicitly exiting on its success and failure paths.

## Fix Focus Areas
- tests/test-cliff-header.sh[95-97]

## Recommended Fix
Replace the final expression with an `if` statement that calls `exit 0` when no assertions failed and `exit 1` otherwise.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Header checks pass after tool errors 📘
Description
The assignments invoking awk at lines 73 and 86 are not checked, while set -uo pipefail leaves
errexit disabled. If either invocation fails, its result is empty and the following conditional
reaches a pass call instead of recording the unavailable check.
Code

tests/test-cliff-header.sh[73]

+	offenders="$(awk 'BEGIN { run = 0 } { if ($0 == "") { run++; if (run > 1) print NR } else run = 0 }' "$rendered")"
Evidence
Rules 406873 and 406886 require non-trivial shell command failures to be propagated or handled
explicitly. The script enables only nounset and pipefail, then uses unchecked awk command
substitutions whose empty output selects successful assertion branches.

Rule 406873: Do not silently ignore exit codes in shell scripts
Rule 406886: Shell scripts must not ignore exit codes and must handle errors explicitly
tests/test-cliff-header.sh[4-4]
tests/test-cliff-header.sh[73-86]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The header assertions can report success when their `awk` commands fail because command-substitution exit statuses are ignored.

## Fix Focus Areas
- tests/test-cliff-header.sh[4-4]
- tests/test-cliff-header.sh[59-59]
- tests/test-cliff-header.sh[73-86]

## Recommended Fix
Explicitly check `mktemp` and both `awk` assignments, recording a failed assertion or exiting non-zero when they fail. If enabling `errexit`, also replace arithmetic post-increments with forms that return success when incrementing from zero.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Two test counters use uppercase names 📘
Description
The mutable PASSED and FAILED counters use all-uppercase names and are incremented by pass and
fail. They are not constants or externally supplied environment variables, so later readers cannot
distinguish them from the file's actual constants.
Code

tests/test-cliff-header.sh[R13-14]

+PASSED=0
+FAILED=0
Evidence
Rule 406880 requires script-defined mutable variables to use lowercase letters and underscores.
Lines 13–14 define uppercase counters, while their increments prove that neither value is constant.

Rule 406880: Use lowercase_with_underscores for shell variable names
tests/test-cliff-header.sh[13-27]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The mutable pass and failure counters use uppercase names reserved by the checklist exception for constants or public environment variables.

## Fix Focus Areas
- tests/test-cliff-header.sh[13-27]
- tests/test-cliff-header.sh[95-97]

## Recommended Fix
Rename `PASSED` and `FAILED` to `passed` and `failed`, then update every increment, summary interpolation, and final status check.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread tests/test-cliff-header.sh Outdated
Comment thread tests/test-cliff-header.sh
Comment thread tests/test-cliff-header.sh
Comment thread tests/test-cliff-header.sh
@michen00

Copy link
Copy Markdown
Owner Author

/agentic_review

Copilot AI 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.

🟡 Changes recommended

The new test’s blank-line detection and header-block parsing are slightly brittle and can miss whitespace-only blank lines or fail on harmless TOML reformatting, undermining the regression guard.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Fixes the git-cliff changelog header template so it no longer emits consecutive blank lines (which break markdownlint MD012 in the Changelog autoupdate workflow), and adds a unit test to prevent regressions.

Changes:

  • Update cliff.toml [changelog].header to use literal blank lines instead of trailing \n escapes.
  • Add tests/test-cliff-header.sh to decode the TOML header template and assert MD012/trailing-blank-line invariants without requiring git-cliff.
  • Wire the new test into tests/test-unit.sh.
File summaries
File Description
cliff.toml Removes trailing \n escapes from the header template and documents why to avoid MD012 failures in CI.
tests/test-cliff-header.sh New test that renders the header template and checks for consecutive blank lines and correct trailing spacing.
tests/test-unit.sh Includes the new cliff header test in the unit test suite.
Review details

Suppressed comments (1)

tests/test-cliff-header.sh:86

  • Trailing blank-line counting has the same issue as the MD012 check: it ignores whitespace-only lines. Using a whitespace-aware blank test keeps this aligned with how most markdown tooling treats blank lines.
	trailing_blanks="$(awk '{ if ($0 == "") blanks++; else blanks = 0 } END { print blanks + 0 }' "$rendered")"
  • Files reviewed: 3/3 changed files
  • Comments generated: 3
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread tests/test-cliff-header.sh
Comment thread tests/test-cliff-header.sh Outdated
Comment thread cliff.toml Outdated
Comment thread tests/test-cliff-header.sh Outdated
@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit f5656e7

michen00 and others added 3 commits September 14, 2026 23:12
The script runs under `set -uo pipefail` with no `errexit`, so a failed
`mktemp -d` left `work` set to the empty string and execution continued.
`rendered` then resolved to `/header.md`: as a normal user the redirect
fails and the suite reports a confusing render failure, and as root it
writes a stray file into the filesystem root that the `rm -rf "$work"`
trap cannot clean up (it expands to a no-op on an empty operand).

Check the assignment and exit before any path is built from it.

Reported by qodo-code-review on PR #79.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
markdownlint treats a whitespace-only line as blank, but both awk
checks tested for an empty line only. A header carrying a line of
spaces next to an empty one therefore passed this suite while
markdownlint failed it -- the exact divergence the test exists to
prevent, since it stands in for the autoupdate workflow's
markdownlint run.

Verified against markdownlint-cli 0.48.0 with the repo's own config:
a header rendering "Some text." / three spaces / empty / "More text."
is reported as MD012 Actual: 2, and is now caught here too.

Reported by copilot-pull-request-reviewer on PR #79 (lines 73, 86).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The comment sat under a line naming the header, body and footer keys
and then said "blank lines here", which reads as a file-wide ban on
trailing \n escapes. The body template 30 lines below legitimately
uses them: its source lines are joined with backslash continuations,
so it places newlines explicitly.

Say which template the rule governs, and why the body differs, so the
note that exists to stop the MD012 bug returning cannot be read as
forbidding what the body already does.

Reported by copilot-pull-request-reviewer on PR #79.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@michen00

Copy link
Copy Markdown
Owner Author

[Review-Convergence] Qodo determination — head f5656e7

1 listed finding: 1 fixed. 0 actionable remaining.

Per-item determinations

The four items struck through in the summary are the previous round's dispositions, already reflected by Qodo itself; they are not re-triaged here.

@michen00
michen00 requested a lite review from Copilot September 15, 2026 06:18
@michen00

Copy link
Copy Markdown
Owner Author

/agentic_review

@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 998e5f8

@michen00

Copy link
Copy Markdown
Owner Author

[Review-Convergence] Round 1: active

  • Head: 998e5f8
  • Base ref: main
  • Base: 0548a62
  • CI: success
  • Bot threads: 0 unresolved
  • Human threads: 0 unresolved
  • Clean signals: none (head moved this round; no signal could propagate)
  • Pending reviewers: Copilot, Qodo
  • Catch-up: none
  • Next action: wait for Copilot and Qodo to review 998e5f8
  • Next wakeup: ~4min (reviewer-pending floor, first wakeup since re-request)
  • Bulletin: Review convergence: PR #79 #80
Round 1 dispositions (4 bot threads)
  • fixed f624b03 — qodo, tests/test-cliff-header.sh unchecked mktemp -d: with errexit off the empty $work made the render target resolve to /header.md. Reproduced first, guarded, verified both directions.
  • fixed ee335df — copilot, blank-line detection: markdownlint counts a whitespace-only line as blank and both awk checks did not. Confirmed against markdownlint-cli 0.48.0 with this repo's config, plus a fixture the old test passed and the new one fails.
  • fixed 998e5f8 — copilot, cliff.toml comment scope: the note read as a file-wide ban on \n escapes while the body template legitimately uses them.
  • wontfix — copilot, exact header = """ anchor: verified with tomllib that trailing whitespace after the delimiter changes the rendered header, so the strict anchor is load-bearing; the benign leading-indent case fails closed with a diagnostic and no formatter here reflows TOML.

Codex has never engaged with this PR, so it is not eligible for re-request. Quorum of 2 is reachable from Copilot (github) + Qodo (qodo).

Copilot AI 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.

🟢 Approval recommended

The changes directly address the documented CI root cause and add a focused regression test without introducing new behavioral risks.

Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@michen00

Copy link
Copy Markdown
Owner Author

[Review-Convergence] Round 2: converged

  • Head: 998e5f8
  • Base ref: main
  • Base: 0548a62
  • CI: success (11 passing, 1 skipped, combined status success)
  • Bot threads: 0 unresolved
  • Human threads: 0 unresolved
  • Clean signals: Copilot (github), Qodo (qodo) — quorum 2/2
  • Pending reviewers: none
  • Catch-up: none
  • Next action: none — converged
  • Bulletin: Review convergence: PR #79 #80
Clean-signal evidence
  • Copilotreview at 998e5f8, 06:20:07Z, "🟢 Approval recommended", 0 new comments, no provider-error body, 0 unresolved Copilot threads.
  • Qodo — persistent summary advanced to 06:18:33Z (past the 06:18:03Z trigger) with a real-review marker naming 998e5f8; every summary item now struck through, including Failed temp setup targets the root, which Qodo marked ✓ after f624b03; 0 unresolved Qodo threads.

Codex has never engaged with this PR at any point, so it was never eligible for re-request. Quorum was met from the engaged set without it.

Converged in 2 rounds: 4 bot threads triaged (3 fixed across f624b03, ee335df, 998e5f8; 1 evidenced wontfix), 3 commits pushed, both reviewers clean on the resulting head.

This runner does not merge — landing the PR remains your call, squash-only per repo policy.

@michen00
michen00 merged commit f67e530 into main Sep 15, 2026
13 checks passed
@michen00
michen00 deleted the fix/changelog-header-newlines branch September 15, 2026 06:31
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.

Review convergence: PR #79

3 participants