p24-infra Issue-Pipeline Cron — Operations

Autonomous nightly that processes p24-infra’s own GitHub issue pipeline (triage → Design → Review) via the /process-issues skill. This is the p24-infra analogue of the et-operational-platform claude-nightly cron.

At a glance

FieldValue
HostIONOS vps-i1 (217.154.82.162)
Schedule0 23 * * *23:00 UTC daily
Cron file/etc/cron.d/p24-infra-nightly
Wrapper/root/p24-infra-nightly.sh (server-local, not in repo)
Runs asclaude-runner (root cron drops privileges via runuser)
Working clone/home/claude-runner/p24-infra (branch dev) — dedicated, NOT the live /opt/p24-infra deployment checkout
Skill/process-issues (--allowedTools Bash,Read,Edit,Write,Glob,Grep)
Log/var/log/p24-infra-nightly.log
Reporadieu/p24-infra (PRs target dev)

Scheduled at 23:00 UTC to stay clear of the et-app claude-nightly (02:07 UTC Mon–Fri) and the 02:00–04:00 UTC GitHub-Actions backup window.

What it does each run

  1. Refreshes the dedicated clone to origin/dev (reset --hard + pull), injecting the GitHub token at runtime and storing the remote tokenless.
  2. Runs claude -p "/process-issues" as claude-runner. The skill triages new issues, posts Code-change-design comments, implements Design-ready issues, and opens PRs to dev — all via gh.
  3. Logs start/finish to /var/log/p24-infra-nightly.log. Does not commit anything into the repo itself; the skill creates its own branches/PRs.

Design rationale

  • Dedicated clone, not /opt/p24-infra — the /opt checkout is the live deployment copy (carries uncommitted local state); issue processing must not switch branches or commit there.
  • Everything runs as claude-runner — Claude Code refuses --dangerously-skip-permissions as root, and running git as root would leave root-owned objects in .git that block later claude-runner commits (the exact failure that broke the et-app nightly — see that cron’s history).

Prerequisites (already satisfied on vps-i1)

  • claude-runner OAuth creds valid at /home/claude-runner/.claude/.credentials.json (with a refresh token, so they self-renew).
  • /home/claude-runner/.claude-env exports GITHUB_TOKEN, TRELLO_API_KEY, TRELLO_TOKEN. The wrapper also exports GH_TOKEN=$GITHUB_TOKEN for gh.
  • gh CLI present; token has push/admin on radieu/p24-infra.

Caveat — no PowerShell

The /process-issues skill is written with PowerShell helper snippets, but pwsh is not installed on vps-i1. Claude adapts these to gh/bash at runtime (the same as the et-app nightly), so this is not a blocker. If pipeline state-field updates ever prove unreliable, install PowerShell or port the Set-PipelineState helper to gh api in the skill.

Run manually / test

# Full run (as cron does)
/root/p24-infra-nightly.sh >> /var/log/p24-infra-nightly.log 2>&1
 
# Watch
tail -f /var/log/p24-infra-nightly.log

Troubleshooting

SymptomLikely cause / fix
Failed to authenticate. API Error: 401claude-runner OAuth expired with empty refresh token. Copy a valid .credentials.json from /root/.claude//home/claude-runner/.claude/, chown claude-runner, chmod 600.
detected dubious ownershipA git op ran as the wrong user. The wrapper runs everything as claude-runner; ensure nobody runs git in the clone as root.
insufficient permission for adding an object in .git/objectsRoot-owned objects in the clone. chown -R claude-runner:claude-runner /home/claude-runner/p24-infra/.git.
Nothing processedCheck gh issue list --repo radieu/p24-infra --state open; confirm token still valid.