Skip to content

Flag a Lone Semicolon After an Explanatory Colon in the Prose Gate - #2737

Merged
ptr727 merged 9 commits into
developfrom
feature/auto-1396
Oct 10, 2026
Merged

ptr727 merged 9 commits into
developfrom
feature/auto-1396

Conversation

@ptr727

@ptr727 ptr727 commented Oct 10, 2026 •

Copy link
Copy Markdown
Owner

Summary

The prose gate's semicolon check exempted any sentence holding a colon before its first semicolon and a comma, so a colon that explains rather than labels let a clause-joining semicolon through (#1396). Per the decision on #2736 (option 1), a lone semicolon now counts as a list separator only between two labeled items, as in Inputs: a, b; outputs: c. Two or more semicolons plus a comma stay exempt.

  • prose_lint.py: LABELED_ITEM (built from LABEL_WORD) must match both the first item, past any list marker, and the item after a single semicolon. A label is up to three words, emphasis or a code span allowed, with ., /, - only between word characters, so D1.2: labels while e.g., /tmp, and a quotation do not.
  • Tests: the old colon-arm exemptions now assert a report, the abbreviation test is rebuilt as a series, and new tests cover labeled items, both halves of the condition, and the three non-label shapes. Each new negative fails with the previous pattern restored.
  • Tree recasts for the six lines the narrower exemption reports: WORKFLOW.md lines 54, 181, 247, 294 (plus generated skill-reference copies) and catalog/snippets/vscode/README.md lines 17-18.
  • Rule text: the maintainer chose to narrow the stated exception in this PR, so comment-and-doc-style and scripts/README.md now say a single semicolon separates a list only between two labeled items.

Closes on promotion: #1396

Known Residual

A short labeled first clause followed by a short labeled tail still passes (It fails: it reads x, y; it stops: the run halts.), since shape cannot tell a three-word clause from a label. Requiring a label on both sides, per Copilot's finding, narrowed this from any colon-bearing first clause.

Local-Review Findings

The four findings the first push listed here were fixed in 91a438e and a4d38d6, the same ones Copilot raised. The rule text's opening-label clause was narrowed to a bold label in b58540b. The last pass found that the gate strips only the ** bold spellings, so __Label__: and ***Label***: openers still count as a first label. That is the gate falling short of the rule rather than the rule being wrong, so it is deferred to #2738 with the pre-existing +/N) marker gap.

Carries the comments label for the added code comments.

🤖 Generated with Claude Code

ptr727 and others added 4 commits October 10, 2026 08:45
The semicolon check exempted any sentence holding a colon before its
first semicolon and a comma, so a colon that explains rather than
labels let a clause-joining semicolon through. A lone semicolon now
counts as a list separator only when the item after it is labeled too,
as in "Inputs: a, b; outputs: c". Two or more semicolons plus a comma
stay exempt.

The tests that pinned the old colon-arm exemption now expect a report,
the abbreviation test is rebuilt as a series, and the five tree lines
the narrower exemption reports are recast.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The labeled-item match now takes a colon inside the emphasis and a
label carrying a dot, a slash, or a blanked quotation, as the tree's
guarantee ids do. The rule text states that a single semicolon joins a
list only between two labeled items, so the rule and the gate agree,
and tests now cover both halves of the condition.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A dot, slash, or hyphen counts inside a label word only between word
characters, so a dotted id still labels while an abbreviation, a path,
or a quotation does not. The rule text and both rule summaries now
state the narrowed exception the gate enforces.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings October 10, 2026 16:03
@ptr727 ptr727 added the comments Permits the comment lines the pull request adds or edits, which the prose gate otherwise refuses label Oct 10, 2026
@coderabbitai

coderabbitai Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: Repository: ptr727/ProjectTemplate/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a600adb0-3064-4abe-aad8-26570ba974af

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

@codecov

codecov Bot commented Oct 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (develop@f905191). Learn more about missing BASE report.

Additional details and impacted files
@@            Coverage Diff             @@
##             develop    #2737   +/-   ##
==========================================
  Coverage           ?   59.83%           
==========================================
  Files              ?       16           
  Lines              ?     8368           
  Branches           ?        0           
==========================================
  Hits               ?     5007           
  Misses             ?     3361           
  Partials           ?        0           
Flag Coverage Δ
python-3.13 59.83% <ø> (?)

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.

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 rule descriptions still misstate when the gate exempts a lone semicolon, and the no-comma case needs a regression test.

4 open findings
What changed in this PR

This PR narrows the prose gate’s lone-semicolon exemption so an explanatory colon no longer excuses a clause-joining semicolon.

Changes:

  • Require a labeled item after a lone semicolon, while retaining the comma requirement.
  • Add regression cases and recast prose affected by the narrower rule.
  • Update the authored rule guidance and its generated copies.
