Skip to content

Add formatter guardrails and contributor docs - #8

Merged
justin808 merged 5 commits into
mainfrom
jg/formatter-guardrails
Jun 25, 2026
Merged

Add formatter guardrails and contributor docs#8
justin808 merged 5 commits into
mainfrom
jg/formatter-guardrails

Conversation

@justin808

Copy link
Copy Markdown
Member

Summary

Validation

  • rubocop -> 15 files inspected, no offenses detected.
  • bin/validate -> PASS agent-workflows validation.
  • git diff --check -> clean.
  • codex review --base origin/main -> no actionable bugs found. The review sandbox could not run bin/validate because it was read-only and had no writable temp directory; the normal local bin/validate run above passed.

Formatter Diagnostic

After adding .rubocop.yml, I created a temporary tmp_formatter_probe.rb through the edit path with puts "double quote probe". The file stayed double-quoted in the diff, then I removed it before commit. That suggests the repo RuboCop config tames the edit-time formatter in this environment.

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@justin808, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 18 minutes and 56 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

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 credits.

🚦 How do rate 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 see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5df66c18-6a01-4e1a-9b11-541bf5ff8ff5

📥 Commits

Reviewing files that changed from the base of the PR and between 358a45c and 3be08e5.

📒 Files selected for processing (14)
  • .editorconfig
  • .github/workflows/validate.yml
  • .rubocop-version
  • .rubocop.yml
  • AGENTS.md
  • CHANGELOG.md
  • CONTRIBUTING.md
  • bin/agent-workflow-seam-doctor
  • bin/agent-workflows-status
  • bin/agent-workflows-status-test.rb
  • bin/validate
  • skills/plan-pr-batch/bin/pr-file-touch-map-test.rb
  • skills/pr-batch/bin/pr-ci-readiness-test.rb
  • skills/pr-batch/bin/pr-security-preflight-test.rb
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jg/formatter-guardrails

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.

@claude

claude Bot commented Jun 25, 2026

Copy link
Copy Markdown

This PR adds RuboCop guardrails, EditorConfig, and contributor docs that the repo needed. The rubocop config passes cleanly against the existing tree, the EditorConfig is sensible, and CONTRIBUTING.md is clear. Four issues to address before merge:


1. Two AGENTS.md seam keys are now stale

AGENTS.md is the authoritative seam that agents and tooling consult. Two keys need updating:

  • Changelog: n/aCHANGELOG.md now exists. This key should reference it (e.g., CHANGELOG.md) so the update-changelog skill and future agents know where to write release notes. As-is, any skill that reads this seam to decide whether to update a changelog will skip it permanently.
  • Lint / format: bin/validate plus Markdown review — the new rubocop CI gate is not listed here, and bin/validate does not invoke rubocop (see finding 2). Agents following this seam will run bin/validate, see green, push, and then fail CI with no prior warning.

2. bin/validate does not invoke rubocop — local and CI gates diverge

The declared pre-push validation entry point (bin/validate, per AGENTS.md) does not call rubocop. The new lint.yml CI workflow does. This means a contributor can pass every local check and still fail CI on a style offense. Consider adding a rubocop invocation at the end of bin/validate (after the existing helper tests) so the local gate is the complete gate.


3. Consumer-repo name react_on_rails appears in CHANGELOG.md (line 19)

AGENTS.md "Editing Rules" state: "Do not hardcode consumer repo commands, labels, branches, release trackers, or package paths in shared skills." The changelog is a shared pack file. Rephrase to something like "a consumer repo" to keep the attribution portable.


4. Lint/RedundantCopDisableDirective: Enabled: false leaves stale inline disables undetected

Three existing test files carry # rubocop:disable Metrics/ClassLength inline comments:

  • skills/pr-batch/bin/pr-ci-readiness-test.rb:107
  • skills/pr-batch/bin/pr-security-preflight-test.rb:15
  • skills/plan-pr-batch/bin/pr-file-touch-map-test.rb:16

