Summary
PR #192 added a check in PersistentClaude._ensure_started() to skip the sudo wrapper when claude_user matches the bot process user (claude.py:216-230). However, triage.py:373-376 and review.py:643-646 have their own subprocess spawning logic with the same sudo pattern and did not receive this fix.
Details
All three locations use the same pattern:
if claude_user:
cmd = ["sudo", "-u", claude_user, "--"] + cmd
claude.py now checks whether self-sudo would be a no-op:
try:
current_user = pwd.getpwuid(os.getuid()).pw_name
except KeyError:
current_user = None
if effective_claude_user == current_user:
log.warning("claude_user %r matches the bot process user; skipping sudo")
effective_claude_user = None
But triage.py:375 and review.py:645 still use the bare if claude_user: guard. In a single-user setup where the bot runs as the same user as claude_user, triage and review subprocesses will attempt self-sudo — which either fails on sudoers rules or is a pointless privilege round-trip.
Impact
GitHub PR reviews and issue triage silently fail in single-user deployments where claude_user equals the bot process user.
Suggested fix
Extract the self-sudo check into a shared utility (e.g., in config.py or a new process_utils.py) and apply it in all three locations:
def resolve_claude_user(claude_user: str | None) -> str | None:
"""Return None if claude_user matches current process user (self-sudo skip)."""
if not claude_user:
return None
try:
current_user = pwd.getpwuid(os.getuid()).pw_name
except KeyError:
return claude_user
if claude_user == current_user:
log.warning("claude_user %r matches bot process user; skipping sudo", claude_user)
return None
return claude_user
Then in all three files:
effective_user = resolve_claude_user(claude_user)
if effective_user:
cmd = ["sudo", "-u", effective_user, "--"] + cmd
Summary
PR #192 added a check in
PersistentClaude._ensure_started()to skip the sudo wrapper whenclaude_usermatches the bot process user (claude.py:216-230). However,triage.py:373-376andreview.py:643-646have their own subprocess spawning logic with the same sudo pattern and did not receive this fix.Details
All three locations use the same pattern:
claude.pynow checks whether self-sudo would be a no-op:But
triage.py:375andreview.py:645still use the bareif claude_user:guard. In a single-user setup where the bot runs as the same user asclaude_user, triage and review subprocesses will attempt self-sudo — which either fails on sudoers rules or is a pointless privilege round-trip.Impact
GitHub PR reviews and issue triage silently fail in single-user deployments where
claude_userequals the bot process user.Suggested fix
Extract the self-sudo check into a shared utility (e.g., in
config.pyor a newprocess_utils.py) and apply it in all three locations:Then in all three files: