Skip to content

Make /address-pr-comment skill use the URL of the PR context#176

Merged
ejfine merged 26 commits into
mainfrom
more-mutmut
Jun 29, 2026
Merged

Make /address-pr-comment skill use the URL of the PR context#176
ejfine merged 26 commits into
mainfrom
more-mutmut

Conversation

@ejfine

@ejfine ejfine commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Why is this change necessary?

If you make comments on the commit link in the repo context, the comments won't be associated with the PR---need to use the URL that opens the commit in the context of the PR.

How does this change address the issue?

Updates the skill to do that and moves more of the deterministic behavior into scripts rather than LLM.

What side effects does this change have?

N/A

How is this change tested?

Playing around with it

Other

Created a workspace file for this repo for root/child/grandchild

Backported some misc AGENTS.md and ruff rules

Summary by CodeRabbit

  • New Features

    • Added safer environment checks before running the comment workflow.
    • Improved commit links in replies so they open the relevant change view directly.
    • Added a workspace setup and updated editor/tooling versions for a smoother setup.
  • Bug Fixes

    • Reduced failures from command timeouts and missing repository details.
    • Improved handling when posting replies and cleaning up temporary files.
  • Chores

    • Updated lint, test, and pre-commit settings.
    • Refreshed pinned tool and extension versions across the project.

@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown

Review Change Stack

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 942b53f8-1b29-4f7f-83a0-4e1c2cf6b1be

📥 Commits

Reviewing files that changed from the base of the PR and between 67bae4a and 491cb21.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (13)
  • .claude/settings/permissions/bash.jsonc
  • .claude/skills/address-pr-comments/SKILL.md
  • .claude/skills/address-pr-comments/commit-link.py
  • .claude/skills/address-pr-comments/post-reply.py
  • .claude/skills/address-pr-comments/utils.py
  • .claude/skills/address-pr-comments/verify-env.py
  • .devcontainer/devcontainer.json
  • .devcontainer/install-ci-tooling.py
  • AGENTS.md
  • extensions/context.py
  • pyproject.toml
  • template/.devcontainer/devcontainer.json.jinja-base
  • template/copier.yml.jinja-base

📝 Walkthrough

Walkthrough

Adds two new Python helper scripts (verify-env.py, commit-link.py) to the address-pr-comments skill, introduces a shared run_cmd utility in utils.py, updates SKILL.md to use both new scripts, widens git bash permissions to a wildcard, registers the new scripts for executable permissions in the Copier template, and bumps various tool/library version pins across the repo.

Changes

address-pr-comments skill: new gate and commit-link scripts

Layer / File(s) Summary
Shared run_cmd helper in utils.py
.claude/skills/address-pr-comments/utils.py
Adds run_cmd wrapper around subprocess.run with configurable timeout and stderr/exit-on-timeout behavior; owner_repo_from_remote updated to use it.
verify-env.py: environment gate script
.claude/skills/address-pr-comments/verify-env.py
New CLI script collects git/PR facts (repo_root, has_remote, branch, on_protected_branch, dirty, pr) into a JSON verdict; exits non-zero on git failures, returns pr: null when gh pr view fails.
commit-link.py: commit placeholder replacement
.claude/skills/address-pr-comments/commit-link.py
New script resolves a git ref to a commit hash, auto-detects PR number via gh, constructs a PR-scoped GitHub commit URL, and rewrites the [COMMIT LINK] placeholder in a reply file.
post-reply.py updated to use run_cmd
.claude/skills/address-pr-comments/post-reply.py
Imports and delegates to run_cmd instead of calling subprocess.run directly; adds timeout=30 and a timeout message.
SKILL.md and permissions wired to new scripts
.claude/skills/address-pr-comments/SKILL.md, .claude/settings/permissions/bash.jsonc, template/copier.yml.jinja-base
Step 1 now runs verify-env.py as the single gate; commit-link.py fills the commit placeholder; steps renumbered; git bash permissions broadened to Bash(git *); new scripts added to the copier executable-permissions task.