.rubocop.yml now globally disables Metrics/ClassLength (and all other Metrics cops), making those inline directives redundant. With Lint/RedundantCopDisableDirective: Enabled: false, this drift will never be auto-detected. The fix is to either: (a) remove the now-redundant inline disables and keep the cop disabled globally, or (b) enable Lint/RedundantCopDisableDirective (the default) and remove the inline directives so the cop has nothing to flag. Either way, disabling the redundancy cop while also globally disabling the cops it would flag creates silent accumulation of stale suppression comments.

Comment thread CHANGELOG.md Outdated
Comment thread .github/workflows/lint.yml Outdated
Comment thread .rubocop.yml Outdated
@justin808

Copy link
Copy Markdown
Member Author

Address-review summary

Scan scope: full PR history; no prior address-review summary cutoff.

Mattered

  • Claude general review comment addressed in commit 444382c:
    • AGENTS.md seam now points Changelog at CHANGELOG.md.
    • AGENTS.md lint/format seam now records that bin/validate includes RuboCop.
    • bin/validate now runs RuboCop, and Validate CI installs the pinned RuboCop gem before invoking bin/validate.
    • Changelog wording no longer names a specific consumer repo.
    • Stale RuboCop suppression directives were removed and Lint/RedundantCopDisableDirective remains enabled.
  • Inline Claude threads were replied to and resolved:
    • CHANGELOG.md portability wording.
    • Local/CI RuboCop gate divergence.
    • Redundant RuboCop suppression drift.

Optional

  • None.

Skipped

  • CodeRabbit rate-limit/status comment: non-actionable status; no code or documentation change required.

Validation after fixes:

  • git diff --check
  • rubocop -> 15 files inspected, no offenses detected
  • bin/validate -> PASS agent-workflows validation
  • codex review --base origin/main -> no discrete correctness issues found

Next default scan starts after this comment. Say check all reviews to rescan the full PR.

@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: 444382cabf

ℹ️ 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 thread CHANGELOG.md Outdated
@claude

claude Bot commented Jun 25, 2026

Copy link
Copy Markdown

Code Review: Add formatter guardrails and contributor docs

This PR adds .rubocop.yml, a Lint workflow, .editorconfig, CONTRIBUTING.md, and CHANGELOG.md. The contributor docs are clear and portable, the editorconfig is straightforward, and gating bin/validate on RuboCop is the right instinct. Four issues worth addressing before merge:


1. RuboCop runs twice on every PR (medium)

lint.yml triggers on pull_request and runs rubocop directly. validate.yml also triggers on pull_request and runs bin/validate, which now ends with a bare rubocop call. Both jobs spin up a full Ubuntu runner, install Ruby 3.4 and RuboCop 1.87.0, and execute an identical rubocop invocation — on every PR.

Pick one of:

  • Remove rubocop from bin/validate and add push: branches: [main] to lint.yml so main is still gated after merge.
  • Remove lint.yml entirely and let validate.yml carry it via bin/validate (simpler; coverage is already symmetric).

The current belt-and-suspenders approach doubles CI cost and surfaces two identical status checks per PR.


2. RuboCop version pinned in two separate files (medium)

gem install rubocop -v 1.87.0 --no-document is copy-pasted verbatim in both lint.yml (line 22) and validate.yml (line 24). When the version is bumped, one file is likely to be missed — the two jobs then run different RuboCop versions on the same PR, producing diverging pass/fail signals that are difficult to reproduce locally.

Fix: a repository-level Actions variable (${{ vars.RUBOCOP_VERSION }}) or a reusable composite action so the version is defined in exactly one place.


3. Lint/ScriptPermission: Enabled: false silences missing-executable-bit warnings (low)

This cop warns when a file with a #!/usr/bin/env shebang lacks the executable bit. With it disabled globally, a future bin/ or skills/*/bin/ script committed without chmod +x passes all lint checks and only fails at runtime with Permission denied when called directly — a silent regression that CI's ruby script.rb invocation masks entirely.

All existing scripts already have correct permissions, so re-enabling the cop adds a guard at zero cost.


4. Style/IdenticalConditionalBranches: Enabled: false hides copy-paste logic bugs (low)

This cop fires when both branches of an if/else produce identical code — a reliable indicator of a copy-paste mistake where one branch was meant to differ. The seam-doctor and status scripts contain moderately complex conditional logic for path resolution; a silent no-op on the failure branch would not be caught by unit tests that only assert happy-path output.

