You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Flag a Lone Semicolon After an Explanatory Colon in the Prose Gate - #2737
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.
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.
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>
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>
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>
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>
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.
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>
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.
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
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.
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.
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.
… 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#1396Closes#2731Closes#2723Closes#2725Closes#2724Closes#2685Closes#1308Closes#2191Closes#1862Closes#2711Closes#2025Closes#1243Closes#1237Closes#1115Closes#1156Closes#1757Closes#1593Closes#1732Closes#1509Closes#1404
🤖 Generated with [Claude Code](https://claude.com/claude-code)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commentsPermits the comment lines the pull request adds or edits, which the prose gate otherwise refuses
2 participants
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 fromLABEL_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, soD1.2:labels whilee.g.,/tmp, and a quotation do not.WORKFLOW.mdlines 54, 181, 247, 294 (plus generated skill-reference copies) andcatalog/snippets/vscode/README.mdlines 17-18.comment-and-doc-styleandscripts/README.mdnow 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
commentslabel for the added code comments.🤖 Generated with Claude Code