Tooling version bumps and config updates

Layer / File(s) Summary
Version bumps across tooling and template context
.devcontainer/install-ci-tooling.py, extensions/context.py, pyproject.toml, .devcontainer/devcontainer.json, template/.devcontainer/devcontainer.json.jinja-base
Bumps uv, pnpm, nvm, pytest, faker, fastapi, pyrefly, pyright versions; removes ty_version from context; expands mutmut.also_copy to include uv.lock; bumps devcontainer node feature and VS Code extension pins.
pyrefly pre-commit hook and config
.pre-commit-config.yaml, pyrefly.toml
Adds a new local pyrefly hook running uv run pyrefly check on Python files excluding generated code; reformats pyrefly.toml with comments.
Ruff, workspace, and docs config updates
ruff.toml, copier-base-template.code-workspace, AGENTS.md
Adds SIM108 to ruff ignore list; adds a VS Code workspace file for the copier base template; adds a pytest assert-in-body rule to AGENTS.md.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • zendern
  • idonaldson
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly names the PR-scope URL change in the address-pr-comment skill and is concise.
Description check ✅ Passed The description covers the why, how, side effects, testing, and other notes, but it omits the required issue or thread link.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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.

@coderabbitai coderabbitai 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.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.claude/skills/address-pr-comments/commit-link.py:
- Line 1: The script commit-link.py needs the executable bit set so it can be
invoked directly by the Phase 2 flow. Update the file’s git mode to mark it
executable, keeping the existing shebang in place, so the direct invocation
described in SKILL.md works and CI no longer reports EXE001.

In @.claude/skills/address-pr-comments/SKILL.md:
- Around line 206-209: The reply-link generation step in commit-link.py is
re-detecting the PR from the branch instead of using the resolved PR number
already available earlier in the flow. Update the SKILL.md instructions around
the commit-link.py invocation so it passes the exact <pr_number> into
commit-link.py for <reply_file>, keeping the generated commit link aligned with
the PR used by the later post step.

In @.claude/skills/address-pr-comments/verify-env.py:
- Around line 52-57: The has_remote() check only confirms that any git remote
exists, but the later workflow in utils.py and commit-link.py requires an origin
remote with a GitHub URL. Update has_remote() in verify-env.py to validate the
origin remote specifically and reject non-GitHub remotes, or return the remote
metadata needed by downstream steps so the workflow fails early with the same
contract they expect.
- Line 1: The verify-env.py script is being invoked directly by path, but it is
not marked executable, which can cause Step 1 to fail with permission denied.
Update the file’s mode to set the executable bit on verify-env.py so the
workflow can run it directly, and ensure the change is applied to the existing
script rather than only affecting future generated copies.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: d6d13966-4488-4ed5-a019-6a898e624c5e

📥 Commits

Reviewing files that changed from the base of the PR and between 3be2550 and 67bae4a.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (14)
  • .claude/skills/address-pr-comments/SKILL.md
  • .claude/skills/address-pr-comments/commit-link.py
  • .claude/skills/address-pr-comments/verify-env.py
  • .devcontainer/devcontainer.json
  • .devcontainer/install-ci-tooling.py
  • .pre-commit-config.yaml
  • AGENTS.md
  • copier-base-template.code-workspace
  • extensions/context.py
  • pyproject.toml
  • pyrefly.toml
  • ruff.toml
  • template/.devcontainer/devcontainer.json.jinja-base
  • template/copier.yml.jinja-base

