Skip to content

ci: audit issue lifecycle without mutation - #463

Closed
proerror77 wants to merge 3 commits into
mainfrom
codex/issue-lifecycle-audit-458
Closed

ci: audit issue lifecycle without mutation#463
proerror77 wants to merge 3 commits into
mainfrom
codex/issue-lifecycle-audit-458

Conversation

@proerror77

Copy link
Copy Markdown
Owner

Issue relationship

Closes #458

Change contract

Add one read-only auditor and one stable Issue Lifecycle workflow check for issue metadata, native relationship, PR-body, and commit-message lifecycle rules.

Out of scope

GitHub issue or PR mutation, historical metadata reconciliation, automatic closure, branch-protection changes, and required-check promotion.

Dependency / merge order

The lifecycle contract is already merged into main at 3d96cf9. This PR must merge before historical reconciliation and required-check promotion.

Focused validation

  • ruby -c .github/scripts/issue-lifecycle-audit.rb
  • bash -n .github/scripts/test-issue-lifecycle-audit.sh
  • shellcheck .github/scripts/test-issue-lifecycle-audit.sh
  • bash .github/scripts/test-issue-lifecycle-audit.sh
  • Live GET-only repository audit: deterministic 91 current violations.
  • Live PR-only counterexample on PR 446: exactly one relationship violation.
  • Fresh spec and standards reviews: pass.

Rollout / rollback impact

The workflow starts as observational and non-required with read-only permissions. Roll back by reverting this PR; it changes no issue metadata, repository setting, runtime, or branch-protection rule.

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@proerror77, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 30 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f6cf6c16-633d-449c-af67-01e5ad2ca8b4

📥 Commits

Reviewing files that changed from the base of the PR and between 3d96cf9 and e4e2e6d.

📒 Files selected for processing (3)
  • .github/scripts/issue-lifecycle-audit.rb
  • .github/scripts/test-issue-lifecycle-audit.sh
  • .github/workflows/issue-lifecycle.yml

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.

Comment thread .github/workflows/issue-lifecycle.yml Fixed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e9550082c7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +98 to +99
section = markdown_section(visible_markdown(body), "Runtime control")
return RUNTIME_CONTROL_FIELDS.keys unless section

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Parse the runtime issue-form fields

Runtime issues created from .github/ISSUE_TEMPLATE/runtime-rollout.yml render values beneath ### Exact target identity, ### Named controller, ### Rollback identity and procedure, and ### Stop rules, rather than inside a ## Runtime control section. Consequently, moving a correctly completed runtime issue to ready-for-agent always makes this function return all four fields as missing and causes the scheduled audit to fail. Parse the repository's actual issue-form headings and their following values instead of requiring an undocumented duplicate section.

Useful? React with 👍 / 👎.

pull_request
end

audited_issue_numbers = pr_number ? [] : issue_entries.map { |issue| issue.fetch("number") }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Audit linked issues during pull-request runs

When --pr is used, this assigns an empty audit set, so the current PR's linked issue bypasses audit_issue; the later pass checks only its assignee. A PR can therefore pass while its target has missing or conflicting category/state labels or other invalid lifecycle metadata, and if it merges before the scheduled audit, the newly closed issue disappears from the state=open query without the violation ever being reported. Scope audited_issue_numbers to the current PR's linked issues instead of excluding every issue.

AGENTS.md reference: AGENTS.md:L43-L46

Useful? React with 👍 / 👎.

Comment on lines +16 to +17
CLOSING_KEYWORD_SOURCE = "(?:close[sd]?|fix(?:es|ed)?|resolve[sd]?)"
CLOSING_PATTERN = Regexp.new("\\b(#{CLOSING_KEYWORD_SOURCE})\\s*:?\\s+#(\\d+)\\b", Regexp::IGNORECASE)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Detect repository-qualified closing references

GitHub closing keywords also accept qualified references such as Fixes OWNER/REPO#123, but this pattern only recognizes a bare #123. A PR can therefore declare Refs #10, include a qualified closing reference in its body or commit message, pass this audit, and still close that other issue when merged to the default branch. Extend the closing-keyword parser to cover GitHub's repository-qualified reference syntax.

AGENTS.md reference: AGENTS.md:L50-L53

Useful? React with 👍 / 👎.


violations << "Issue ##{number}: expected exactly one category label; found #{categories.empty? ? "none" : categories.join(", ")}" unless categories.length == 1
violations << "Issue ##{number}: expected exactly one triage state label; found #{states.empty? ? "none" : states.join(", ")}" unless states.length == 1
violations << "Issue ##{number}: body contains a literal escaped newline (\\n); publish multiline Markdown through a body file" if issue["body"].to_s.include?("\\n")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Allow legitimate escaped-newline text in issue bodies

The publication rule concerns accidentally encoding multiline Markdown as escaped shell text, but this rejects any literal \n anywhere in an issue body. Valid bug reports and engineering issues that include JSON strings, regular expressions, stack traces, or fenced examples containing that escape sequence therefore make the scheduled audit fail. Detect the structural artifact of an escaped multiline body, or at least exclude code spans and fenced blocks, rather than treating every occurrence as a publication error.

AGENTS.md reference: AGENTS.md:L43-L44

Useful? React with 👍 / 👎.

Comment on lines +193 to +194
visible_body = visible_markdown(pull_request["body"])
body_closings = closing_keywords(visible_body)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Scan PR titles that become squash commit messages

The audit scans the PR body and source commit messages but ignores pull_request["title"]. On this repository's squash-merge path, the PR title can become the final default-branch commit subject, so a title such as Fixes #99 can pass alongside a body declaring Refs #10 and then close issue #99 when the squash commit lands. Include the title in the closing-keyword and negation checks, and constrain any separately editable final merge message.

AGENTS.md reference: AGENTS.md:L50-L53

Useful? React with 👍 / 👎.

@proerror77

Copy link
Copy Markdown
Owner Author

Superseded by #470 for the auditor-only contract from #458. The workflow entrypoint has been split into #467 and will follow as a separate stacked PR. Closing this combined PR to keep one behavior contract per review unit.

@proerror77 proerror77 closed this Jul 29, 2026
@proerror77
proerror77 deleted the codex/issue-lifecycle-audit-458 branch August 13, 2026 06:37
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.

Audit issue hygiene and PR closure semantics without mutation

2 participants