Skip to content

docs: make the pull request template followable - #47

Merged
michen00 merged 6 commits into
mainfrom
docs/pr-template-instructions
Sep 9, 2026
Merged

docs: make the pull request template followable#47
michen00 merged 6 commits into
mainfrom
docs/pr-template-instructions

Conversation

@michen00

@michen00 michen00 commented Sep 3, 2026

Copy link
Copy Markdown
Owner

What changes, and why

The title rule could not be met. The template asks for "imperative, lowercase, 50 characters or fewer", and the squash subject is the title with (#N) appended:

squash_merge_commit_title: COMMIT_OR_PR_TITLE
allow_squash: true   allow_merge: false   allow_rebase: false

So a contributor who used the whole budget lands a subject over the bound. On main, 14 subjects exceed 50 characters and 6 of those are within 50 before the appended number — the failure this describes, already in the history. .gitlint sets line-length=50 and runs at commit-msg, so it holds the bound on every local commit and never sees a merged subject; the template is the only place it can be kept. It now says the number gets appended, and why the bound is manual here.

The answer-key pointer sent people somewhere the rule was not. The template says "corpus/README.md and corpus/cli/README.md say how." Only the CLI tier's does — corpus/cli/README.md:75, "Generate expected/ and stdout.txt by running the tool rather than by writing them out." corpus/README.md's "Adding a case" section said nothing about it.

That is backwards from where the rule is needed. The transform tier has no regeneration commandREGENERATE_CLI_CORPUS belongs to the CLI tier — so it is the half where hand-writing a key is easiest and least likely to be caught, and CONTRIBUTING.md:35 already says so: "There is no such path for the transform tier, so produce those two files by running the tool and reading the diff."

The rule now sits in corpus/README.md as well, which makes the template's pointer true rather than narrowing it to the one tier that already had it.

The same rule lived in a third place. CONTRIBUTING.md said pull request titles become the squash subject and to write them the same way as commit subjects, which is 50 characters or fewer — the bound the template now states after the appended number. Following the contributing guide therefore still produced an over-limit subject, so it now names the space and the number too, and the three contributor-facing places agree. The template keeps the code-span form; CONTRIBUTING.md states the space in prose, because markdownlint MD038 rejects a leading space inside a code span anywhere but an HTML comment. That comment also keeps its colon rather than a double hyphen, which HTML does not allow in comment text.

Corpus

The corpus is the specification, and both implementations answer to it. Tick what applies.

  • This changes no behavior the corpus specifies.
  • This changes what gets joined, and a case in corpus/ pins the new behavior. The case was written first and failed first.
  • The change makes the tool join more than it did. The section above says what it will not eat.

Documentation of how to write a case. No case, key or harness changes.

Checks

  • make check passes, or make test does and this touches no Rust.

make tidy, plus unwrap-markdown-prose-py --fail-on-change over the three changed files — corpus/README.md and CONTRIBUTING.md are both in scope for this repository's own hook, since .unwrapignore names the two corpus tiers rather than the whole tree.


Closes #63 (review-convergence bulletin)

Two instructions in it could not be followed as written.

The title rule asked for 50 characters or fewer, and the squash subject
is the title with ` (#N)` appended -- this repository allows squash and
nothing else, with `squash_merge_commit_title: COMMIT_OR_PR_TITLE`. So a
contributor who used the whole budget landed a longer subject on `main`.
Fourteen subjects there exceed 50 and six of them are inside it before
the number, which is the failure this describes. `gitlint` holds the
bound on every local commit and never sees a merged subject, so the
template is the only place it can be kept.

The answer-key note points at both tier readmes for how to produce one.
Only the CLI tier's says: generate by running the tool, never by hand.
The transform tier's readme said nothing about it, and that is the half
with no regeneration command at all, so it is where hand-writing a key
is likeliest and where the rule was missing. The rule now sits in that
readme too, which makes the pointer true rather than narrowing it.

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

Copy link
Copy Markdown

PR Summary by Qodo

Clarify PR title limits and corpus answer-key generation

📝 Documentation 🕐 Less than 10 minutes

Grey Divider

AI Description

• Explain squash numbering when enforcing the 50-character commit subject limit.
• Document generated transform corpus answer keys where no regeneration command exists.
Diagram

graph TD
  A["Contributor"] --> B["PR Template"] --> C["Squash Subject"]
  B --> D["Corpus README"] --> E["Transform Key"]
  B --> F["CLI README"] --> G["CLI Key"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Automate PR title validation
  • ➕ Prevents invalid squash-subject lengths before merge
  • ➕ Removes reliance on contributors calculating the appended suffix
  • ➖ Requires additional CI or GitHub automation
  • ➖ Must account for pull request number length and repository merge settings
2. Add transform corpus regeneration tooling
  • ➕ Makes answer-key generation repeatable
  • ➕ Aligns transform and CLI corpus workflows
  • ➖ Expands this documentation fix into tooling work
  • ➖ Could encourage blindly accepting generated behavior without reviewing the diff

Recommendation: Keep the documentation changes as the focused immediate fix: they accurately describe current GitHub and corpus workflows without adding maintenance overhead. Automated title validation and transform regeneration tooling are worthwhile follow-ups if manual mistakes continue.

Files changed (2) +8 / -3

Documentation (2) +8 / -3
pull_request_template.mdClarify the effective squash-subject length limit +6/-3

Clarify the effective squash-subject length limit

• Explains that GitHub appends ' (#N)' to the PR title when forming the squash subject. It also clarifies why contributors must manually keep the resulting subject within gitlint’s 50-character limit.

.github/pull_request_template.md

README.mdDocument transform answer-key generation +2/-0

Document transform answer-key generation

• Instructs contributors to generate 'expected.md' by running the tool and reviewing the diff rather than writing or editing it manually. It also explains that the transform tier lacks the CLI corpus regeneration command.

corpus/README.md

@codecov-commenter

codecov-commenter commented Sep 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.40%. Comparing base (da4b651) to head (a77367c).

Additional details and impacted files
@@           Coverage Diff           @@
##             main      #47   +/-   ##
=======================================
  Coverage   87.40%   87.40%           
=======================================
  Files           3        3           
  Lines         691      691           
=======================================
  Hits          604      604           
  Misses         87       87           

☔ 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

qodo-code-review Bot commented Sep 3, 2026

Copy link
Copy Markdown

Code Review by Qodo

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

Grey Divider


Remediation recommended

1. Contributors can still exceed the subject limit 🐞
Description
CONTRIBUTING.md describes the appended squash suffix as (#N), omitting the leading space
included in the pull-request template’s  (#N) suffix. A contributor who follows the guide’s
character budget—for example, using a 47-character title for a single-digit pull request—will end up
with a 51-character merged subject rather than staying within the stated 50-character maximum.
Code

CONTRIBUTING.md[87]

+Conventional Commit messages; imperative, lowercase subjects of 50 characters or fewer. Commit atomically — one concern per commit. Pull request titles become the squash subject with `(#N)` appended, so write them the same way and short enough that the subject is still 50 characters or fewer once the number is on it.
Evidence
The changed contributing-guide line identifies (#N) as the appended text, while the repository’s
pull-request template documents the complete suffix as  (#N). That missing leading space
understates the final squash-subject length by one character and directly changes how many
characters contributors must reserve.

CONTRIBUTING.md[87-87]
.github/pull_request_template.md[3-6]

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 contributing guide represents the squash suffix as `(#N)`, omitting the leading space present in the actual ` (#N)` suffix documented by the pull-request template. This makes the documented character-budget calculation one character too permissive.

## Issue Context
A pull request title must be sized so that its resulting squash subject remains at most 50 characters. The pull-request template already documents the complete suffix accurately; if including leading whitespace inside a code span violates Markdown linting, use wording such as “with a space and `(#N)` appended” to preserve the exact rule.

## Fix Focus Areas
- CONTRIBUTING.md[87-87]

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


2. Generated cases cannot fail first 🐞
Description
Generating expected.md with the current tool makes it equal that implementation's current output,
so a behavior-changing case passes instead of satisfying the template's requirement that it fail
before implementation. Because the same instruction prohibits authoring the intended output
independently and provides no transform-tier regeneration path, contributors cannot follow both
rules.
Code

corpus/README.md[59]

+Produce `expected.md` by running the tool over `input.md` and reading the diff, rather than by writing it out, and never edit one to make a test pass: an answer key written by hand pins what its author believed, which is the one thing a conformance case must not do. This tier has no regeneration command — `REGENERATE_CLI_CORPUS` belongs to the CLI tier and does not reach it — so nothing but the discipline enforces that here, which is why it is worth stating in the tier that lacks the tooling rather than only in the one that has it.
Evidence
The template requires behavior cases to be written and fail first, while the new README text
requires their asserted output to come from the current tool. The corpus test directly compares that
tool's result with expected.md, and the repository confirms there is no transform-tier
regeneration command.

corpus/README.md[55-59]
.github/pull_request_template.md[12-18]
tests/test_corpus.py[21-34]
tests/test_corpus.py[76-80]
CONTRIBUTING.md[31-35]

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 transform-tier instructions require `expected.md` to be generated from the current tool, but behavior-changing corpus cases are also required to fail before implementation. An expected result generated from existing behavior passes by construction.

## Issue Context
Transform tests load `expected.md` as the asserted result, and no transform regeneration command exists. Document a workflow that lets contributors establish the independently intended output before changing either implementation, while retaining appropriate review safeguards for answer keys.

## Fix Focus Areas
- corpus/README.md[55-61]
- .github/pull_request_template.md[12-18]
- CONTRIBUTING.md[31-35]
- tests/test_corpus.py[21-34]

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


3. Conflicting pull request limits 🐞
Description
The template requires the title plus  (#N) to remain within 50 characters, while CONTRIBUTING.md
still tells contributors that pull request titles themselves may use all 50 characters. Following
the contributing guide can therefore produce an over-limit squash subject.
Code

.github/pull_request_template.md[R4-6]

+     ` (#N)` appended, so write it as a Conventional Commit -- imperative,
+     lowercase, and short enough that the subject is still 50 characters or
+     fewer once the number is on it. `gitlint` enforces that bound on every
Evidence
The changed template applies the 50-character limit after appending the PR number, whereas the
contributing guide says subjects may be 50 characters and directs authors to write PR titles the
same way.

.github/pull_request_template.md[3-8]
CONTRIBUTING.md[81-85]

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 pull request template requires the title plus GitHub's appended ` (#N)` suffix to remain within 50 characters, but the contributing guide still allows a 50-character pull request title before that suffix.

## Issue Context
Contributors following `CONTRIBUTING.md` can create squash subjects that violate the repository's 50-character limit. Make every contributor-facing title instruction state the same post-suffix constraint.

## Fix Focus Areas
- .github/pull_request_template.md[3-8]
- CONTRIBUTING.md[81-85]

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


Grey Divider

Context sources
✅ Compliance rules (platform): 11 rules
Review mode: ⏭️ Skipped: The patch only clarifies wording in two documentation files and introduces no behavioral or configuration changes.

Grey Divider

Tip of the day
💡 Did you know, you can commit Qodo's fix in one click with committable suggestions (GitHub & GitLab)

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Previous reviews

Review updated until commit a77367c

Results up to commit 70038c2 ⚖️ Balanced


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


Remediation recommended
1. Generated cases cannot fail first 🐞
Description
Generating expected.md with the current tool makes it equal that implementation's current output,
so a behavior-changing case passes instead of satisfying the template's requirement that it fail
before implementation. Because the same instruction prohibits authoring the intended output
independently and provides no transform-tier regeneration path, contributors cannot follow both
rules.
Code

corpus/README.md[59]

+Produce `expected.md` by running the tool over `input.md` and reading the diff, rather than by writing it out, and never edit one to make a test pass: an answer key written by hand pins what its author believed, which is the one thing a conformance case must not do. This tier has no regeneration command — `REGENERATE_CLI_CORPUS` belongs to the CLI tier and does not reach it — so nothing but the discipline enforces that here, which is why it is worth stating in the tier that lacks the tooling rather than only in the one that has it.
Evidence
The template requires behavior cases to be written and fail first, while the new README text
requires their asserted output to come from the current tool. The corpus test directly compares that
tool's result with expected.md, and the repository confirms there is no transform-tier
regeneration command.

corpus/README.md[55-59]
.github/pull_request_template.md[12-18]
tests/test_corpus.py[21-34]
tests/test_corpus.py[76-80]
CONTRIBUTING.md[31-35]

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 transform-tier instructions require `expected.md` to be generated from the current tool, but behavior-changing corpus cases are also required to fail before implementation. An expected result generated from existing behavior passes by construction.

## Issue Context
Transform tests load `expected.md` as the asserted result, and no transform regeneration command exists. Document a workflow that lets contributors establish the independently intended output before changing either implementation, while retaining appropriate review safeguards for answer keys.

## Fix Focus Areas
- corpus/README.md[55-61]
- .github/pull_request_template.md[12-18]
- CONTRIBUTING.md[31-35]
- tests/test_corpus.py[21-34]

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


2. Conflicting pull request limits 🐞
Description
The template requires the title plus  (#N) to remain within 50 characters, while CONTRIBUTING.md
still tells contributors that pull request titles themselves may use all 50 characters. Following
the contributing guide can therefore produce an over-limit squash subject.
Code

.github/pull_request_template.md[R4-6]

+     ` (#N)` appended, so write it as a Conventional Commit -- imperative,
+     lowercase, and short enough that the subject is still 50 characters or
+     fewer once the number is on it. `gitlint` enforces that bound on every
Evidence
The changed template applies the 50-character limit after appending the PR number, whereas the
contributing guide says subjects may be 50 characters and directs authors to write PR titles the
same way.

.github/pull_request_template.md[3-8]
CONTRIBUTING.md[81-85]

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 pull request template requires the title plus GitHub's appended ` (#N)` suffix to remain within 50 characters, but the contributing guide still allows a 50-character pull request title before that suffix.

## Issue Context
Contributors following `CONTRIBUTING.md` can create squash subjects that violate the repository's 50-character limit. Make every contributor-facing title instruction state the same post-suffix constraint.

## Fix Focus Areas
- .github/pull_request_template.md[3-8]
- CONTRIBUTING.md[81-85]

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


Grey Divider

Qodo Logo

Comment thread .github/pull_request_template.md Outdated
Comment thread corpus/README.md

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 are documentation-only, consistent with the stated rationale, and do not introduce any correctness or maintainability issues.

Pull request overview

Updates contributor-facing documentation to make the PR template’s guidance accurate and actionable, especially around title length constraints under squash-merge and how to produce corpus answer keys without “hand-authoring” expected output.

Changes:

  • Clarifies in the PR template that GitHub appends (#N) to the squash subject, so the 50-character bound must account for that suffix.
  • Adds explicit guidance to corpus/README.md to generate expected.md by running the tool and reviewing diffs (and not by writing/editing expected output by hand).
File summaries
File Description
corpus/README.md Documents the “generate expected output by running the tool” rule in the transform-tier corpus docs.
.github/pull_request_template.md Adjusts title-length guidance to reflect squash-merge title suffixing and where the 50-char bound must be enforced.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Lite

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

@michen00

michen00 commented Sep 9, 2026

Copy link
Copy Markdown
Owner Author

[Review-Convergence] Round 1: active

  • Head: 9806fb8
  • Base ref: main
  • Base: da4b651
  • CI: green
  • Bot threads: 2 unresolved
  • Human threads: 0 unresolved
  • Clean signals: Copilot
  • Pending reviewers: Qodo
  • Catch-up: update-branch-dispatched
  • Next action: wait for update-branch and rerun on the new head
  • Next wakeup: ~2min (update-branch head visibility)
  • Bulletin: Review convergence: PR #47 #63

The opening preflight found the head two commits behind main, so this round stopped before thread triage. The catch-up brings in changes to pyproject.toml and tests/corpus.rs, which the PR does not own, so Copilot's clean signal at the current head is expected to propagate to the merge head rather than invalidate.

The template now says the squash subject is the title with the number
appended, and asks for 50 characters or fewer once it is on. This file
still asked for 50 on the title alone and said to write pull request
titles the same way as commit subjects, so a contributor following it
lands an over-limit subject -- the failure the template change exists
to remove.

The code span drops the leading space the template uses, because
markdownlint MD038 rejects it outside an HTML comment.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@michen00
michen00 requested a lite review from Copilot September 9, 2026 08:48
@michen00

michen00 commented Sep 9, 2026

Copy link
Copy Markdown
Owner Author

/agentic_review

Comment thread CONTRIBUTING.md Outdated
@qodo-code-review

Copy link
Copy Markdown

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

@michen00

michen00 commented Sep 9, 2026

Copy link
Copy Markdown
Owner Author

[Review-Convergence] Round 3: active

  • Head: 7649558
  • Base ref: main
  • Base: da4b651
  • CI: green
  • Bot threads: 0 unresolved
  • Human threads: 0 unresolved
  • Clean signals: none valid on this head
  • Pending reviewers: Copilot, Qodo
  • Catch-up: none
  • Next action: wait for Copilot and Qodo to return on 7649558
  • Next wakeup: ~2min (reviewer-pending floor)
  • Bulletin: Review convergence: PR #47 #63

Both Qodo threads are dispositioned and resolved. The title-limit finding was a divergence this pull request opened — the template gained the post-number bound and CONTRIBUTING.md kept the old one — and is fixed in 7649558. The answer-key finding is a real contradiction that predates this change, carried by CONTRIBUTING.md:31 and CONTRIBUTING.md:35 on main, so it is a wontfix here and is settled in #65 instead.

Copilot's earlier clean signal invalidated rather than propagating: the fix made CONTRIBUTING.md PR-owned, so it intersects the head move. Both reviewers are re-requested on the new head.

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

There are small but concrete documentation issues in the changed lines (an inconsistent (#N) vs (#N) append string, and invalid -- content inside an HTML comment) that should be corrected to keep the template reliably followable.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

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

Comment thread .github/pull_request_template.md Outdated
Comment thread CONTRIBUTING.md Outdated
michen00 and others added 2 commits September 9, 2026 01:54
The suffix is a space and the number, so a budget computed against the
number alone is one character too generous: a 47-character title on a
single-digit pull request lands a 51-character subject. Saying it in
words keeps the space visible without putting it inside a code span,
which markdownlint MD038 rejects.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A double hyphen is not allowed in HTML comment text, and this was the
only comment body in the tree carrying one. The colon is what stood
here before and reads the same way.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@michen00
michen00 requested a lite review from Copilot September 9, 2026 08:56
@michen00

michen00 commented Sep 9, 2026

Copy link
Copy Markdown
Owner Author

/agentic_review

@michen00

michen00 commented Sep 9, 2026

Copy link
Copy Markdown
Owner Author

[Review-Convergence] Round 4: active

  • Head: a77367c
  • Base ref: main
  • Base: da4b651
  • CI: pending
  • Bot threads: 0 unresolved
  • Human threads: 0 unresolved
  • Clean signals: none valid on this head
  • Pending reviewers: Copilot, Qodo
  • Catch-up: none
  • Next action: wait for CI on a77367c and for both reviewers to return
  • Next wakeup: ~3min (reviewer-pending floor, taken against pending CI)
  • Bulletin: Review convergence: PR #47 #63

The second pass found two defects, both introduced here, and both are fixed. Qodo and Copilot independently caught the same off-by-one in the round-3 wording: the squash suffix is a space and the number, so naming the number alone left the budget one character too generous — a 47-character title on a single-digit pull request lands a 51-character subject. Fixed in d8ccfb9. Copilot separately flagged the double hyphen in the template's HTML comment, which HTML disallows in comment text and which was the only such comment body in the tree; a77367c restores the colon main had there.

All three threads are resolved and both reviewers are re-requested.

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 are documentation-only, consistent across the referenced docs, and verified against existing regeneration tooling references in the repository.

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

@qodo-code-review

Copy link
Copy Markdown

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

@michen00

michen00 commented Sep 9, 2026

Copy link
Copy Markdown
Owner Author

[Review-Convergence] Round 5: converged-merge-blocked

  • Head: a77367c
  • Base ref: main
  • Base: da4b651
  • CI: green
  • Bot threads: 0 unresolved
  • Human threads: 0 unresolved
  • Clean signals: Copilot, Qodo
  • Pending reviewers: none
  • Catch-up: none
  • Next action: human merge gate, since the ruleset asks for one approving review and GitHub does not let an author approve their own pull request
  • Bulletin: Review convergence: PR #47 #63

Bot-review convergence is reached on this head. Copilot returned approval-recommended with no threads, and Qodo posted a real-review marker naming this commit with no unresolved threads and no active summary findings, so quorum is met from both families. Base is an ancestor of the head and all five review threads are resolved.

Five findings were raised across the cycle. Four were fixed: the title-limit divergence this pull request opened, the off-by-one that the first fix introduced by naming the number without its leading space, and the double hyphen in the template's HTML comment. One is an evidenced wontfix — the transform-tier answer-key contradiction predates this change and is settled in #65.

reviewDecision is REVIEW_REQUIRED, which is the remaining barrier and not something this runner acts on.

@michen00
michen00 merged commit 5a6cae8 into main Sep 9, 2026
26 checks passed
@michen00
michen00 deleted the docs/pr-template-instructions branch September 9, 2026 09:11
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 #47

3 participants