Repository navigation
Keep a Line Holding Code After a Block Comment's Closer Out of comment-added - #3665
Conversation
A heredoc body in a workflow run block is read as code only where the command opening it names a program that runs the body, such as python3 or bash. Any other body, such as one cat writes into a file, is data. A line closing a block comment before code is no longer reported by comment-added, since deleting it deletes that code and leaves the comment unterminated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Code An opener closing nowhere is more often a shift, so the rest of the script stays code as it did before. Each heredoc on a line is judged by the list element holding it, so a program after && or in another command no longer makes a data body code. A flag value is no longer split at its equals sign, and ssh is added to the programs that run a body. The comment-and-doc-style skill states both exclusions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A separator inside quotes no longer splits a heredoc's command, `|&` is read as the pipe it is, and a comment line ending in a backslash continues no command. A command that is an expansion, such as "$PY", names its program only at run time, so its heredoc body stays code. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
A recorded local strict-review pass covers head |
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars.
|
There was a problem hiding this comment.
🟡 Changes recommended
Moderate active issues leave supported interpreters and quoted command expansions unrecognized, allowing comments in executed heredocs to bypass the prose gate.
2 open issues
What changed in this PR
This PR updates the prose gate to distinguish executable workflow heredocs from data heredocs and to exclude code following block-comment closers from comment-added findings. It also adds regression coverage and synchronizes documentation and generated skill artifacts. Two moderate findings remain regarding incomplete interpreter coverage and quoted expansion handling.
Changes:
- Adds
Line.trailedhandling for code after block-comment closers. - Classifies workflow heredocs using configured runners, expansions, pipelines, and continuations.
- Adds regression tests for heredoc and block-comment behavior.
- Updates prose-gate configuration, documentation, generated skills, and the source digest.
| File | Description |
|---|---|
tests/test_prose_lint.py |
Adds block-comment and heredoc regression tests. |
scripts/README.md |
Documents the two new comment-added exclusions. |
.github/skills/comment-and-doc-style/SKILL.md |
Updates the generated GitHub Copilot skill documentation. |
.github/actions/prose-gate/prose-gate.json |
Adds the configured heredoc runner allowlist. |
.github/actions/prose-gate/prose_lint.py |
Implements trailing-comment metadata and workflow heredoc classification. |
.claude-plugin/fleet-skills/skills/comment-and-doc-style/SKILL.md |
Updates the generated Claude skill documentation. |
.claude-plugin/fleet-skills/.source-digests/comment-and-doc-style |
Updates the generated skill source digest. |
.agents/skills/comment-and-doc-style/SKILL.md |
Updates the authored comment-and-documentation skill. |
Review effort: Lite
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #3665 +/- ##
===========================================
+ Coverage 81.60% 81.72% +0.11%
===========================================
Files 26 27 +1
Lines 9070 9126 +56
===========================================
+ Hits 7402 7458 +56
Misses 1668 1668
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
A quoted assignment value is no longer read as the command, so a body captured into a variable stays data. An expansion runs a body wherever a pipeline stage runs it, past a wrapper such as sudo or timeout. A trailing comment on the opener, or on a line above it, adds no words. uv, pypy, fish, csh and tcsh join the programs that run a body. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A list of programs that run a body kept missing runners, each one a body develop reads as code silently read as data. The rule is now the inverse. A body is data only where every pipeline stage it feeds runs a program in heredoc_data, such as cat, tee or gh. An unknown command, an expansion among them, keeps it code as develop reads it. Reserved words, groups and an assignment's command substitution open onto the command after them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gh, kubectl, jq and yq each have a form whose heredoc body runs as code, so they leave the data list, as base64 does, which the version strip never matched. A stage holding a process substitution may run the body through it, so it stays code. A trailing backslash on a continued opener is no longer read as the command word. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A group, a subshell, or a compound command's keyword on the opener can send the body to a pipe after its closer, so the body stays code, as does an opener whose own line a backslash continues. An assignment whose substitution closes before the command is skipped rather than followed into, and a substitution run as the command names no program. The rule text says a data command treats its input as data. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Code before the opener's line can leave a quote, a substitution, or a block open, and the construct can then send the body on to a shell when it closes. Such a body stays code. A stage's words are read from the quote-filled text, so a quoted paren no longer closes a substitution. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
A recorded local strict-review pass covers head |
The run-block heredoc reading did not converge. Each review pass found new shapes it read as data where bash runs the body as code. So the reading is withdrawn and a run-block heredoc stays code, as develop reads it. A line holding code after a block comment's closer is still out of comment-added's scope, with its seven-language test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A line holding two comments and then code is now tested, which catches a reading that stops at the second comment. The newline check in code_follows never changed its result, since the final slice is empty once the scan passes the line's end. The README sentence moves after the one its predecessor's "those defects" refers back to. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
A recorded local strict-review pass covers head |
…Session Prompt Rules (#3667) Promotes the changes merged into `develop` since promotion #3636 to `main`. - [#3640](#3640) Pins the validator's `uvx ruff` to a Dependabot-managed manifest. - [#3642](#3642) Counts Copilot findings under the unresolved bullet and the file table. - [#3644](#3644) Aligns the split comment copies and drops the stale counts. - [#3646](#3646) Sends a command meant for the session's input line in a plain message, never in a blocking prompt. - [#3648](#3648) Opens the attended session by cloning a hub checkout of the session's own. - [#3650](#3650) Reads a held package as installed in both Linux host scripts. - [#3652](#3652) States the PowerShell `-Help` and `-h` form in the command-line argument rules. - [#3654](#3654) Counts sentences in Markdown table cells for the sentence-length check. - [#3658](#3658) Splits a table row only at an unescaped pipe in the semicolon rule. - [#3660](#3660) Finds table cell boundaries before blanking code spans and quotations. - [#3662](#3662) Names a stale job record on a completed run in `pr_review.py`. - [#3665](#3665) Keeps a line holding code after a block comment's closer out of `comment-added`. Its squash commit on `develop` carries the pull request's original title, which names a heredoc reading. That reading was withdrawn before the merge on decision #3666, so a workflow `run:` heredoc body still reads as code. - [#3669](#3669) Counts each `[Pn]` marker in a Copilot Findings cell, so a second finding in one cell is no longer dropped from triage. It answers one of the two findings Copilot raised on this promotion. The other is declined with a parser probe in its thread. Closes #3616 Closes #3610 Closes #3622 Closes #3638 Closes #3604 Closes #3511 Closes #3602 Closes #3456 Closes #3655 Closes #3657 Closes #3362 Closes #1664 🤖 Generated with [Claude Code](https://claude.com/claude-code)

This closes the one #1664 shape that the lexer-based prose gate still reads as a comment and that a fix can remove without trading a visible false positive for a silent false negative.
comment-addedline. A newLine.trailedflag marks it, and a later comment on that line does not count as code. Deleting such a line, ascomment-addedasks, would delete that code and leave the comment unterminated. The case is covered for CSS, TypeScript, C#, JSONC, HTML, XML and csproj.run:block stays code, as develop reads it. This is the answer on decision Decide How the Prose Gate's Heredoc Half of #1664 Proceeds #3666. Eight recordedlocal-strict-reviewpasses over a hand-built reading of shell each found new shapes it read as data where bash runs the body as code. Each such error silently drops a real comment fromcomment-added,comment-wrapandcomment-case. Develop's reading errs only toward a visible false positive, which thecommentslabel clears. So this shape from The comment parser reads string and heredoc content as comments where a syntax carries no string state #1664 is recorded as accepted rather than fixed, and the heredoc commits on this branch are withdrawn by the latest commits rather than rewritten out of its history.b09f957c, the TOML"""string, the Terraform heredoc, the extensionless.husky/pre-push, and a multi-line double-quoted YAML scalar under an ordinary key all read clean.scripts/README.mdand thecomment-and-doc-styleskill state the closer exclusion. The skill's distributions are regenerated.Verification
code_followsthat stops at the second comment on a line fails it in all seven languages.build_dist.py --check, and the eol gate are clean.Closes on promotion: #1664
🤖 Generated with Claude Code