Comment thread .claude/skills/address-pr-comments/commit-link.py
Comment thread .claude/skills/address-pr-comments/SKILL.md
Comment thread .claude/skills/address-pr-comments/verify-env.py
Comment thread .claude/skills/address-pr-comments/verify-env.py Outdated
ejfine and others added 6 commits June 29, 2026 16:02
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Prevents re-detecting the PR from the branch when the PR number is
already known from Step 1, avoiding wrong commit links when a branch
maps to multiple PRs or --pr was used.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Prevents the skill from proceeding through Phase 1 when origin either
doesn't exist or isn't a GitHub remote, surfacing the failure at Step 1
instead of crashing at commit-link.py after work is already committed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
/pull/<pr>/changes/<hash> redirects to the standalone /commit/<hash>
view where comments are not PR-scoped. /pull/<pr>/commits/<hash> is
the correct PR-scoped URL.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bare URLs get auto-linkified by GitHub which may trigger URL
canonicalization; a Markdown link avoids that transformation.
Uses short 7-char hash as display text.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Comment thread .claude/skills/address-pr-comments/verify-env.py
ejfine and others added 7 commits June 29, 2026 16:32
Documents that bare URLs are auto-canonicalised by GitHub to the
standalone commit view, and why Markdown format is required to
preserve the PR-scoped link.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implementation detail, not relevant at the module description level.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The URL we generate is not where the user lands; clarify that GitHub
redirects it to the PR-scoped changes view.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@ejfine ejfine marked this pull request as ready for review June 29, 2026 16:59
@ejfine ejfine requested a review from zendern June 29, 2026 17:00

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
extensions/context.py (1)

16-31: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Restore context["ty_version"] or remove all template consumers in this PR.

extensions/context.py no longer supplies ty_version, but both template/extensions/context.py.jinja-base:8-26 and template/pyproject.toml.jinja-base:7-20 still reference {{ ty_version }}. That breaks the render contract for child templates the next time Copier evaluates those files.

Suggested fix
         context["pytest_version"] = ">=9.1.1"
         context["pytest_randomly_version"] = ">=4.1.0"
         context["pytest_cov_version"] = ">=7.1.0"
