orca-pi-connect
Skill14 starsChanged 20 days agoMITView on GitHub
Connect the foreman's session to a Pi builder in an Orca pane and PROVE the link (a pane the foreman opened itself (or one the owner confirmed) + assigned Pi session id, two-round handshake, Stop-log and session-file evidence), then send work-order pointers and wait on Pi's real turn-end signal. Use for /orca-pi-connect, "connect to pi", "set up the builder pane", or before a Topping Out job whose repo profile says builder delivery = pane link. Orca only (another pane host: hand-carry the pointers). Proves and uses the channel; never decides or approves anything for the owner. Also answers to its old name, /pi.
In this repository32 other files it gives its agents.
- AGENTS.mdAGENTS.md
- docs/llms-full.txtllms.txt
- docs/llms.txtllms.txt
- adjudicateSkill
- agent-councilSkill
- converseSkill
- f-archive-searchSkill
- f-archiveSkill
- f-blueprintSkill
- f-boardSkill
- f-cardSkill
- f-catchupSkill
- f-complySkill
- f-contextSkill
- f-distillSkill
- f-dreamSkill
- f-greploopSkill
- f-inspectSkill
- f-night-shiftSkill
- f-plancheckSkill
- f-scheduleSkill
- f-searchSkill
- f-setupSkill
- f-shiftSkill
- f-signoffSkill
- f-sketchSkill
- f-statusSkill
- f-surveySkill
- model-councilSkill
- pack-reviewSkill
- speakSkill
- xreviewSkill
The file
We split this skill into the rules it gives an agent
4 rules. About 0 are common, 3 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 101
If anything moved, go back to §1.
- Distinctive: line 112
Check all of these:
- Distinctive: line 158
The prompt produced no visible change: read the pane before resending.
- Very specific: line 163
More than one builder pane exists: keep one, on the right, in the foreman's tab.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
orca-pi-connect: the foreman ↔ a Pi builder, over Orca
The pane link for a repo whose builder runs in Orca (repo profile: builder delivery = pane link). It is the one bundled pane link: the Pi pieces it needs (the stop extension and stop-watch.mjs) live in this folder. Proven with pi 0.87 to 1.0 and orca 1.4.
Evidence, not vibes. Every claim is proven by an observable (a Stop-log line, a file on disk, a reply), never by a quiet pane.
1 binding the foreman opened the pane itself (exactly one new pane, on its right, fresh SID, or the old SID in a §1b resume), or the owner confirmed the handle + SID
2 pane Orca can target that binding and submit prompts
3 hook Pi's global agent_settled extension logs ONCE per genuine turn end
4 replies Pi answers, runs tools, and the reply is readable
5 session the on-disk session file records the turn under the bound idThe wake signal
- Extension:
~/.pi/agent/extensions/foreman-stop.ts, Topping Out's own. It's global, bindsagent_settled, fails open, and guards against child agents (FOREMAN_PI_STOP_OWNED). The source is bundled at.claude/skills/orca-pi-connect/pi-extension/foreman-stop.ts. On a new machine, copy it to~/.pi/agent/extensions/and restart Pi. - Log:
~/.pi/agent/foreman-stops.log. Lines look likeSTOP tag=<cwd folder> session=<id>; filter bysession=<id>. - Watcher:
.claude/skills/orca-pi-connect/stop-watch.mjs. Exit 0 = turn end, 2 = timeout, 3 = bad args. - Proved: one headless Pi turn (
pi -p --session-id <uuid>) wrote exactly one line, and the watcher returned exit 0. Other global stop extensions log to their own files and don't interfere.
LOG="$HOME/.pi/agent/foreman-stops.log"
WATCH=".claude/skills/orca-pi-connect/stop-watch.mjs"Halt
- A pane read with a missing or wrong handle can hit this session. That's a targeting halt, not builder evidence.
- Dim composer ghosts or predicted "next message" text aren't the builder speaking.
- The TUI can swallow a paste. If the prompt is sitting in the composer, send Enter only; don't resend.
- Never infer a finished turn from a quiet pane or
orca terminal wait --for tui-idle. A long tool call looks identical. The Stop log is the only completion signal. Timed out waiting for split pane handledoes not mean no pane was created. Orca timed out waiting for the handle; the pane is often already open on the right. A split error is UNKNOWN until §1's wait-and-count says otherwise.- Pi shows a trust or tool-approval prompt: surface it to the owner. Never blind-approve with keystrokes. (Starting Pi with
--approvein §1 is the deliberate, up-front trust for the job's own worktree; it is not a keystroke approval.)
0. Preconditions
orca worktree current --json # must be inside an Orca worktree
echo "$ORCA_WORKTREE_ID" # set in every Orca pane
pi --version
grep -c "agent_settled" ~/.pi/agent/extensions/foreman-stop.ts # >= 1; missing file -> install it (see "The wake signal")
grep -n "pi.on(" ~/.pi/agent/extensions/foreman-stop.ts # must be agent_settled, never agent_end
test -f .claude/skills/orca-pi-connect/stop-watch.mjs # missing -> re-run SETUP §1's install (an older install kept it elsewhere)orca agent hooks status reports Orca's own orca-agent-status.ts, which is a different extension and says nothing about the Stop signal.
1. Bind pane + session
Assign the session id; don't discover it. The builder goes in a pane on the right of the foreman, in the same tab, running in the job's worktree. Split the foreman's own pane: a split inherits the foreman's worktree (the main checkout) and takes no worktree flag, so the startup command changes folder first:
WT="<job worktree, absolute>" # cut by the foreman before work order 1 (METHOD §4)
orca terminal show --terminal "$ORCA_TERMINAL_HANDLE" --json # note the foreman's tabId
orca terminal list --include-visual-layouts --json # BEFORE: count the panes in that tab
SID=$(node -e "console.log(crypto.randomUUID())") # a FRESH id for every split attempt (one exception: §1b)
orca terminal split --terminal "$ORCA_TERMINAL_HANDLE" --direction vertical --command "cd '$WT'; pi --approve --session-id $SID" --json
orca terminal list --include-visual-layouts --json # AFTER: exactly one new pane, on the right, in the foreman's tabThe split is confirmed by the count, not by the command's reply:
- A split error is UNKNOWN, never a failure (the timeout above, or any other error). List the panes again a few times over about 10 seconds (
orca terminal list --include-visual-layouts --json), counting the panes in the foreman's tab. A new pane there means the split worked: take its handle from the list. Only an unchanged count after those checks means it failed. One immediate look proves nothing: a pane can register a few seconds late (the same rule as rule 12 of the Foreman rules inRULES.md, an empty read is not "nothing yet"). - Never split a second time on your own. If the wait shows no new pane, stop and ask the owner to look at the foreman's tab: the pane list can lag, and the owner can see the screen. Split again (with a new
SID) only after the owner says there is no new pane. (Learned in job 08: two splits, both "unconfirmed" by the list, both opened a pane.) - No fallback outside the foreman's tab. Never
orca terminal create(it opens a separate tab), and never start the builder in a terminal that already exists in another tab (the new worktree's own startup terminal included). If the split can't be confirmed in the foreman's tab, stop and tell the owner; never call another layout "a minor deviation". - Duplicates (two or more builder panes): keep one pane on the right in the foreman's tab, close the rest, and redo the kept pane's handshake (§3–§5) if any other pane shared its
SID. The layout rule wins over handshake evidence: a handshake costs a minute to redo. After closing the duplicates, the kept pane still needs the owner's yes (§1: the count was off). - Orca files the new pane under the foreman's worktree (its
worktreePathis the main checkout). That's expected. Pi's own working directory is the proof, checked in handshake round 1 (§3). --direction verticalputs the pane on the right. Orca's own guide states this backwards.--approve(Pi 1.0+) trusts the project's own files for this run, so a new worktree doesn't block on "Trust project folder?" and an autonomous run never waits on the owner's Enter. Only for a worktree of the owner's own repo. If the prompt appears anyway (an older Pi), read the pane and surface it to the owner.- The session file only appears after the first turn:
~/.pi/agent/sessions/<cwd-slug>/<timestamp>_<SID>.jsonl. - For a pane the owner started by hand, resolve the id from
ls -t ~/.pi/agent/sessions/<cwd-slug>/and a fresh Stop-log line. Never ask Pi for its own session id.
A pane you opened yourself binds without asking: the split ran in this session with a fresh SID (or, for a §1b resume, the old SID whose session file exists), the count went up by exactly one, and the new pane is on your right in your tab. Say which handle and SID you bound, in one line, and go straight to the handshake (§3), which proves the pane is Pi in the job's worktree. Ask the owner only for a pane you didn't open (one the owner started by hand), when two panes share a worktree, or when the count or placement is off: then put the handle + SID to the owner and get an explicit yes.
1b. Resume after the host slept or restarted
The builder pane died with the host, but its Pi session file exists (~/.pi/agent/sessions/<cwd-slug>/<timestamp>_<SID>.jsonl): split a new pane exactly as in §1, with the old SID (pi --approve --session-id <old SID>), which resumes its context. Redo both handshake rounds (§3, §4) and confirm the session file grew; the Stop-log count carries on from the old SEEN (the log is global, but counted by session=<SID>, so the old count still holds). Record the resume in the job file. This is the only reuse of a SID: a failed or duplicate split always takes a fresh one.
2. Revalidate, then snapshot
Right before every send:
orca terminal show --terminal <handle> --json # worktreePath, branch, tabId, incarnationId unchanged since binding
SEEN=$(grep -c "session=$SID" "$LOG" 2>/dev/null || echo 0)If anything moved, go back to §1. Count only the bound session's lines, because the log is global.
3. Handshake round 1: identity (no tools)
orca terminal read --terminal <handle> --limit 1 --json # keep result.terminal.nextCursor
orca terminal send --terminal <handle> --enter --json --text "Handshake check from the Foreman controller. Reply with exactly two lines: (1) your working directory, (2) the word READY. Do not run any tools or commands."
node "$WATCH" --session "$SID" --seen "$SEEN" --log "$LOG" # run as a BACKGROUND command so its exit wakes you
orca terminal read --terminal <handle> --cursor <nextCursor> --limit 80 --jsonCheck all of these:
- The reply contains the job worktree's absolute path and READY. Strip ANSI and match the string.
- The bound session's count grew by at least 1, and the new line's
session=equalsSID. - The pane footer shows the model the job expects. Ctrl+P silently cycles models; a changed footer means a changed builder.
4. Handshake round 2: tool loop
orca terminal send --terminal <handle> --enter --json --text "Run three SEPARATE bash commands, one at a time: echo one, then echo two, then echo three. Then print the value of ORCA_TERMINAL_HANDLE, and reply DONE."
node "$WATCH" --session "$SID" --seen <count after round 1> --log "$LOG"Check all of these:
- There were three separate tool calls and
DONE. - The printed
ORCA_TERMINAL_HANDLEequals the prompted handle. - The count grew by exactly 1, not 3. One line per real turn end. If it's more, the wrong event is bound, and every
--seendownstream is wrong.
5. Session file
ls -l ~/.pi/agent/sessions/<cwd-slug>/*"$SID"*.jsonl # exists, mtime inside the handshake windowThe reply, the Stop log and the session file are three witnesses to the same turn.
6. Using the link in a Topping Out job (METHOD §7e)
For each work order:
- Revalidate (§2) and take
SEEN. - Send only the one-line pointer to the work-order file, never the pasted text. Mark the file header "Sent by the foreman as a one-line pointer."
- Arm
stop-watch.mjsas a background command right after the send. A foreman that only checks the log during its own turns misses stops made while it's idle. If the host kills the watcher (memory pressure), don't restart it in the background unasked; say so in the reply and wait in the foreground, repeated:node "$WATCH" --session "$SID" --seen "$SEEN" --log "$LOG" --timeout-seconds 540, reading the log before each wait. At the start of your next turn, read the Stop log yourself (grep -c "session=$SID" "$LOG"againstSEEN) and act on any new STOP: a reaped watcher must not hide one. - On exit 0: disk check first (commits, captures, files), then read the builder's report file. The pane text isn't the report. A Stop counts as the work order's end only when its named report file exists: a Stop with no report (a tool-call timeout mid work order, say) is not done; read the pane and wait again.
- On exit 2 (timeout): check
orca terminal showforconnected: trueand an unchangedincarnationId. Never restart the builder on a quiet read. - Any other exit (1, 3), or a Stop log you can't read: tell the owner the link is down and go hand-carried (METHOD §7e). Never go quiet.
- At the end game, before removing the job's worktrees (METHOD §10 step 4), close the builder pane, not just Pi:
orca terminal close --terminal <builder handle> --json. Pi runs inside the pane's shell, so stopping Pi (or Pi exiting) leaves an empty shell pane behind. Then check it's gone:orca terminal list --include-visual-layouts --jsonshows your tab with only your own pane. A pane still there (a bare shell prompt): close it by its handle again; never leave it.
The owner keeps every word RULES.md reserves (merge, push, deletions). The link only carries pointers.
7. Report
Say whether the link is proven. Include the bound handle and SID (assigned; and whether you opened the pane or the owner confirmed it), both rounds, the Stop-log counts before and after, the session file, the model in the footer, and any findings. Don't start builder work without the owner's go.
Failure handling
- The log didn't grow after a finished turn: the wake signal is dead. Check the extension file, its
agent_settledbinding, and Pi's startup output for a load error. Don't proceed, and don't substitutetui-idle. - The log grew by more than 1 in one turn: wrong event, or the PID guard (
FOREMAN_PI_STOP_OWNED) was removed. Fix it before trusting any count. - The prompt produced no visible change: read the pane before resending. It may be mid-turn, or blocked on a trust or approval prompt.
- Pi's working directory in round 1 isn't the job worktree (the
cdfailed or was skipped): close that pane and split again with thecd. Never use it anyway, and never fall back toorca terminal create(a separate tab). - The handle printed in round 2 differs, or
incarnationIdchanged: the pane was replaced. Rebind: a pane you open again yourself binds as in §1; any other pane needs the owner's confirmation. - Pi never starts: the pane is a live shell, so read the actual error (PATH, bad
--session-id, missing provider credentials). - The split returned an error or timed out: it's unknown, not failed. Do §1's wait-and-count before anything else; if still unconfirmed, ask the owner to look; never retry on your own, fall back to another tab, or reuse the
SID. - More than one builder pane exists: keep one, on the right, in the foreman's tab; close the others; redo its handshake if they shared a
SID. Record the false start in the job file.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