Prefer suppressing specific known-identical branches locally with rubocop:disable Style/IdenticalConditionalBranches rather than a global disable.

Comment thread .github/workflows/lint.yml Outdated
Comment thread .github/workflows/lint.yml Outdated
Comment thread .rubocop.yml Outdated
Comment thread .rubocop.yml Outdated
@justin808

Copy link
Copy Markdown
Member Author

Address-review summary

Scan scope: review activity after 2026-06-25T08:03:20Z.

Mattered

  • Addressed the Codex changelog-format thread in 4b72426: CHANGELOG.md now uses ### [Unreleased], a bracketed dated header, and nested subsection headings compatible with the update-changelog helper.
  • Addressed the Claude duplicate-RuboCop workflow/version threads in 4b72426: removed the dedicated Lint workflow so RuboCop runs only through Validate / bin/validate with a single version pin.
  • Addressed the Claude RuboCop guardrail threads in 4b72426: re-enabled Lint/ScriptPermission by making bin/agent-workflows-status-test.rb executable, and re-enabled Style/IdenticalConditionalBranches by refactoring available_revision to share the common rev-parse tail.

Optional

  • None.

Skipped

  • CodeRabbit status/rate-limit comments were non-actionable.
  • Claude's top-level summary duplicated the inline findings above and is covered by the linked fixes/replies.

Validation:

  • git diff --check: pass.
  • rubocop: 15 files inspected, no offenses detected.
  • bin/validate: PASS agent-workflows validation.
  • codex review --base origin/main: no actionable regressions found.

Next default scan starts after this comment. Say check all reviews to rescan the full PR.

@claude

claude Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review: Add formatter guardrails and contributor docs

This PR cleanly introduces RuboCop enforcement, EditorConfig, and contributor docs. The bin/agent-workflows-status refactor is behavior-equivalent and a genuine simplification. The inline rubocop:disable removals are correctly covered by the new global config.

Findings (most severe first):

1. bin/validate calls rubocop without a version guard (medium)

CI pins rubocop 1.87.0 via gem install, but there is no Gemfile/Gemfile.lock, so a developer running bin/validate locally uses whatever rubocop is first on their PATH. A developer with 1.90.x could pass locally and fail in CI (or vice versa), with no error message pointing them to the right version. See inline comment on bin/validate.

2. CHANGELOG.md uses ### (h3) for release entries instead of ## (h2) (low-medium)

Keep a Changelog convention is ## [version] - date (h2) with ### Added/Changed/Fixed (h3) subsections. This file uses ### for releases and #### for subsections. The date is also duplicated: ### [2026-06-24] - 2026-06-24. Any changelog parser following the spec will find zero releases. See inline comment.

3. CONTRIBUTING.md redundant rubocop bullet (low)

The 'Before Opening A PR' checklist says 'Run rubocop after Ruby helper or test changes' but bin/validate (bullet above it) now calls rubocop internally. The redundant bullet risks confusion: a contributor reading it literally may run rubocop --autocorrect, which the very next sentence warns against. See inline comment.

4. NewCops: disable is undocumented (low)

.rubocop.yml silently opts out of every cop added in future RuboCop versions. This is a legitimate stability choice, but without a comment in the file a future upgrader will not know they need to audit rubocop --enable-new-cops when bumping the pinned version. See inline comment.


