AI-Dev-IO1 Claude Runner (on vps-i1)
Environment ID: ai-dev-io1
Type: agent-runner
Status: active
Purpose
Autonomous Claude Code agent runner hosted on vps-i1 (IONOS). Handles p24-infra monitoring-ops tasks: nightly infra checks, hourly triage, compliance audits, PR reviews, and feature implementation for monitoring stack issues.
Host
Runs on vps-i1 (217.154.82.162 / AlmaLinux 9.7). See docs/environments/vps-i1.md for host hardware specs.
Agent Configuration
| Field | Value |
|---|---|
| GitHub user | AI-Dev-IO1 |
| Claude version | v2.1.121 at /usr/bin/claude |
| User | claude-runner (dedicated non-root user) |
| Credentials | /home/claude-runner/.claude/.credentials.json |
| Auth type | OAuth subscription (Claude Max) — not ANTHROPIC_API_KEY |
| Max parallel agents | 3 |
| Role | monitoring-ops |
| Repos | radieu/p24-infra (write), radieu/et-operational-platform (write) |
Parallelism Windows
| Window | Max agents | UTC hours |
|---|---|---|
| Daily scan | 3 | 09:00–22:45 |
| Nightly reviews | 5 | 23:00–01:00 |
Scheduled Tasks
| Task | Schedule | Description |
|---|---|---|
| Nightly infra check | 23:00 UTC daily | Checks VPS health, containers, disk, alerts |
| Hourly triage | Every hour | Processes new GitHub issues and assigns milestones |
| Issues review | On demand / nightly | Runs worker queue dispatching |
| Heartbeat | Every 6h | Reports agent health to Supabase scanner_heartbeat |
Environment Sync
The repo is synced to /opt/p24-infra via Ansible claude-env-sync role every 6 hours. The CLAUDE_ENV_LAST_CHANGED timestamp in CLAUDE.md triggers a forced resync when bumped.
Re-auth Procedure
OAuth tokens expire every 8–12 hours. Claude Code auto-refreshes using the refreshToken. When auth expires:
-
Automated (preferred): Claude attempts Playwright automation to complete the OAuth flow
- Run reauth script:
python d:\tmp\reauth-ionos.py - Use Playwright browser MCP to navigate the OAuth URL and capture the code
- Send code to server tmux session:
tmux send-keys -t claude_auth "<code>" Enter - Verify:
su -s /bin/bash claude-runner -c 'claude -p say-ok'
- Run reauth script:
-
Human escalation (if Playwright fails twice):
- Discord alert via
P24_DISCORD_INFRA_SCRIPTS_ERRORS_WEBHOOK_URL - GitHub issue with
human-actionlabel:"CRITICAL: claude-runner auth expired on vps-i1"
- Discord alert via
Notes
- Do not use ANTHROPIC_API_KEY for this runner — OAuth subscription provides zero marginal cost per call
- Never SSH into vps-i1 as claude-runner from an automated context — use the agent session on the server itself
- The claude-runner user has limited sudo:
docker,systemctl,mkdir,chown,cp,tee
Secrets Access
| Secret store | Access method | Can decrypt SOPS? |
|---|---|---|
All secrets/*.env.sops files | age key at /home/claude-runner/.age/keys.txt | Yes � claude-runner has the age key (verified 2026-06-24) |
| On-server plaintext fallback | /opt/p24-infra/monitoring/.env (deployed by CI) | N/A � already plaintext |
| GitHub Actions secrets | Not accessible from VPS directly | N/A |
AI-Dev-IO1 (claude-runner on vps-i1) does hold the SOPS age key and can decrypt all SOPS files directly. CI also deploys a plaintext copy to /opt/p24-infra/monitoring/.env on each merge as a fallback.
CLAUDE.md in Effect
The following rule layers are active for every AI-Dev-IO1 session, in priority order (highest first):
| Source | File on VPS | Key rules active |
|---|---|---|
| Global (user) | /home/claude-runner/.claude/CLAUDE.md | Use Bash (not PowerShell); SOPS lookup order; worktree workflow mandatory |
| Project | /opt/p24-infra/CLAUDE.md | Stack architecture; error notification standard (Discord + GH issue); EU AI Act compliance |
| Skills | ~/.claude/commands/*.md | /role-*, /new-issue, /nightly-infra-check, /hourly-devops-triage |
| Role standards | /opt/p24-infra/standards/project-types/sysadmin/* | Loaded when P4_CLAUDE_ROLE=monitoring-ops |
The global CLAUDE.md (/home/claude-runner/.claude/CLAUDE.md) is sourced from scripts/vps-global-claude.md in this repo and deployed by the claude-env-sync Ansible role.