+        context["ty_version"] = ">=0.0.1"  # keep this in sync with template consumers, or remove all consumers in the same PR
         context["mutmut_version"] = ">=3.6.0"
         context["pyrefly_version"] = ">=1.1.1"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@extensions/context.py` around lines 16 - 31, The template context is missing
ty_version while existing consumers still expect it. In extensions/context.py,
either restore context["ty_version"] so
template/extensions/context.py.jinja-base and template/pyproject.toml.jinja-base
can continue rendering, or remove every {{ ty_version }} reference from the
templates in this PR so the render contract stays consistent.
.claude/skills/address-pr-comments/verify-env.py (2)

98-99: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Use separate protected-branch branches here.

The repo guideline asks Python implementation code to avoid membership tests like x in {"main", "master"} so coverage can measure each path independently. As per coding guidelines, "avoid x in ['a', 'b']-style membership tests in implementation code; use separate branches so coverage tools can measure each path independently."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/skills/address-pr-comments/verify-env.py around lines 98 - 99, The
protected-branch check in verify-env.py uses a membership test that should be
split into explicit branches so coverage can track each path independently.
Update the logic around current_branch() and on_protected_branch to avoid the
set membership form and instead compare the branch name with separate
branch-specific conditions for "main" and "master", preserving the same behavior
while making each path individually measurable.

Source: Coding guidelines


101-107: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Skip PR lookup when the remote gate already failed.

find_pr(args.pr) is evaluated while building the verdict. If has_remote() is False, this still runs gh auth status, so the script can exit before Step 1 ever sees has_remote: false. Compute the remote result first and only resolve pr after that contract passes.

Suggested fix
-    verdict = {
+    has_github_remote = has_remote()
+    verdict = {
         "repo_root": repo_root(),
-        "has_remote": has_remote(),
+        "has_remote": has_github_remote,
         "branch": branch,
         "on_protected_branch": on_protected_branch,
         "dirty": is_dirty(),
-        "pr": find_pr(args.pr),
+        "pr": find_pr(args.pr) if has_github_remote else None,
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/skills/address-pr-comments/verify-env.py around lines 101 - 107, The
verdict construction in verify-env.py eagerly calls find_pr(args.pr), which can
trigger gh auth status even when has_remote() is false. Update the logic so
repo_root(), has_remote(), branch, on_protected_branch, and dirty are evaluated
first, then only call find_pr(args.pr) after the remote check has passed. Keep
the fix localized around the verdict assembly and the find_pr helper usage so
the Step 1 remote gate can fail cleanly before any PR lookup runs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.claude/settings/permissions/bash.jsonc:
- Around line 44-45: The Bash permission entry for git is too broad because
Bash(git *) allows high-risk subcommands by default. Replace the wildcard in the
permissions config with an explicit allowlist in the same permissions block, and
move destructive or repository-altering operations such as remote changes,
pushes, resets, and clean operations behind ask-based approval rather than
matching every git subcommand. Use the Bash permission rule around git to locate
and narrow the allowed commands.

In `@template/copier.yml.jinja-base`:
- Around line 210-214: The new copier task in the copier template is invoking
copier_provenance.py with a raw python3 command, which conflicts with the repo’s
tooling guidance. Update the copier task to use the project’s standard
automation wrapper for running copier_provenance.py instead of calling python3
directly, or add a clear justification if this is the one allowed exception. Use
the existing copier task entry in copier.yml.jinja-base and the
copier_provenance.py script reference to locate the change.

---

Outside diff comments:
In @.claude/skills/address-pr-comments/verify-env.py:
- Around line 98-99: The protected-branch check in verify-env.py uses a
membership test that should be split into explicit branches so coverage can
track each path independently. Update the logic around current_branch() and
on_protected_branch to avoid the set membership form and instead compare the
branch name with separate branch-specific conditions for "main" and "master",
preserving the same behavior while making each path individually measurable.
- Around line 101-107: The verdict construction in verify-env.py eagerly calls
find_pr(args.pr), which can trigger gh auth status even when has_remote() is
false. Update the logic so repo_root(), has_remote(), branch,
on_protected_branch, and dirty are evaluated first, then only call
find_pr(args.pr) after the remote check has passed. Keep the fix localized
around the verdict assembly and the find_pr helper usage so the Step 1 remote
gate can fail cleanly before any PR lookup runs.

In `@extensions/context.py`:
- Around line 16-31: The template context is missing ty_version while existing
consumers still expect it. In extensions/context.py, either restore
context["ty_version"] so template/extensions/context.py.jinja-base and
template/pyproject.toml.jinja-base can continue rendering, or remove every {{
ty_version }} reference from the templates in this PR so the render contract
stays consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 942b53f8-1b29-4f7f-83a0-4e1c2cf6b1be

📥 Commits

Reviewing files that changed from the base of the PR and between 67bae4a and 491cb21.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (13)
  • .claude/settings/permissions/bash.jsonc
  • .claude/skills/address-pr-comments/SKILL.md
  • .claude/skills/address-pr-comments/commit-link.py
  • .claude/skills/address-pr-comments/post-reply.py
  • .claude/skills/address-pr-comments/utils.py
  • .claude/skills/address-pr-comments/verify-env.py
  • .devcontainer/devcontainer.json
  • .devcontainer/install-ci-tooling.py
  • AGENTS.md
  • extensions/context.py
  • pyproject.toml
  • template/.devcontainer/devcontainer.json.jinja-base
  • template/copier.yml.jinja-base

@coderabbitai coderabbitai 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.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
extensions/context.py (1)

16-31: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Restore context["ty_version"] or remove all template consumers in this PR.

extensions/context.py no longer supplies ty_version, but both template/extensions/context.py.jinja-base:8-26 and template/pyproject.toml.jinja-base:7-20 still reference {{ ty_version }}. That breaks the render contract for child templates the next time Copier evaluates those files.

Suggested fix
         context["pytest_version"] = ">=9.1.1"
         context["pytest_randomly_version"] = ">=4.1.0"
         context["pytest_cov_version"] = ">=7.1.0"
+        context["ty_version"] = ">=0.0.1"  # keep this in sync with template consumers, or remove all consumers in the same PR
         context["mutmut_version"] = ">=3.6.0"
         context["pyrefly_version"] = ">=1.1.1"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@extensions/context.py` around lines 16 - 31, The template context is missing
ty_version while existing consumers still expect it. In extensions/context.py,
either restore context["ty_version"] so
template/extensions/context.py.jinja-base and template/pyproject.toml.jinja-base
can continue rendering, or remove every {{ ty_version }} reference from the
templates in this PR so the render contract stays consistent.
.claude/skills/address-pr-comments/verify-env.py (2)

98-99: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Use separate protected-branch branches here.

The repo guideline asks Python implementation code to avoid membership tests like x in {"main", "master"} so coverage can measure each path independently. As per coding guidelines, "avoid x in ['a', 'b']-style membership tests in implementation code; use separate branches so coverage tools can measure each path independently."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/skills/address-pr-comments/verify-env.py around lines 98 - 99, The
protected-branch check in verify-env.py uses a membership test that should be
split into explicit branches so coverage can track each path independently.
Update the logic around current_branch() and on_protected_branch to avoid the
set membership form and instead compare the branch name with separate
branch-specific conditions for "main" and "master", preserving the same behavior
while making each path individually measurable.

Source: Coding guidelines


101-107: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Skip PR lookup when the remote gate already failed.

find_pr(args.pr) is evaluated while building the verdict. If has_remote() is False, this still runs gh auth status, so the script can exit before Step 1 ever sees has_remote: false. Compute the remote result first and only resolve pr after that contract passes.