Out of scope / refuted:

  • actions/checkout@v6 was pre-existing and not changed by this PR.
  • Metrics/* blanket disables are intentional to avoid reformatting the existing tree; acceptable given the PR scope.
  • CONTRIBUTING.md mentioning main and bin/validate is this repo's own guide, not a shared skills/workflows file -- portability rules do not apply.

Comment thread bin/validate Outdated
Comment thread CHANGELOG.md Outdated
Comment thread CHANGELOG.md
Comment thread CONTRIBUTING.md Outdated

@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: 4b72426238

ℹ️ 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 thread CHANGELOG.md Outdated
Comment thread .rubocop.yml
@justin808

Copy link
Copy Markdown
Member Author

Address-review summary

Scan scope: review activity after 2026-06-25T08:20:25Z.

Mattered

  • Addressed the RuboCop version-skew thread in c770c3e: .rubocop-version is the single pin, CI installs from it, and bin/validate verifies/selects that version before running RuboCop.
  • Addressed the changelog entry-format thread in c770c3e: seeded entries now use bold descriptions plus linked [PR N](...) and author links.
  • Addressed the changelog header/date feedback in c770c3e: changed the seeded version slot to 0.1.0; kept ### headers intentionally because this pack's own update-changelog workflow parses that convention, and documented it in CHANGELOG.md.
  • Addressed the CONTRIBUTING redundancy thread in c770c3e: the bin/validate bullet now says it includes the pinned RuboCop check without encouraging a separate autocorrect run.
  • Addressed the NewCops: disable documentation thread in c770c3e: added an inline note to audit new cops deliberately on RuboCop bumps.

Optional

  • None.

Skipped

  • Claude's top-level summary and Codex's empty review summary were non-actionable after the inline threads above were handled.

Validation:

  • git diff --check: pass.
  • rubocop: 15 files inspected, no offenses detected.
  • bin/validate: PASS agent-workflows validation, including == rubocop 1.87.0 ==.
  • codex review --base origin/main: no actionable findings; its read-only sandbox could not complete full validation because temporary directories were not writable, so the writable local bin/validate result above is the validation source of truth.

Next default scan starts after this comment. Say check all reviews to rescan the full PR.

Comment thread .rubocop.yml
Comment thread .rubocop.yml
Comment thread CHANGELOG.md Outdated
Comment thread CHANGELOG.md
Comment thread CHANGELOG.md
Comment thread .github/workflows/validate.yml
@claude

claude Bot commented Jun 25, 2026

Copy link
Copy Markdown

Code Review

This PR wires RuboCop 1.87.0 into the validation pipeline, adds .editorconfig, seeds a CHANGELOG.md, and adds CONTRIBUTING.md. The bin/agent-workflows-status refactor is a clean simplification with no behavioral change — all prior error paths are preserved.

Six findings inline; summary below ranked by severity.


Must fix

CHANGELOG.md — two entries violate the update-changelog skill's "Do NOT add" rules
skills/update-changelog/SKILL.md Critical Requirements §2 states: "Do NOT add entries for: Linting fixes, Code formatting, CI/CD changes."

  • The PR 8 entry (RuboCop + EditorConfig — formatter/linter tooling) falls under "Code formatting" and "Linting fixes."
  • The PR 4 entry (GitHub Actions validate.yml) falls under "CI/CD changes."
    Both should be removed. See inline comments on lines 11 and 17.

CHANGELOG.md — version diff links missing
The update-changelog SKILL.md requires [unreleased]: and [0.1.0]: compare links at the bottom of the file. Without them the next /update-changelog release run will fail or corrupt the file. See inline comment on line 26.


Should fix

.rubocop.ymlMetrics/BlockLength omitted from the disabled list
Nine Metrics cops are disabled, but Metrics/BlockLength (default max: 25 lines) is missing. The intent is clearly "Metrics are not enforced here," but the gap silently re-enables enforcement for do…end blocks. The next contributor who writes a longer block will get an unexpected CI failure. One line fixes it — see the inline suggestion on line 34.

.github/workflows/validate.yml — no gem caching
gem install rubocop re-downloads RuboCop and ~40 transitive gems on every run. A minimal Gemfile + bundler-cache: true on setup-ruby (or an actions/cache step) would make subsequent runs near-instant. See inline comment on line 24.


Consider

.rubocop.yml line 12 — Layout/LineLength: Enabled: false
A blanket disable leaves no upper bound at all. Max: 120 (or similar) enforces a real ceiling while still being generous. See inline suggestion on line 13.

@justin808

Copy link
Copy Markdown
Member Author

Address-review summary

Scan scope: review activity after 2026-06-25T08:34:16Z.

Mattered

  • Addressed Metrics/BlockLength in 3be08e5: added it to the disabled Metrics cops so the RuboCop config is consistent.
  • Addressed the formatter-tooling changelog entry in 3be08e5: removed the current PR's [Unreleased] entry.
  • Addressed changelog version links in 3be08e5: added [unreleased] and [0.1.0] links.
  • Addressed CI gem install cost in 3be08e5: added an actions/cache@v4 gem-cache step keyed by Ruby and .rubocop-version.
  • Declined the Layout/LineLength cap suggestion with rationale: this repo currently has long shared workflow prompt lines and this PR must not reflow existing content, so disabling the cop remains the minimal passing config.
  • Declined removal of the PR Add CI workflow to run bin/validate #4 changelog seed with rationale: the task explicitly requested seeding the changelog from PR Add CI workflow to run bin/validate #4; future update-changelog runs should apply normal user-visible filtering.

Optional

  • None.

Skipped

  • Claude's top-level summary duplicated the inline findings above and is covered by the linked fixes/replies.

Validation:

  • git diff --check: pass.
  • rubocop: 15 files inspected, no offenses detected.
  • bin/validate: PASS agent-workflows validation, including == rubocop 1.87.0 ==.
  • codex review --base origin/main: attempted after 3be08e5, but the local review command hit the Codex usage limit before producing a verdict. Previous branch review passes were clean; final validation evidence is from the commands above and GitHub checks on this head.

Next default scan starts after this comment. Say check all reviews to rescan the full PR.

@claude

claude Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review: Add formatter guardrails and contributor docs

This PR adds RuboCop 1.87.0 with a double-quote style policy, .editorconfig, CONTRIBUTING.md, CHANGELOG.md, and a RuboCop lint step in CI. The agent-workflows-status refactor cleanly unifies the two rev-parse branches without dropping any error paths, and the removed rubocop:disable annotations are correctly superseded by the new global config. Portability looks clean — no consumer-repo specifics leaked into skills/ or workflows/.

Issues found (inline comments below):

Severity File Issue
Medium .github/workflows/validate.yml:31 ruby-3.4 hardcoded in cache key; won't track ruby-version: when bumped
Medium .github/workflows/validate.yml:27 No restore-keys — every .rubocop-version bump causes a full cold install
Low .github/workflows/validate.yml:34 gem install contacts rubygems.org even on a full cache hit
Low bin/validate:70 rescue Gem::LoadError misses Gem::ConflictError — raw backtrace on dependency conflicts
Low bin/validate:77 abort branch is unreachable dead code (gem "rubocop", version uses exact = constraint)
Low CHANGELOG.md:24 [unreleased] diff link hardcodes main; silently breaks on a branch rename

Comment thread .github/workflows/validate.yml
Comment thread .github/workflows/validate.yml
Comment thread .github/workflows/validate.yml
Comment thread bin/validate
Comment thread bin/validate
Comment thread CHANGELOG.md
@justin808

Copy link
Copy Markdown
Member Author

Address-review summary

Scan scope: review activity after 2026-06-25T08:52:37Z.

Mattered

  • Resolved the latest cache-key, restore-key, and cache-hit install suggestions as optional CI optimizations. The current cache is best-effort, exact-keyed by .rubocop-version, and the unconditional install keeps the small validation workflow simple.
  • Resolved the Gem::ConflictError and version postcondition suggestions as low-risk defensive-code discussion. The guard runs in a fresh Ruby process and already gives the expected friendly path for missing pinned RuboCop.
  • Resolved the [unreleased] branch-link suggestion with rationale: this repo's own seam currently names main as the base branch, and the root changelog is repo-local.
  • No code changes were made after 3be08e5; this was a reply/resolve-only convergence pass to avoid push-amplifying optional feedback.

Optional

  • The six latest suggestions were declined/deferred with rationale in-thread.

Skipped

  • Claude's top-level summary duplicated the inline findings above and is covered by the thread replies.

Validation state for 3be08e5:

  • GitHub Validate: pass.
  • CodeRabbit: pass.
  • GitHub claude-review: pass.
  • Local git diff --check, rubocop, and bin/validate: pass from the pushed 3be08e5 validation run.

Next default scan starts after this comment. Say check all reviews to rescan the full PR.

@justin808
justin808 merged commit 0aee555 into main Jun 25, 2026
39 checks passed
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.

1 participant