File Description
WORKFLOW.md Recasts three prose examples.
tests/​test_prose_lint.py Adds and updates semicolon cases.
scripts/​README.md Updates the rule explanation.
catalog/​snippets/​vscode/​README.md Recasts two list descriptions.
.github/​skills/​workflow-ci-contract/​references/​d-guarantees.md Mirrors a workflow prose recast.
.github/​skills/​workflow-ci-contract/​references/​architecture.md Mirrors a workflow prose recast.
.github/​skills/​comment-and-doc-style/​SKILL.md Distributes the updated rule guidance.
.github/​actions/​prose-gate/​prose_lint.py Narrows the lone-semicolon exemption.
.claude-plugin/​fleet-skills/​skills/​workflow-ci-contract/​references/​d-guarantees.md Mirrors a workflow prose recast.
.claude-plugin/​fleet-skills/​skills/​workflow-ci-contract/​references/​architecture.md Mirrors a workflow prose recast.
.claude-plugin/​fleet-skills/​skills/​comment-and-doc-style/​SKILL.md Distributes the updated rule guidance.
.claude-plugin/​fleet-skills/​.source-digests/​workflow-ci-contract Updates the generated source digest.
.claude-plugin/​fleet-skills/​.source-digests/​comment-and-doc-style Updates the generated source digest.
.agents/​skills/​workflow-ci-contract/​references/​d-guarantees.md Recasts authored workflow guidance.
.agents/​skills/​workflow-ci-contract/​references/​architecture.md Recasts authored workflow guidance.
.agents/​skills/​comment-and-doc-style/​SKILL.md Narrows the authored rule guidance.

🧠 Review effort: Lite


💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .agents/skills/comment-and-doc-style/SKILL.md Outdated
Comment thread .github/actions/prose-gate/prose_lint.py Outdated
Comment thread scripts/README.md Outdated
Comment thread tests/test_prose_lint.py
The rule text, both rule summaries, and the README now say a labeled
pair still needs the commas a list carries, and that a bullet's opening
label is not one of its items. A test pins the comma guard on the
labeled path, and two test docstrings now match their cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ptr727 and others added 2 commits October 10, 2026 09:15
The rule text names any list item's opening label rather than one
spelling of it, the summaries place the comma on both list shapes, and
the labeled-items docstring names its slashed case.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The gate strips only a bold opening label, so a plain, italic, or code
opening label still counts as the first of a labeled pair.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

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.

🔵 Needs a closer look

The gate can still exempt a clause-joining semicolon when only the second item has a label.

0 open findings

4 resolved since last review
Previously missed (1)

In code that hasn't changed since last review

Medium severity Require a qualifying first-item label before accepting lone semicolons

.github/​actions/​prose-gate/​prose_lint.py:2632

The lone-semicolon check accepts any colon in head, even when it introduces an explanation rather than a labeled first item. For example, The gate runs once, at merge: it reads, checks, and records the label; outputs: d and e. has a comma and a label-shaped tail, so the gate reports nothing despite the clause-joining semicolon. This leaves the original false-negative open when the second clause starts with a label. Require the first item to start with a qualifying label too, and cover this case in a test.

🧠 Review effort: Lite

ptr727 and others added 2 commits October 10, 2026 09:25
Any colon before the semicolon used to qualify the first item, so an
explanatory colon followed by a labeled second clause still exempted a
splice. The first item now has to open with a label too, a test pins
that shape, and the one WORKFLOW.md cell whose first label is a long
clause is recast as two sentences.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The head-label check read the list marker as the start of the first
label, so a plain labeled pair in a bullet was reported. The marker is
now skipped, the non-label tail cases carry a labeled head so they still
reach the tail check, and a docstring counts the colon arm's cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ptr727

ptr727 commented Oct 10, 2026

Copy link
Copy Markdown
Owner Author

Require a qualifying first-item label before accepting lone semicolons (.github/actions/prose-gate/prose_lint.py:2632): the lone-semicolon check accepts any colon in head, even when it introduces an explanation rather than a labeled first item.

Fixed in 4309839 and 372fc68. The first item must now open with a label too: LABELED_ITEM.match(LIST_MARKER.sub("", head, count=1)), where the list marker is skipped so a plain-labeled bullet still counts. Your example, The gate runs once, at merge: it reads, checks, and records the label; outputs: d and e., is now a reported case in test_a_colon_that_explains_does_not_exempt_a_lone_semicolon, and restoring ":" in head fails it. The one tree line this newly reported (WORKFLOW.md:247, a table cell whose first label is a 7-word clause) was recast as two sentences.

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.

🔵 Needs a closer look

The new matcher still exempts a lone semicolon when an invalid label appears inside an inline code span.

0 open findings

Previously missed (1)

In code that hasn't changed since last review

Medium severity Reject invalid code-span labels during exemption detection

.github/​actions/​prose-gate/​prose_lint.py:1052

The new two-label exemption treats an invalid code-span label as valid. For Inputs: a, b; /tmp: the run halts., check_file() first masks /tmp to two backticks, which LABEL_WORD accepts as a word, so the clause-joining semicolon is missed. The same happens with e.g. in a code span. Matching the original text alone will not fix this: the regex also treats the backtick delimiters as word characters, making /tmp and e.g. match even before masking. Validate the code-span contents as a label without counting backticks as word characters, while still masking code punctuation for prose scanning, and cover these cases in the negative tests.

🧠 Review effort: Lite

@ptr727

ptr727 commented Oct 10, 2026

Copy link
Copy Markdown
Owner Author

Reject invalid code-span labels during exemption detection (.github/actions/prose-gate/prose_lint.py:1052): the new two-label exemption treats an invalid code-span label as valid. For Inputs: a, b; /tmp: the run halts., check_file() first masks /tmp to two backticks, which LABEL_WORD accepts as a word.

Declined, with evidence. A code span is this repository's ordinary label for a file, key, task, or path, so it is a valid label rather than an invalid one. git grep -c -E '^\s*([-*]|[0-9]+\.)\s+[^]+:\s' -- '*.md'(excluding reports and generated copies) counts 20 tree lines that open with one, such as- .NET Build: build with diagnostic verbosity`. Rejecting code-span contents would report every such labeled pair joined by a single semicolon.

The example is itself label-shaped: ``/tmp: the run halts reads as a label and its description. A clause shaped like a short label is the known residual the PR body records under "Known Residual". Shape alone cannot tell the two apart, and it is the accepted cost of #2736's option 1. The earlier "Require a qualifying first-item label" finding, listed again on this round, was answered above and fixed in 4309839 and 372fc68.

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

Stripping an invalid code-span label can still cause the gate to miss a lone prose semicolon.

1 open finding

🧠 Review effort: Lite

Comment thread .github/actions/prose-gate/prose_lint.py
@ptr727

ptr727 commented Oct 10, 2026

Copy link
Copy Markdown
Owner Author

A recorded local strict-review pass covers head 372fc68ab18753047b61bf2743b0e1ad09f55f3f, the content this pull request carries at that commit against develop, and it recorded 0 findings.

@ptr727
ptr727 merged commit 043a10e into develop Oct 10, 2026
15 checks passed
@ptr727
ptr727 deleted the feature/auto-1396 branch October 10, 2026 17:10
ptr727 added a commit that referenced this pull request Oct 10, 2026
… Corrections to Main (#2740)

## Summary

Promotes 20 changes from `develop` to `main`:

- #2737: Flag a Lone Semicolon After an Explanatory Colon in the Prose
Gate
- #2734: Share pr_review.py wait's Liveness Readings and Open the Held
Poll on Its Snapshot
- #2732: Share One Bounded Backoff Loop Between pr_review.py wait's Two
Polls
- #2729: Document pr_review.py wait's Immediate 44 and check_nodes's
Node Keys
- #2727: Narrow pr_review.py wait's Exit 44 to Required Checks
- #2722: Poll an Attested Head's Checks in pr_review.py wait
- #2720: Name the Command That Enumerates Open Feature Pull Requests in
backlog-burndown
- #2718: Point the Skills Refresh Cadence at host-setup.md
- #2716: Fall Back to os.defpath for PATH in Two Test Harnesses
- #2714: State the Pip Form's Root-Config Type-Check Command in
python-codestyle
- #2712: State the Build Profile's CI Type Check as the Validator Runs
It
- #2709: Bring the Fleet-Map workflow-ci-contract Entry and G9 Gap Up to
the Skill Description
- #2707: Bring the Line-Endings Reference and a Test Docstring to the
Corrected Wording
- #2705: Drop the Stale Utilities driftNote From the Registry
- #2703: Remove the Inert SC2016 Directives in configure.sh and Correct
the shell-codestyle Claim
- #2701: Report Whether the Fleet Skills Plugin Is Installed and Enabled
in the Live Channel
- #2699: Align the Audit Report Template Dimensions With AUDIT.md
Section 4
- #2697: Harden the Source-Pinning Assertions in test_pr_review.py
- #2695: Name the Off-Grammar --branch Outcome in AUDIT.md
- #2693: Count Every Unresolved Review Thread in pr_review.py

Closes #1396
Closes #2731
Closes #2723
Closes #2725
Closes #2724
Closes #2685
Closes #1308
Closes #2191
Closes #1862
Closes #2711
Closes #2025
Closes #1243
Closes #1237
Closes #1115
Closes #1156
Closes #1757
Closes #1593
Closes #1732
Closes #1509
Closes #1404

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comments Permits the comment lines the pull request adds or edits, which the prose gate otherwise refuses

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants