@irythill/orq 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -163,6 +163,7 @@ async function move(ws, c, to, dir, model, mark) {
163
163
  for (const id of c.issues)
164
164
  writeAtomic(join(ws, ".orquestra", id, "owner"), `pane=${pane} kind=herdr account=${basename(dir)} at=${new Date().toISOString()} name=${label}\n`);
165
165
  writeAtomic(handoffFile(c.pane), pane);
166
+ rmSync(handoffFile(pane), { force: true }); // the new pane is live: a leftover redirect out of it would make a cycle
166
167
  const regs = join(ws, ".orquestra", ".conductors");
167
168
  mkdirSync(regs, { recursive: true });
168
169
  writeAtomic(join(regs, pane.replace(/[^A-Za-z0-9_-]/g, "_")), `pane=${pane} kind=herdr account=${basename(dir)} at=${new Date().toISOString()} name=${label}\n`);
@@ -7,6 +7,7 @@ import { basename } from "node:path";
7
7
  import { m } from "../i18n.js";
8
8
  import { alive } from "../lock.js";
9
9
  import { ackPrefix } from "../notice.js";
10
+ import { doneStatus } from "../process.js";
10
11
  export const USAGE = "orq wait [--any] [--timeout <s>] [--answer] <prefix>... block until child agents finish (exit 1 = one failed)";
11
12
  const read = (f) => { try {
12
13
  return readFileSync(f, "utf8");
@@ -29,7 +30,10 @@ export function doneLine(prefix) {
29
30
  }
30
31
  catch { /* verify/baseline: no job */ }
31
32
  const answer = [`${prefix}.out.md`, `${prefix}.txt`].find(existsSync) ?? prefix;
32
- return { line: `[ORQ AGENT DONE] ${title} ${done} answer: ${answer}`, ok: /\bstatus=ok\b/.test(done) };
33
+ const status = doneStatus(done);
34
+ if (status === "killed")
35
+ done = done.replace(/\bstatus=\S+/, "status=killed"); // legacy "status=ok rc=137"
36
+ return { line: `[ORQ AGENT DONE] ${title} ${done} answer: ${answer}`, ok: status === "ok" };
33
37
  }
34
38
  export async function wait(argv) {
35
39
  let any = false, timeout = 0, answer = false;
package/dist/config.js CHANGED
@@ -15,6 +15,7 @@ export const DEFAULTS = {
15
15
  mem_enforce: "auto", // auto (kernel cap where possible, else watchdog) | kernel | watchdog | off
16
16
  test_slots: 1, // test suites in parallel on the machine
17
17
  close_tab_after: 20, // seconds until a finished child tab closes (0 = never)
18
+ tui_idle_close_min: 30, // minutes a finished -T agent waits for a follow-up before it is closed (0 = never)
18
19
  tui: false, // children in the agent's own screen (-T) by default
19
20
  terminal: "auto", // where children show their output: auto (herdr, else tmux, else plain) | herdr | tmux | plain
20
21
  },
@@ -27,7 +28,7 @@ export const DEFAULTS = {
27
28
  max_rounds: 2, // fix rounds before stopping and calling the user
28
29
  review: "other-vendor", // other-vendor | any
29
30
  },
30
- ui: { lang: "auto", theme: "gunmetal", desktop_notify: true }, // lang: auto | en | pt · theme: gunmetal | chrome | lcd | terminal · desktop_notify: desktop popup for failures (Linux, notify-send)
31
+ ui: { lang: "auto", theme: "gunmetal", desktop_notify: true, board_hide_hours: 6 }, // board_hide_hours: finished/dead agents older than this leave `orq board` (still in --json) · lang: auto | en | pt · theme: gunmetal | chrome | lcd | terminal · desktop_notify: desktop popup for failures (Linux, notify-send)
31
32
  // Where quota comes from, per agent: "builtin" | "none" | false | { command = "..." } (see src/quota.ts).
32
33
  // "claude" covers every account in claude-accounts.
33
34
  quota: { claude: "builtin", codex: "builtin", opencode: "builtin", antigravity: "builtin", copilot: "builtin" },
package/dist/notice.js CHANGED
@@ -9,7 +9,7 @@
9
9
  // if ui.desktop_notify allows, a desktop notification. Successes stay quiet: a plain herdr notification, nothing else.
10
10
  // `orq board` reads the same log to show failures that were not delivered or not yet acknowledged.
11
11
  import { spawn, spawnSync } from "node:child_process";
12
- import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, statSync } from "node:fs";
12
+ import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, statSync } from "node:fs";
13
13
  import { dirname, join } from "node:path";
14
14
  import { fileURLToPath } from "node:url";
15
15
  import { getPath, loadConfig } from "./config.js";
@@ -181,9 +181,24 @@ const exec = (cmd, args, timeoutMs = 15_000) => {
181
181
  return { status: r.error ? null : r.status, stdout: r.stdout ?? "", stderr: r.stderr || (r.error ? String(r.error.message) : "") };
182
182
  };
183
183
  const hasBin = (b) => spawnSync(process.platform === "win32" ? "where" : "which", [b], { stdio: "ignore" }).status === 0;
184
- /** Follow `orq handoff` redirects to the pane that now holds the conductor (stops at cycles and unreadable files). */
185
- export function currentPane(pane) {
186
- const seen = new Set();
184
+ /** Does herdr know this pane? true | false (herdr answered pane_not_found) | undefined (unreachable or unclear).
185
+ * `pane get`, not `agent get`: a live pane whose agent exited has no agent but is still a place to type. */
186
+ export function paneExists(pane, run = exec) {
187
+ const r = run("herdr", ["pane", "get", pane], 2_000);
188
+ if (r.status === 0)
189
+ return true;
190
+ if (r.status === null)
191
+ return undefined; // herdr is not installed / did not answer
192
+ return /"code"\s*:\s*"pane_not_found"/.test(`${r.stdout}\n${r.stderr}`) ? false : undefined;
193
+ }
194
+ /**
195
+ * Follow `orq handoff` redirects to the pane that now holds the conductor (stops at cycles and unreadable files).
196
+ * Walks the whole chain by files and returns the furthest pane that still exists, so a dead middle hop (A→B→C, B gone,
197
+ * C alive) does not strand the notice. The redirect out of that last live pane leads nowhere live: it is deleted (and
198
+ * logged). When herdr cannot be asked, a hop counts as live (the old behaviour: follow blindly).
199
+ */
200
+ export function currentPane(pane, run = exec) {
201
+ const chain = [pane], seen = new Set();
187
202
  while (!seen.has(pane) && existsSync(handoffFile(pane))) {
188
203
  seen.add(pane);
189
204
  let next;
@@ -195,9 +210,22 @@ export function currentPane(pane) {
195
210
  }
196
211
  if (!next || next === pane)
197
212
  break;
213
+ chain.push(next);
198
214
  pane = next;
199
215
  }
200
- return pane;
216
+ let last = 0;
217
+ for (let i = 1; i < chain.length; i++)
218
+ if (paneExists(chain[i], run) !== false)
219
+ last = i;
220
+ // A redirect out of the last live pane exists only when the chain went on to dead panes.
221
+ if (last < chain.length - 1 && existsSync(handoffFile(chain[last]))) {
222
+ try {
223
+ rmSync(handoffFile(chain[last]), { force: true });
224
+ append({ id: `redirect-${Date.now().toString(36)}`, ev: "redirect", pane: chain[last], detail: `stale handoff to closed ${chain[last + 1]} removed` });
225
+ }
226
+ catch { /* best effort */ }
227
+ }
228
+ return chain[last];
201
229
  }
202
230
  function realDeps(id, pane, issue) {
203
231
  let setting;
package/dist/process.js CHANGED
@@ -77,6 +77,13 @@ export function treePids(root, table = processTable()) {
77
77
  export function treeMem(root, table = processTable()) {
78
78
  return treePids(root, table).reduce((t, p) => t + (table.get(p)?.[1] ?? 0), 0);
79
79
  }
80
+ /** An exit code of 128+signal (137 = SIGKILL): the process was killed, it did not finish. */
81
+ export const killedRc = (rc) => rc !== undefined && rc > 128 && rc <= 128 + 64;
82
+ /** "status=ok rc=137" (written before `killed` existed) is a kill, not a success: the status a done line really means. */
83
+ export function doneStatus(line) {
84
+ const st = /\bstatus=(\S+)/.exec(line)?.[1], rc = /\brc=(\d+)/.exec(line)?.[1];
85
+ return st === "ok" && killedRc(rc === undefined ? undefined : Number(rc)) ? "killed" : st;
86
+ }
80
87
  export function killTree(pid, group = true) {
81
88
  if (process.platform === "win32")
82
89
  spawnSync("taskkill", ["/T", "/F", "/PID", String(pid)], { stdio: "ignore" });
package/dist/stats.js CHANGED
@@ -6,6 +6,7 @@
6
6
  import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
7
7
  import { homedir } from "node:os";
8
8
  import { basename, join } from "node:path";
9
+ import { doneStatus } from "./process.js";
9
10
  const ROLE = /^(impl|fix\d*|review\d*|[a-z]+-review\d*|watchdog\d*)-?/;
10
11
  const read = (f) => { try {
11
12
  return readFileSync(f, "utf8");
@@ -120,7 +121,7 @@ export function collectRuns(ws, days) {
120
121
  : name.startsWith("impl") ? "impl" : "other";
121
122
  const out = read(`${pre}.out.md`);
122
123
  const [neu, tot] = tokens(agent, log, read(`${pre}.id`).trim());
123
- runs.push({ issue, name, agent, model, role, ok: read(done).includes("status=ok") && out.trim() !== "",
124
+ runs.push({ issue, name, agent, model, role, ok: doneStatus(read(done)) === "ok" && out.trim() !== "",
124
125
  secs: Math.max(0, Math.floor((statSync(done).mtimeMs - rs.mtimeMs) / 1000)), new: neu, tot,
125
126
  repo: name.includes("-") ? name.slice(name.indexOf("-") + 1) : "" });
126
127
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@irythill/orq",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Orchestrate coding agents (Claude Code, Codex, OpenCode, Antigravity, Copilot) from one conductor.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,36 +1,36 @@
1
1
  ---
2
2
  name: issue
3
- description: Runs a Plane issue end to end by orchestrating coding agents in herdr or any terminal (herdr-agent / orq agent + orq wait) — implementer and cross-vendor reviewer picked by orq pick, tests by herdr-verify / orq verify, comment and status in Plane. Use when the user says "/issue <ID>", "take issue X", "run ABC-123", or asks to check/create issues in the conductor's ecosystem.
3
+ description: Runs a Plane issue end to end by orchestrating coding agents in herdr or any terminal (orq agent + orq wait) — implementer and cross-vendor reviewer picked by orq pick, tests by orq verify, comment and status in Plane. Use when the user says "/issue <ID>", "take issue X", "run ABC-123", or asks to check/create issues in the conductor's ecosystem.
4
4
  ---
5
5
 
6
- # /issue <ID> — conductor playbook (herdr or any terminal)
6
+ # /issue <ID> — conductor playbook
7
7
 
8
8
  You are the **orchestrator**: you plan, dispatch, follow up and report. **Do not implement anything yourself** (it
9
9
  burns the conductor's model). Talk to the user in the user's language.
10
10
 
11
11
  **Ecosystem configuration:** the **workspace** `CLAUDE.md` (the folder named in your conductor instructions) defines
12
- the repositories and their groups (= herdr workspace, `-g`), **each repo's base branch**, verification commands,
12
+ the repositories and their groups (= herdr workspace or just a label, `-g`), **each repo's base branch**, verification commands,
13
13
  Plane projects (identifier → project_id), default assignee, labels/modules and MCP limitations. Read it before you
14
14
  start. Below, `$WS` = workspace.
15
- **Inside herdr** (`HERDR_ENV=1`): children open in herdr tabs and their notices reach your pane — the flow below.
16
- **Outside herdr** (any terminal, tmux, any OS): the same flow with these swaps —
17
- - `herdr-agent ...` → `orq agent ...` (same flags; it is the same program). Children run in tmux windows inside tmux,
18
- else in the background (their screen goes to a log; the answer is still `<prefix>.out.md`). `-T` needs tmux.
19
- - `herdr-claim` → `orq claim` (set `ORQ_CONDUCTOR_ID` to a fixed name per conductor), `herdr-deps` → `orq deps`.
20
- - **Completion signal:** no line arrives in your pane. After dispatching, run `orq wait <prefix>` **as a background
15
+ **Terminal:** the flow is the same in herdr, tmux or a plain terminal, on any OS. Children open in herdr tabs inside
16
+ herdr (`HERDR_ENV=1`), in tmux windows inside tmux, else in the background (their screen goes to a log; the answer is
17
+ still `<prefix>.out.md`; `-T`, the agent's own screen, needs herdr or tmux). Set `ORQ_CONDUCTOR_ID` to a fixed name per
18
+ conductor outside herdr.
19
+ - **Completion signal:** in herdr, one line `[HERDR-AGENT DONE] <title> status=ok|fail ... answer: <file>` is typed into
20
+ your pane after each child. Anywhere else no line arrives: after dispatching, run `orq wait <prefix>` **as a background
21
21
  task** (Claude Code: Bash with `run_in_background`); its exit wakes you and its output is the line
22
- `[ORQ AGENT DONE] <title> status=ok|fail ... answer: <file>` — treat it exactly like `[HERDR-AGENT DONE]`. Several
23
- children in parallel: `orq wait --any <prefix1> <prefix2>` (one wake-up per finish; wait again for the rest).
24
- No background tasks in your harness → run `orq wait` in the foreground; that is the one allowed blocking wait.
25
- - `herdr-verify` → `orq verify`, `herdr-baseline` → `orq baseline` (same flags). They run in a tmux window or in
26
- the background like children, and you wait for them the same way: `orq wait $O/verify-<repo>`.
27
- - Peeking at a child: `<prefix>.log` (not `herdr pane read`).
22
+ `[ORQ AGENT DONE] <title> status=ok|fail ... answer: <file>`. Treat both lines the same. Several children in parallel:
23
+ `orq wait --any <prefix1> <prefix2>` (one wake-up per finish; wait again for the rest). No background tasks in your
24
+ harness → run `orq wait` in the foreground; that is the one allowed blocking wait.
25
+ - `orq verify` and `orq baseline` run like children (herdr tab, tmux window or background) and you wait for them the same
26
+ way, e.g. `orq wait $O/verify-<repo>`.
27
+ - Peeking at a child: `<prefix>.log` (in herdr also `herdr pane read $(cat <prefix>.pane) --source recent`).
28
28
  Issue artifacts (prompts, notes) live in `$WS/.orquestra/<ID>/`.
29
29
 
30
30
  ## 1. Read the issue
31
- - **First, claim it:** `herdr-claim -w $WS <ID>`. Exit 1 = another conductor owns it: **stop** and tell the user
31
+ - **First, claim it:** `orq claim -w $WS <ID>`. Exit 1 = another conductor owns it: **stop** and tell the user
32
32
  (don't read it, don't dispatch anything). Taking it over (e.g. switching accounts) only with the user's OK:
33
- `herdr-claim -w $WS -f <ID>`. Several conductors may share a workspace; `herdr-claim -w $WS -l` lists who has what,
33
+ `orq claim -w $WS -f <ID>`. Several conductors may share a workspace; `orq claim -w $WS -l` lists who has what,
34
34
  with each conductor's name (its herdr workspace label, e.g. "emp: orq-cms-dsgn"; outside herdr, `ORQ_CONDUCTOR_ID`).
35
35
  - **The user names another conductor** ("take over orq-cms-dsgn's work"): never guess a pane id. Run
36
36
  `orq claim -w $WS --from "<what they said>"` (any part of the name works). It lists that conductor's issues; exit 3 =
@@ -71,19 +71,19 @@ orq pick opinion --impl-agent <agent that implemented> # second opin
71
71
  ```
72
72
  More than one agent eligible for `review`/`opinion` (declared, not excluded or blocked, with a model for the role; quota is not considered) and neither `--impl-agent` nor `--impl-vendor` given → exit 2:
73
73
  always pass one of them (`--no-record`/`--explain` do not change this).
74
- The output goes straight into `herdr-agent` (`herdr-agent $(orq pick ...) -g ... -t ... -d ... -o ... -- prompt.md`).
74
+ The output goes straight into `orq agent` (`orq agent $(orq pick ...) -g ... -t ... -d ... -o ... -- prompt.md`).
75
75
  - Exit 3 = no candidate (quota exhausted, no agent with that role): **stop and ask the user**.
76
76
  - Implementer failed review twice (step 6) → pick again without it: `orq pick impl --level <level> --exclude-agent <agent>`.
77
77
  - `--exclude-agent` never "sticks": every `orq pick` call decides again, with only that dispatch's exclusions.
78
78
  - The conductor's own model (e.g. Opus) as implementer: only with the user's OK, never through `orq pick`.
79
79
  - Want to understand a choice? `orq pick ... --explain --no-record` (score of each candidate; not counted in rotation).
80
80
 
81
- **Every child runs through `herdr-agent`** (agent from `orq pick`): headless (`claude -p` / `codex exec` /
82
- `opencode run` / `agy -p` / `copilot -p`) in a herdr tab (workspace = group `-g`, tab = title) with live output.
83
- When it finishes it writes `<prefix>.done` and sends ONE line `[HERDR-AGENT DONE] <title> status=ok|fail ...` to your
84
- pane; no MCP, and a **4 GB memory cap per agent** (own cgroup: if it blows up, only it dies). NEVER `herdr agent start`
81
+ **Every child runs through `orq agent`** (agent from `orq pick`): headless (`claude -p` / `codex exec` /
82
+ `opencode run` / `agy -p` / `copilot -p`) in a herdr tab (workspace = group `-g`, tab = title), a tmux window or the
83
+ background, with a log. When it finishes it writes `<prefix>.done` and signals you (see the completion signal above:
84
+ `[HERDR-AGENT DONE] <title> status=ok|fail ...` in herdr, `orq wait` elsewhere); no MCP, and a **4 GB memory cap per agent** (own cgroup: if it blows up, only it dies). NEVER `herdr agent start`
85
85
  for children (no memory cap, no answer file). **Screen mode (`-T`, or `HERDR_AGENT_TUI=1`; herdr or tmux):** the tab
86
- shows the agent's own TUI instead of the log; same cap, same files, same signal (end-of-turn hook). The screen stays
86
+ or window shows the agent's own TUI instead of the log; same cap, same files, same signal (end-of-turn hook). The screen stays
87
87
  open after the turn (it holds memory until the tab closes); `-R` with the tab open types the follow-up into it. Use it
88
88
  when the user wants to watch. The repo must already be trusted in Codex/Claude (otherwise the TUI stops at the "trust this
89
89
  folder?" dialog — tell the user, don't approve it for them).
@@ -115,7 +115,7 @@ git -C $WT log -1 --format='%h %s' # check HEAD == origin/$BA
115
115
  on a modest disk that saturates I/O and memory and freezes the machine). The worktree uses a **link** to the main
116
116
  repo's `node_modules`:
117
117
  ```bash
118
- herdr-deps -r $R -b $BASE -w $WT # link; stale deps → fast-forward + ONE install in $R (per-repo lock across conductors)
118
+ orq deps -r $R -b $BASE -w $WT # link; stale deps → fast-forward + ONE install in $R (per-repo lock across conductors)
119
119
  ```
120
120
  Exit 3 = stale deps and `$R` dirty or not on `$BASE` → **ask the user**. If another conductor is installing in the
121
121
  same repo, the command waits its turn (never install by hand).
@@ -124,39 +124,39 @@ tell me".
124
124
  **Dispatch** (no MCP; memory cap; writes in automatic mode — that is why implementation only happens in a worktree):
125
125
  ```bash
126
126
  orq pick impl --level <level> > $O/impl-<repo>.pick # the fix rounds reuse it (step 6)
127
- herdr-agent $(cat $O/impl-<repo>.pick) -g <group> -t "<ID> impl <repo>" -d $WT -o $O/impl-<repo> -- $O/impl-<repo>.md
127
+ orq agent $(cat $O/impl-<repo>.pick) -g <group> -t "<ID> impl <repo>" -d $WT -o $O/impl-<repo> -- $O/impl-<repo>.md
128
128
  ```
129
129
  - The Claude account (`-c`) already comes from `orq pick` (one under the limit whose pace stays within it, then the least used).
130
130
  - Full final answer in `$O/impl-<repo>.out.md`; log in `.log`; the agent's session id in `.id`.
131
131
  - Codex's sandbox has no network: `git fetch` is yours, beforehand (above). Push/PR: yours (step 7).
132
- - `herdr-agent` returns immediately (no need to background it); the child's pane is in `<prefix>.pane`
133
- (`herdr pane read $(cat <prefix>.pane) --source recent` to peek).
134
- - **No baseline in the issue flow:** don't run `herdr-baseline` before dispatching (the base moves with every merge and
135
- the full suite blocks every conductor's test queue). `herdr-verify` checks the base on demand (step 4b).
132
+ - `orq agent` returns immediately (no need to background it); the child's pane is in `<prefix>.pane`
133
+ (to peek: `<prefix>.log`; in herdr, `herdr pane read $(cat <prefix>.pane) --source recent`).
134
+ - **No baseline in the issue flow:** don't run `orq baseline` before dispatching (the base moves with every merge and
135
+ the full suite blocks every conductor's test queue). `orq verify` checks the base on demand (step 4b).
136
136
  - **Children start WITHOUT MCP** (Plane is yours; each MCP costs ~150–200 MB per session and `systemd-oomd` kills the
137
- whole herdr server when memory runs out) — `herdr-agent` takes care of it.
137
+ whole herdr server when memory runs out) — `orq agent` takes care of it.
138
138
  - Every child prompt ends with: "Don't try to talk to the conductor or use herdr; finish with your complete final
139
139
  answer (that is what I read)."
140
140
  - **Verification in the child: lint and tsc only, one command at a time** (the cap is 4 GB per agent and jest/vitest
141
141
  blow it; tests are yours, step 4b): use the Verification column of the workspace `CLAUDE.md` and put in the prompt
142
142
  "verify sequentially, never in parallel or watch mode: (1) lint only the changed files (`git diff --name-only
143
143
  origin/<BASE>...HEAD`); (2) `NODE_OPTIONS=--max-old-space-size=2048 tsc --noEmit` for the project. Don't run tests".
144
- Full suite only in CI (or a manual `herdr-baseline` if the user asks).
144
+ Full suite only in CI (or a manual `orq baseline` if the user asks).
145
145
  - An issue that changes an API contract: **API first**; consumers afterwards, with the new contract in the prompt.
146
146
  - **A red board line / `✗` pane title = a failure you may have missed.** If you see one (or the user says notices aren't
147
147
  arriving), run `orq notice` (delivery log) and `<prefix>.done` for that issue, then handle the failure; running
148
148
  `orq wait`, `orq verify` or `orq agent` for the issue acknowledges it.
149
149
  - **Never block waiting** (`herdr agent wait`, `pane wait-output`, `sleep`, `timeout`): completion arrives as a
150
- `[HERDR-AGENT DONE]` line in your pane. Dispatch, report in one line and end your turn. "Done yet?" = `<prefix>.done`
150
+ `[HERDR-AGENT DONE]` line in your pane (herdr) or through the background `orq wait`. Dispatch, report in one line and end your turn. "Done yet?" = `<prefix>.done`
151
151
  exists (never `pgrep`).
152
- - Investigation only (no code): "READ ONLY" prompt, in the repo itself, no worktree. `herdr-agent -r` (Claude:
152
+ - Investigation only (no code): "READ ONLY" prompt, in the repo itself, no worktree. `orq agent -r` (Claude:
153
153
  `--permission-mode plan`; the others: throwaway worktree, no editing).
154
154
 
155
155
  ## 4b. Tests (yours, not the child's)
156
156
  Child with `status=ok` → run the tests related to the diff, in their own tab, one at a time on the machine (queue):
157
- `herdr-verify -w $WS -r <repo> -d $WT -b <BASE> -o $O/verify-<repo> -g <group>` → `$O/verify-<repo>.txt` with
157
+ `orq verify -w $WS -r <repo> -d $WT -b <BASE> -o $O/verify-<repo> -g <group>` → `$O/verify-<repo>.txt` with
158
158
  **new failures** and pre-existing ones: if any test fails, it runs the same test files on an updated
159
- `origin/<BASE>` (whatever fails there is pre-existing). You get `[HERDR-AGENT DONE] verify ... new=N`.
159
+ `origin/<BASE>` (whatever fails there is pre-existing). You get the done line (`[HERDR-AGENT DONE]` / `[ORQ AGENT DONE]`) `verify ... new=N`.
160
160
  `new>0` → fix round with the list (step 6), no review. `new=0` → review.
161
161
  **Pre-existing failures get fixed too.** Any failure — tests listed as "already failing on origin/<BASE>", or a CI job
162
162
  (lint, biome, typecheck, shard, regression) failing on the PR or on the base — goes into a fix round on the issue's
@@ -165,12 +165,12 @@ something is red, new or old, and never widen a baseline or allowlist to silence
165
165
  outside the issue's domain: ask the user first (then it ships as its own PR, not as a note).
166
166
  **Mandatory order every round (impl and each fix): child `ok` → verify → review.** Never dispatch the review (or an
167
167
  "early" fix) while this round's verify is pending, even if it is queued behind another verify: wait for
168
- `[HERDR-AGENT DONE] ... verify ...` and end your turn until then.
168
+ the `... verify ...` done line and end your turn until then.
169
169
 
170
170
  ## 5. Cross review (always another vendor)
171
171
  ```bash
172
172
  orq pick review --level <level> --impl-agent <who implemented> > $O/review-<repo>.pick # round 2+ reuses it
173
- herdr-agent $(cat $O/review-<repo>.pick) -b $BASE \
173
+ orq agent $(cat $O/review-<repo>.pick) -b $BASE \
174
174
  -g <group> -t "<ID> review <repo>" -d $WT -o $O/review-<repo> -r -i $O/impl-<repo>.md -i $O/impl-<repo>.out.md \
175
175
  -i $O/verify-<repo>.txt \
176
176
  -- $O/review-<repo>.md
@@ -211,7 +211,7 @@ repo checklist.
211
211
  only restates a `## Decisions` choice, counts as a suggestion; when you downgrade one, say why in the Plane comment.
212
212
  No blockers left → APPROVED, even with suggestions.
213
213
  Blocking problems → write the list (blockers only) to `$O/fix-<n>.md` (always this name; reviews `$O/review-<repo>-<n>`, never `fix<n>-<repo>` or other variants — a later conductor counts rounds by these files) and continue the implementer's session (any agent):
214
- `herdr-agent $(orq pick fix --same $O/impl-<repo>.pick) -g <group> -t "<ID> fix<n> <repo>" -d $WT -o $O/impl-<repo> -R $(cat $O/impl-<repo>.id) -- $O/fix-<n>.md`.
214
+ `orq agent $(orq pick fix --same $O/impl-<repo>.pick) -g <group> -t "<ID> fix<n> <repo>" -d $WT -o $O/impl-<repo> -R $(cat $O/impl-<repo>.id) -- $O/fix-<n>.md`.
215
215
  A fix is a continuation: same agent, model, account and session, effort one level up (`--same` reads the implementer's
216
216
  pick; never a new `orq pick`, never `-a` alone — without `-m` the session resumes on the CLI's default model, which
217
217
  loses the prompt cache and hands the work to a weaker model). `fix-<n>.md` = the numbered blockers + these rules: "fix only
@@ -219,7 +219,7 @@ these items, with the smallest diff that does it; don't refactor, rename or refo
219
219
  each blocker add or adjust a test that fails without the fix, when the code is testable (say so when it isn't); if an
220
220
  item is wrong or conflicts with a criterion, don't fix it: say why"; and it ends with "update the `## Decisions`
221
221
  section of your final answer for the whole branch". **Before dispatching the fix:** `git -C $WT rev-parse HEAD > $O/round-<n>.sha`.
222
- Then a new `herdr-verify` (4b) and the **round review** (step 5 with these changes):
222
+ Then a new `orq verify` (4b) and the **round review** (step 5 with these changes):
223
223
  - Same reviewer as the round before: `$(cat $O/review-<repo>.pick)`. Only if it is over quota, blocked or fails with
224
224
  no verdict → a new `orq pick review` (saved to the same file).
225
225
  - Extra attachments: `git -C $WT diff $(cat $O/round-<n>.sha)..HEAD > $O/fix-<n>.diff` → `-i $O/fix-<n>.md -i $O/fix-<n>.diff`
@@ -258,9 +258,9 @@ rules live) commits and writes the PR. Find and cite in the prompt, by path, wha
258
258
  Red → `gh run view <id> --log-failed | tail -40`: error from the diff → fix round; error already on the base → create
259
259
  a Plane issue (workspace standard) and tell the user. "Ready to merge" only with green checks or an explained failure
260
260
  + issue.
261
- - Move it to **In Review** (finished child tabs close by themselves; close any leftover with
261
+ - Move it to **In Review** (finished child tabs close by themselves; in herdr, close any leftover with
262
262
  `herdr tab list | jq -r '.result.tabs[]|select(.label|startswith("<ID> "))|.tab_id' | xargs -rn1 herdr tab close`)
263
- and **release the issue**: `herdr-claim -w $WS -r <ID>`. The worktree stays until the merge.
263
+ and **release the issue**: `orq claim -w $WS -r <ID>`. The worktree stays until the merge.
264
264
  - **After the merge** (when the user confirms): run `orq gc -w $WS` and show the list. If this issue's worktree is
265
265
  listed as removable, run `orq gc -w $WS --yes`; anything else → ask the user.
266
266
  - **Never** push, PR, merge or deploy unless the user asks. Report to the user in 3–5 lines.
@@ -5,11 +5,12 @@ rules — read the repo's own before touching it. This file only holds the map a
5
5
 
6
6
  ## Orchestration (read by the `/issue` skill)
7
7
  - **Workspace:** `{{WORKSPACE}}`
8
- - **Conductor (herdr):** opened with `herdr-conductor [account] [model] [-r <session-id>]` in a herdr pane, in this folder
9
- (instructions in `.orquestra-conductor.md`); the **Group** in the table below is the herdr workspace (`-g`).
10
- Tests from the Verification column (jest/vitest) **don't run in the child**: the conductor runs `herdr-verify` (`orq verify`
11
- outside herdr; one at a time on the machine); the child does lint + `tsc` (`NODE_OPTIONS=--max-old-space-size=2048`).
12
- - **Agents:** chosen by `orq-pick` from each developer's `~/.config/orq/config.toml` — nothing about models here.
8
+ - **Conductor:** opened with `orq conductor [account] [model] [-r <session-id>]` in this folder, in any terminal (inside a
9
+ herdr pane too; `herdr-conductor` still works there). Instructions in `.orquestra-conductor.md`; the **Group** in the
10
+ table below is the herdr workspace (`-g`) or just a label outside herdr.
11
+ Tests from the Verification column (jest/vitest) **don't run in the child**: the conductor runs `orq verify`
12
+ (one at a time on the machine); the child does lint + `tsc` (`NODE_OPTIONS=--max-old-space-size=2048`).
13
+ - **Agents:** chosen by `orq pick` from each developer's `~/.config/orq/config.toml` — nothing about models here.
13
14
 
14
15
  ## Scope
15
16
  - Before dispatching, split big issues into sub-issues or sequential batches (one PR, one implementer each) when they touch