1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
---
name: wf-pilot
description: Use when the owner types /wf-pilot in a project session (often an idle session opened from the phone app via Remote Control) to pilot an overnight run of headless `wf batch` runs; the session itself stays tiny. Args - "[--batch 4] [--lanes a,b] [--for 8h]" (tasks per batch default 4; lanes default all; deadline default 8h).
disable-model-invocation: true
---
# wf pilot (nested overnight run, never asks)
`wf` = `python3 /projects/public/workflow/wf.py`. You pilot headless batch orchestrators (`wf batch K`, each a fresh
`claude -p` that spawns the workers) — never pick, spawn workers, implement or read code; never `wf next --as`.
Background: /projects/public/workflow/docs/orchestrator.md 'Pilot (nested)'.
Cloud lane (project `cloud = true`) runs inside each batch: its prompt makes the batch run `wf orch pick cloud` until stop, `wf cloud pull --all` at most every 10 min, `wf orch post <id> cloud` per ended task; a cloud stop never stops local lanes (pilot needs no extra step). Needs the owner allow rule
`Bash(python3 /projects/public/workflow/wf.py batch:*)`; denied → tell the owner, end.
## Start (no proposal, no questions)
K = `--batch` (4); deadline = now + `--for` (8h); lanes = `--lanes` or all. `wf lanes` · `wf list -s awaiting`
(remember the awaiting ids). One status line to the owner, then go.
## Loop
1. Launch: `wf batch K [--lanes …] --left <time left>` (K shrinks to the tasks that fit by history, `--for` = left) → `<rid> started` → background Bash
`wf res wait <rid> --timeout <same>`; end the turn. `fit: 0 of K …; nothing started` → stop (step 6, why: deadline). Exit 3 (busy) → background Bash `sleep 600`, then retry.
2. Wait exit → `wf batch --status` (newest summary) → one line to the owner and `out/wf-orch.log`:
`<HH:MM> pilot batch <n> rc=<rc> done=<ids> stopped=<lanes: why> added=<ids>`. No task bodies, no logs.
A handback/awaiting blocks only its task (parked by `wf orch post`, alert); its lane stays in the next batch while it has pickable tasks. Never wait on the owner while tasks are pickable.
3. Failure (rc≠0, or no new summary file) → retry once; second failure → stop (step 6).
Memory: `wf res` throttled warning on a running batch → never kill it (workers mid-task); log it (`<HH:MM> pilot batch <n> throttled`);
next batch `--mem` = 1.5 × last (cap per `wf res free`). Batch oom-killed → re-run the same N with 1.5 × `--mem`.
4. `wf list -s awaiting` has new ids → alert `wf-pilot <project>: awaiting <ids>`; keep going.
5. Next: deadline passed → stop. Else `wf lanes`: a lane pickable → step 1. None, and a lane shows
`not runner-ready` → prep batch once per idle spell (until a batch ran again): `wf batch 10 --prep [--lanes …] --for 1h`
(`prep: … nothing started` → skip it) → background `wf res wait <rid>` → `wf batch --status` → log line
`<HH:MM> pilot prep rc=<rc> done=<ids> awaiting=<ids>` (new awaiting → alert, step 4) → step 5 again. Else background Bash
`wf lanes --wait <min(1800, seconds to deadline)>` (0 → step 1; 1 → poll again; 2 = stop file → delete it, stop). Seconds left < 60 → stop, no wait.
6. Stop: append a summary line to `out/wf-orch.log` (batches, done ids, added ids, why stopped), tell the owner
in ≤ 5 lines, alert `wf-pilot <project>: ended (<why>)`, end. Never kill a running batch.
Alert = PushNotification AND an `ALERT <text>` line in `out/wf-orch.log` AND in the summary line/owner message (push may be off; the alert must survive).
## Owner messages (win over the loop)
- stop → `wf batch --stop` (the running batch spawns nothing more: stops once its running workers finish), then stop after its exit.
- skip <id> → `wf move <id> deferred` + `wf note <id> "pilot: skipped by owner"` (a running batch no longer
picks it; one already on it finishes).
- pause / change lanes / batch size → apply from the next launch. Status? → `wf batch --status`, one line.
- Never /clear; context stays one line per batch.
|