Suggested fix
-    verdict = {
+    has_github_remote = has_remote()
+    verdict = {
         "repo_root": repo_root(),
-        "has_remote": has_remote(),
+        "has_remote": has_github_remote,
         "branch": branch,
         "on_protected_branch": on_protected_branch,
         "dirty": is_dirty(),
-        "pr": find_pr(args.pr),
+        "pr": find_pr(args.pr) if has_github_remote else None,
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/skills/address-pr-comments/verify-env.py around lines 101 - 107, The
verdict construction in verify-env.py eagerly calls find_pr(args.pr), which can
trigger gh auth status even when has_remote() is false. Update the logic so
repo_root(), has_remote(), branch, on_protected_branch, and dirty are evaluated
first, then only call find_pr(args.pr) after the remote check has passed. Keep
the fix localized around the verdict assembly and the find_pr helper usage so
the Step 1 remote gate can fail cleanly before any PR lookup runs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.claude/settings/permissions/bash.jsonc:
- Around line 44-45: The Bash permission entry for git is too broad because
Bash(git *) allows high-risk subcommands by default. Replace the wildcard in the
permissions config with an explicit allowlist in the same permissions block, and
move destructive or repository-altering operations such as remote changes,
pushes, resets, and clean operations behind ask-based approval rather than
matching every git subcommand. Use the Bash permission rule around git to locate
and narrow the allowed commands.

In `@template/copier.yml.jinja-base`:
- Around line 210-214: The new copier task in the copier template is invoking
copier_provenance.py with a raw python3 command, which conflicts with the repo’s
tooling guidance. Update the copier task to use the project’s standard
automation wrapper for running copier_provenance.py instead of calling python3
directly, or add a clear justification if this is the one allowed exception. Use
the existing copier task entry in copier.yml.jinja-base and the
copier_provenance.py script reference to locate the change.

---

Outside diff comments:
In @.claude/skills/address-pr-comments/verify-env.py:
- Around line 98-99: The protected-branch check in verify-env.py uses a
membership test that should be split into explicit branches so coverage can
track each path independently. Update the logic around current_branch() and
on_protected_branch to avoid the set membership form and instead compare the
branch name with separate branch-specific conditions for "main" and "master",
preserving the same behavior while making each path individually measurable.
- Around line 101-107: The verdict construction in verify-env.py eagerly calls
find_pr(args.pr), which can trigger gh auth status even when has_remote() is
false. Update the logic so repo_root(), has_remote(), branch,
on_protected_branch, and dirty are evaluated first, then only call
find_pr(args.pr) after the remote check has passed. Keep the fix localized
around the verdict assembly and the find_pr helper usage so the Step 1 remote
gate can fail cleanly before any PR lookup runs.

In `@extensions/context.py`:
- Around line 16-31: The template context is missing ty_version while existing
consumers still expect it. In extensions/context.py, either restore
context["ty_version"] so template/extensions/context.py.jinja-base and
template/pyproject.toml.jinja-base can continue rendering, or remove every {{
ty_version }} reference from the templates in this PR so the render contract
stays consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 942b53f8-1b29-4f7f-83a0-4e1c2cf6b1be

📥 Commits

Reviewing files that changed from the base of the PR and between 67bae4a and 491cb21.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (13)
  • .claude/settings/permissions/bash.jsonc
  • .claude/skills/address-pr-comments/SKILL.md
  • .claude/skills/address-pr-comments/commit-link.py
  • .claude/skills/address-pr-comments/post-reply.py
  • .claude/skills/address-pr-comments/utils.py
  • .claude/skills/address-pr-comments/verify-env.py
  • .devcontainer/devcontainer.json
  • .devcontainer/install-ci-tooling.py
  • AGENTS.md
  • extensions/context.py
  • pyproject.toml
  • template/.devcontainer/devcontainer.json.jinja-base
  • template/copier.yml.jinja-base
🛑 Comments failed to post (2)
.claude/settings/permissions/bash.jsonc (1)

44-45: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Do not open git access with a wildcard.

Bash(git *) now permits destructive and exfiltration-prone commands that the current denylist does not cover, including git remote set-url ..., non-force git push to other remotes/refs, git reset --hard, and git clean. Keep git on an explicit allowlist, and gate high-impact write operations behind ask instead of allowing every subcommand by default.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.claude/settings/permissions/bash.jsonc around lines 44 - 45, The Bash
permission entry for git is too broad because Bash(git *) allows high-risk
subcommands by default. Replace the wildcard in the permissions config with an
explicit allowlist in the same permissions block, and move destructive or
repository-altering operations such as remote changes, pushes, resets, and clean
operations behind ask-based approval rather than matching every git subcommand.
Use the Bash permission rule around git to locate and narrow the allowed
commands.
template/copier.yml.jinja-base (1)

210-214: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Avoid adding another raw python3 copier task.

This new task introduces another direct interpreter invocation, but the repo tooling guidance says not to call python/python3 directly. Please route copier_provenance.py through the project's standard automation wrapper, or document why this task is the exception. Based on learnings, "For tooling, never chain shell commands, never use python/python3 directly, prefer pre-commit run for linting and type-checking, avoid pnpm --prefix and uv --directory, and never rely on IDE diagnostics for ruff."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@template/copier.yml.jinja-base` around lines 210 - 214, The new copier task
in the copier template is invoking copier_provenance.py with a raw python3
command, which conflicts with the repo’s tooling guidance. Update the copier
task to use the project’s standard automation wrapper for running
copier_provenance.py instead of calling python3 directly, or add a clear
justification if this is the one allowed exception. Use the existing copier task
entry in copier.yml.jinja-base and the copier_provenance.py script reference to
locate the change.

Source: Learnings

import sys


def run(cmd: list[str], *, timeout: int) -> subprocess.CompletedProcess[str]:

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.

Should we use the utils run_cmd function here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Intentionally kept local here. utils.run_cmd uses check=True (raises on non-zero exit), but verify-env.py has deliberate soft-failure paths — find_pr returns None rather than exiting when gh pr view fails, and has_remote returns False when the URL fetch fails. Using run_cmd would require try/except CalledProcessError wrappers throughout, adding noise without benefit. The local run with check=False fits the "report facts, don't enforce policy" design of this script.

Reply drafted by AI (Claude), reviewed and approved by the author before posting.

@@ -0,0 +1,25 @@
{

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.

:nooice:

@ejfine ejfine merged commit 8819c8c into main Jun 29, 2026
7 checks passed
@ejfine ejfine deleted the more-mutmut branch June 29, 2026 17:26
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.

2 participants