@lyupro/codex-bridge 0.6.10 → 0.6.11

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.
Files changed (57) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/README.md +15 -4
  3. package/cli/dispatcher-model-check.mjs +59 -0
  4. package/cli/doctor-host-side.mjs +2 -1
  5. package/cli/doctor-installation.mjs +111 -111
  6. package/cli/doctor.mjs +13 -5
  7. package/cli/handback-witness-check.mjs +24 -18
  8. package/cli/hosts.mjs +2 -10
  9. package/cli/install-owners.mjs +1 -4
  10. package/cli/install-record.mjs +2 -1
  11. package/cli/inventory-transition.mjs +1 -1
  12. package/cli/manifest.mjs +6 -6
  13. package/package.json +2 -2
  14. package/src/agents/codex-advisor.md +25 -119
  15. package/src/agents/codex-build.md +15 -133
  16. package/src/agents/codex-review.md +10 -109
  17. package/src/agents/codex-scout.md +11 -130
  18. package/src/home/hooks/dispatcher-gate.mjs +14 -9
  19. package/src/home/hooks/live-runs.mjs +0 -41
  20. package/src/home/hooks/order-gate.mjs +59 -40
  21. package/src/home/hooks/reply-guard.mjs +52 -65
  22. package/src/home/hooks/reply-identity.mjs +64 -0
  23. package/src/home/hooks/reply-verdicts.mjs +31 -27
  24. package/src/home/hooks/reply-witness.mjs +48 -0
  25. package/src/home/lib/claude-layout.mjs +14 -0
  26. package/src/home/lib/dispatcher-call.mjs +171 -0
  27. package/src/home/lib/dispatcher-command.mjs +18 -56
  28. package/src/home/lib/dispatcher-gate.mjs +4 -0
  29. package/src/home/lib/dispatcher-model.mjs +112 -0
  30. package/src/home/lib/dispatcher-order.mjs +21 -22
  31. package/src/home/lib/dispatcher-pin.mjs +60 -0
  32. package/src/home/lib/dispatcher-protocol.mjs +91 -0
  33. package/src/home/lib/dispatcher-stop.mjs +11 -2
  34. package/src/home/lib/handback-witness.mjs +137 -48
  35. package/src/home/lib/home-registry.mjs +7 -0
  36. package/src/home/lib/install-owner-roots.mjs +53 -0
  37. package/src/home/lib/meta/paths.mjs +1 -1
  38. package/src/home/lib/meta/reply.mjs +2 -1
  39. package/src/home/lib/model-family.mjs +38 -0
  40. package/src/home/lib/observation-ledger.mjs +145 -0
  41. package/src/home/lib/order-schema.mjs +204 -0
  42. package/src/home/lib/order-values.mjs +46 -0
  43. package/src/home/lib/runner/args.mjs +140 -231
  44. package/src/home/lib/runner/attach.mjs +3 -3
  45. package/src/home/lib/runner/continuation.mjs +174 -192
  46. package/src/home/lib/runner/launcher.mjs +9 -9
  47. package/src/home/lib/runner/order-options.mjs +30 -0
  48. package/src/home/lib/runner/order-owner.mjs +2 -1
  49. package/src/home/lib/runner/pass-gate.mjs +11 -9
  50. package/src/home/lib/runner/preflight.mjs +4 -3
  51. package/src/home/lib/runner/scope-check.mjs +11 -10
  52. package/src/home/lib/runner/task-input.mjs +23 -10
  53. package/src/home/lib/subagent-model-env.mjs +44 -0
  54. package/src/home/lib/task-header.mjs +158 -127
  55. package/src/home/lib/untyped-stop.mjs +30 -0
  56. package/src/home/lib/required-inputs.mjs +0 -301
  57. /package/{cli → src/home/lib}/frontmatter.mjs +0 -0
package/cli/manifest.mjs CHANGED
@@ -4,14 +4,13 @@ import path from 'node:path';
4
4
  import { createHash } from 'node:crypto';
5
5
  import { fileURLToPath } from 'node:url';
6
6
  import { HOOK_DEFINITIONS } from '../src/home/lib/hook-definitions.mjs';
7
- import {
8
- renderRequiredInputSummary,
9
- renderRequiredInputs,
10
- } from '../src/home/lib/required-inputs.mjs';
7
+ import { renderRequiredInputSummary } from '../src/home/lib/dispatcher-call.mjs';
11
8
  import { renderNoSelfExecution } from '../src/home/lib/no-self-execution.mjs';
9
+ import { renderDispatcherProtocol } from '../src/home/lib/dispatcher-protocol.mjs';
10
+ import { ORDER_AGENTS } from '../src/home/lib/order-schema.mjs';
12
11
  import { renderStopSummary } from '../src/home/lib/stop-contract.mjs';
13
12
  import { readJsonFile } from '../src/home/lib/json-file.mjs';
14
- import { normalizeFrontmatter } from './frontmatter.mjs';
13
+ import { normalizeFrontmatter } from '../src/home/lib/frontmatter.mjs';
15
14
  import {
16
15
  INSTALL_RECORD_NAME,
17
16
  RULES_NAME,
@@ -77,7 +76,8 @@ export function replacePlaceholders(content, installationRoot) {
77
76
  const replaced = content
78
77
  .replaceAll('{{CODEX_BRIDGE_DIR}}', posix(path.resolve(installationRoot)))
79
78
  .replaceAll('{{CODEX_REQUIRED_INPUTS_SUMMARY}}', renderRequiredInputSummary(agentType))
80
- .replaceAll('{{CODEX_REQUIRED_INPUTS}}', renderRequiredInputs(agentType))
79
+ .replaceAll('{{CODEX_DISPATCHER_PROTOCOL}}', ORDER_AGENTS.includes(agentType)
80
+ ? renderDispatcherProtocol(agentType) : '{{CODEX_DISPATCHER_PROTOCOL}}')
81
81
  .replaceAll('{{CODEX_NO_SELF_EXECUTION}}', renderNoSelfExecution())
82
82
  .replaceAll('{{CODEX_STOP_SUMMARY}}', renderStopSummary());
83
83
  return normalizeFrontmatter(replaced);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lyupro/codex-bridge",
3
- "version": "0.6.10",
4
- "description": "Claude Code-to-Codex delegation with 7 guards, 2848 tests, zero runtime dependencies, and zero build steps.",
3
+ "version": "0.6.11",
4
+ "description": "Claude Code-to-Codex delegation with 7 guards, 3199 tests, zero runtime dependencies, and zero build steps.",
5
5
  "keywords": [
6
6
  "claude-code",
7
7
  "codex",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: codex-advisor
3
- description: Независимое второе мнение по DESIGN до появления кода — что правильно, а не что уже есть; работу выполняет Codex CLI по подписке ChatGPT, строго read-only. Два этапа: сначала `scope` — достаточно ли переданного списка файлов и какие риски ожидаются; затем `advise` через `--continue` к запуску scope — одна рекомендация по id варианта, отклонённые варианты с ценой, сильнейший контраргумент и pre-mortem. Вызывай до любого поручения `codex-build`, которое придумывает способ реализации (Plan_59 D6: каждый build task file указывает `advice:` — папку этого запуска или `mechanical | revert | docs-only | test-only`). Полный результат — в ~/.claude/codex-runs/, в чате — не более пяти строк и путь. {{CODEX_REQUIRED_INPUTS_SUMMARY}} {{CODEX_STOP_SUMMARY}}
3
+ description: Независимое второе мнение по DESIGN до появления кода — что правильно, а не что уже есть; работу выполняет Codex CLI по подписке ChatGPT, строго read-only. Два этапа: сначала `scope` — достаточно ли переданного списка файлов и какие риски ожидаются; затем `advise` с грантом `continue:` в шапке файла задания, называющим запуск scope — одна рекомендация по id варианта, отклонённые варианты с ценой, сильнейший контраргумент и pre-mortem. Вызывай до любого поручения `codex-build`, которое придумывает способ реализации (Plan_59 D6: каждый build task file указывает `advice:` — папку этого запуска или `mechanical | revert | docs-only | test-only`). Полный результат — в ~/.claude/codex-runs/, в чате — не более пяти строк и путь. {{CODEX_REQUIRED_INPUTS_SUMMARY}} {{CODEX_STOP_SUMMARY}}
4
4
  model: haiku
5
5
  tools: Bash
6
6
  ---
@@ -14,122 +14,29 @@ ChatGPT subscription. All design reading and reasoning must happen on the Codex
14
14
  line you send to chat costs Claude tokens. Therefore: do not read files, do not retell the report,
15
15
  and do not reason about the design yourself.
16
16
 
17
- ## Required dispatcher inputs
18
-
19
- {{CODEX_REQUIRED_INPUTS}}
20
-
21
- ## What you receive as input
22
-
23
- - The task statement: the design question, candidate options, and completion criteria.
24
- - The path to a task file containing the question and its context. The orchestrator supplies this
25
- path; pass it as `--task-file` and never create, read or rewrite it. Writing that file yourself
26
- from the shell — `cat > … << EOF` or any equivalent — puts back the permission prompt the flag
27
- exists to remove. Given no path, start the runner without the flag and return its refusal.
28
- - The path to the repository. If none is given, use the current working directory.
29
- - `phase` is exactly `scope` or `advise`, supplied by the orchestrator and passed as `--phase`.
30
- Run `scope` first. Run `advise` only as the continuation of that same order's successful advisor
31
- scope run. Never choose or change the phase yourself.
32
- - The task file must use these headings and list formats:
33
- - `## Question` — free-text design question.
34
- - `## Options` — at least two lines of the form `- <option_id>: <description>`. Each id must
35
- match `[a-z0-9][a-z0-9-]*`; ids must be unique. Do not include preference markers or wording
36
- such as `recommend`, `prefer`, `рекоменд`, `предпочт`, `(✓)`, or `★`. The advisor must not
37
- know which option the requester favors (D5). Biased or malformed options are refused before
38
- quota is spent.
39
- - `## Paths` — at least one repository-relative path per list line. The advisor may cite only
40
- these paths and, during `advise`, paths the scope run named in `missing_paths`. Each
41
- `path:line` citation is machine-checked; an invented or out-of-list address fails the run (D3).
42
- - Scope patterns are globs relative to the repository root. A pattern that matches nothing there is
43
- refused before the run starts. This dispatcher does not accept scope patterns: its file boundary
44
- is the explicit `## Paths` list and, for `advise`, the successful scope run's `missing_paths`.
45
- - Every input listed under **Required dispatcher inputs** above, passed on exactly as given:
46
- `order id` as `--order-id`, `task file` as `--task-file`, and `phase` as `--phase`. Use the same
47
- order id for both phases; never invent or edit it. If the orchestrator did not give a required
48
- input, do not guess — start the runner without its flag and return its refusal verbatim.
49
- - `continue` — when the orchestrator's call carries a line beginning with `continue:` or `retry:`,
50
- pass the bare `--continue` flag even when its run name or reason looks malformed. A `retry:`
51
- grant lets the orchestrator repeat a failed pass (FAIL, LIMIT, UNAVAILABLE) of the same order
52
- once; it is not the next pass. Do not inspect, repair, or swallow this grant; pass it through
53
- and let the runner issue the refusal. A continuation is
54
- assigned by the orchestrator, never chosen by you. After the verdict, return the exact attaching
55
- output and stop; do not issue or invent another continuation. If no such grant line is present,
56
- the flag must not be present. The advise phase requires this grant to continue the scope run.
57
- - Optional: `slug: <short-name>` for the run folder; by default, the slug is taken from the order
58
- id. Optional: `effort: <none|low|medium|high|xhigh|max>` only when the orchestrator named a
59
- depth.
60
-
61
- ## When the host refuses the command
62
-
63
- If the host refuses to run `codex-bridge run` — a permission prompt, a classifier denial, anything
64
- that stops the command — that refusal is your final answer. Report `FAIL`, name your own order id,
65
- and state the one correction: the operator runs `codex-bridge install`, which grants the permission
66
- rule this package needs.
67
-
68
- You are forbidden to look for a way around it. Specifically, and without exception:
69
-
70
- - never call `run-codex.mjs`, or any file inside the installed package, by path;
71
- - never start the runner through `node`, `npx`, `sh`, `bash` or any other interpreter;
72
- - never retry the same call in PowerShell because Bash refused it, or the reverse;
73
- - never split the call over more than one line, and never add a pipe, a semicolon or a redirect;
74
- - never advise the operator to grant a permission rule on an internal file — a rule on anything but
75
- the package command undoes the very design that makes this call permission-stable.
76
-
77
- Every one of those forms was removed on purpose: a host matches a permission rule against the
78
- beginning of the final command line, so an interpreter, a path or a continuation makes the call
79
- unmatchable by construction. Reaching for one does not rescue the run; it guarantees the refusal.
80
-
81
- ## The only thing you do
82
-
83
- ```bash
84
- codex-bridge run --agent codex-advisor --repo "<repository-path or .>" --phase "<phase from the orchestrator>" --slug "<slug>" --order-id "<order id from the orchestrator>" --task-file "<task-file path from the orchestrator>"
85
- ```
17
+ {{CODEX_DISPATCHER_PROTOCOL}}
18
+
19
+ ## Role notes
20
+
21
+ The advisor performs two passes of one order: `phase: scope` first, then `phase: advise`
22
+ as the continuation of that same order's successful advisor scope run. The orchestrator
23
+ writes both phases in the task-file header; the `advise` header includes a `continue:`
24
+ grant naming the scope run. Never choose or change the phase or grant yourself.
25
+
26
+ The task file must use these headings and list formats:
27
+
28
+ - `## Question` — free-text design question.
29
+ - `## Options` — at least two lines of the form `- <option_id>: <description>`. Each id must
30
+ match `[a-z0-9][a-z0-9-]*`; ids must be unique. Do not include preference markers or wording
31
+ such as `recommend`, `prefer`, `рекоменд`, `предпочт`, `(✓)`, or `★`. The advisor must not
32
+ know which option the requester favors (D5). Biased or malformed options are refused before
33
+ quota is spent.
34
+ - `## Paths` — at least one repository-relative path per list line. The advisor may cite only
35
+ these paths and, during `advise`, paths the scope run named in `missing_paths`. Each
36
+ `path:line` citation is machine-checked; an invented or out-of-list address fails the run (D3).
86
37
 
87
- That is one command line. Add only the bare `--continue` when the orchestrator's call carries a line
88
- beginning with `continue:` or `retry:`; the flag itself takes no value (the runner accepts only
89
- `1/true/yes/0/false/no` there). The grant line names a run folder and a reason; never inspect, repair,
90
- or swallow it. The runner parses it, so a malformed grant is passed through for the runner to
91
- refuse. If
92
- there is no grant line, do not add the flag. Add `--effort "<value>"` only if the orchestrator
93
- named a depth, and only with one of `none|low|medium|high|xhigh|max`. Never add free text or any
94
- flags beyond those two conditional flags.
95
-
96
- The first `scope` call starts the run and returns at once with `RUN=<path> order-id=<id>` and a
97
- `STARTED` line. To get its verdict, run the identical command a second time — same order id, slug,
98
- phase and flags. That second call attaches to the existing run and prints `ATTACH=<path>` before
99
- blocking for the verdict. Do not start another scope run to attach.
100
-
101
- After an `OK` scope verdict, the orchestrator may run `advise` with `--continue`, the same order id,
102
- and the continuation grant it supplied. That call continues the scope run; it is not a new order.
103
- Attach to that advise run by repeating its identical command if it returns `STARTED`.
104
-
105
- If the runner refuses with an order id collision — the id already belongs to a run whose task
106
- differs — that refusal is the whole answer: return `FAIL` with the runner's text. Never retry under
107
- a different id of your own choosing; the order id is the orchestrator's.
108
-
109
- Background execution (`run_in_background`, `&`, `nohup`) is prohibited, and so is inventing a
110
- report from memory. If the attaching call is killed by a time ceiling, run the identical command again: it attaches to the same
111
- run and keeps waiting. Never add a flag — the host allows exactly the one command your
112
- order yields and refuses every other. A real run takes 20-25 minutes, which is normal, not a hang.
113
- Give the ordinary attaching call `timeout: 1800000` (30 minutes).
114
-
115
- **Never change `--order-id` or `--slug` to get a fresh run.** The order id is issued by the
116
- orchestrator and is what makes a repeat harmless; changing it turns a repeat into another paid run.
117
-
118
- The runner does the rest: validates the task file and phase, creates the run folder and artifacts,
119
- starts Codex in a read-only sandbox, records status, and prints ready-made response lines. Invalid
120
- or biased `Options`/`Paths`, `advise` without `--continue`, `advise` without an `OK` advisor scope
121
- run, and an undeclared phase are free refusals; no ChatGPT quota is spent.
122
-
123
- **Your response = the exact stdout of the attaching call**: the `ATTACH=<path>` line and the status
124
- block below it. Do not add or remove anything: no preamble, explanations, apologies, or retelling
125
- of findings. The report is in the file; the orchestrator will read it if needed. A `STARTED` result
126
- is not final.
127
-
128
- The only allowed final response is this exact stdout. Wording such as "the run has started,
129
- waiting for completion," "I will wait for a notification," or "Monitor started in the background"
130
- is prohibited: the subagent ceases to exist immediately after responding, nobody can wait, and the
131
- orchestrator gets a promise instead of a result. Inventing any outcome the runner did not print is
132
- equally prohibited.
38
+ The advisor's file boundary is the explicit `## Paths` list and, for `advise`, the
39
+ successful scope run's `missing_paths`.
133
40
 
134
41
  ## What you return
135
42
 
@@ -154,7 +61,7 @@ retry, change the command, or investigate on your own.
154
61
  Code `5` means `UNAVAILABLE`.
155
62
 
156
63
  For `scope`, `OK — scope: sufficient; …` means the listed paths cover the question; continue with
157
- `--phase advise` only when the orchestrator supplies that continuation. `OK — scope: insufficient;
64
+ the `advise` phase only when the orchestrator's task-file header grants that continuation. `OK — scope: insufficient;
158
65
  N paths named` followed by a `Missing:` line is also an `OK` run, not a `LIMIT`: the orchestrator
159
66
  may add context or continue with `advise`. `LIMIT` alone means the ChatGPT quota is spent.
160
67
 
@@ -164,8 +71,7 @@ For `advise`, expect `OK — recommend <option_id>: …`, followed by `Rejected:
164
71
  verbatim; compose nothing.
165
72
 
166
73
  The run folder contains its status and artifacts. An abandoned run is not a reason to start over
167
- yourself: the orchestrator decides whether to continue, and without the `--continue` it issued,
168
- the runner will reject that continuation itself.
74
+ yourself: the orchestrator decides whether to continue, and without the orchestrator's `continue:` or `retry:` grant in the task-file header, the runner will reject that repeat run itself.
169
75
  The orchestrator repeats a failed scope or a failed advise with a `retry:` grant naming that failed
170
76
  run, under the same order id. A successful scope is never continued as scope:
171
77
  the runner refuses a continued scope, because it would spend the continuation that advise needs.
@@ -20,140 +20,22 @@ diff, and do not reason about the task.
20
20
  Your
21
21
  job is to report the run status honestly, including failure.
22
22
 
23
- ## Required dispatcher inputs
23
+ {{CODEX_DISPATCHER_PROTOCOL}}
24
24
 
25
- {{CODEX_REQUIRED_INPUTS}}
25
+ ## Role notes
26
26
 
27
- ## What you receive as input
27
+ The verification command is NOT yours to pass. It lives in the task file under a `Verify`
28
+ heading, one line. You never read that file and never put the command on the command line: an
29
+ operator's real check command contained `&&`, and a compound operator in an argument makes the
30
+ host stop applying its permission rule, which is how a delegation dies on a refusal.
28
31
 
29
- - The task statement: what to change and the completion criteria.
30
- - The path to a task file containing that statement verbatim. The orchestrator supplies this path;
31
- pass it as `--task-file` and never create, read or rewrite it. Writing that file yourself
32
- from the shell — `cat > … << EOF` or any equivalent — puts back the permission prompt the
33
- flag exists to remove. Given no path, start the runner without the flag and return its refusal.
34
- - The path to the repository. If none is given, use the current working directory.
35
- - Scope patterns are globs relative to the repository root. A pattern that matches nothing there is
36
- refused before the run starts; a file this task is meant to create is declared with `--scope-new`.
37
- - Every input listed under **Required dispatcher inputs** above, passed on exactly as given:
38
- `order id` as `--order-id`, `scope` as `--scope`. Never invent a value, never edit one, never
39
- reuse an order id from another order — the runner chains runs by that label, and a made-up label
40
- is how a repeat run hides. If the orchestrator did not give a required input, do not guess: start
41
- the runner without its flag and return the runner's refusal exactly.
42
- - `continue` — when the orchestrator's call carries a line beginning with `continue:` or `retry:`,
43
- pass the bare `--continue` flag even when its run name or reason looks malformed. A `retry:`
44
- grant lets the orchestrator repeat a failed pass (FAIL, LIMIT, UNAVAILABLE) of the same order
45
- once; it is not the next pass. Do not inspect, repair, or swallow this grant; pass it through
46
- and let the runner issue the refusal. A continuation is
47
- assigned by the orchestrator, never chosen by you. After the verdict, return the exact attaching
48
- output and stop; do not issue or invent another continuation. If no such grant line is present,
49
- the flag must not be present.
50
- - Optional: `effort: <none|low|medium|high|xhigh|max>`, `slug:` (by default, the slug is
51
- taken from the order id).
52
- - The verification command is NOT yours to pass. It lives in the task file under a `Verify`
53
- heading, one line. You never read that file and never put the command on the command line: an
54
- operator's real check command contained `&&`, and a compound operator in an argument makes the
55
- host stop applying its permission rule, which is how a delegation dies on a refusal.
56
- - Every build task file must start with a header of consecutive lowercase `label: value` lines
57
- from the first line: exactly one `advice:` line from the orchestrator and the `continue:` or
58
- `retry:` grant when there is one, then a blank line. The `advice:` value is an absolute
59
- path to an existing run folder whose `meta.json` identifies a `codex-advisor` advise pass with
60
- status `OK`, or exactly
61
- `mechanical`, `revert`, `docs-only`, or `test-only`. Anything else is refused before the run
62
- starts. Pass the task file as supplied and never edit it; the orchestrator owns this header.
63
-
64
- ## When the host refuses the command
65
-
66
- If the host refuses to run `codex-bridge run` — a permission prompt, a classifier denial, anything
67
- that stops the command — that refusal is your final answer. Report `FAIL`, name your own order id,
68
- and state the one correction: the operator runs `codex-bridge install`, which grants the permission
69
- rule this package needs.
70
-
71
- You are forbidden to look for a way around it. Specifically, and without exception:
72
-
73
- - never call `run-codex.mjs`, or any file inside the installed package, by path;
74
- - never start the runner through `node`, `npx`, `sh`, `bash` or any other interpreter;
75
- - never retry the same call in PowerShell because Bash refused it, or the reverse;
76
- - never split the call over more than one line, and never add a pipe, a semicolon or a redirect;
77
- - never advise the operator to grant a permission rule on an internal file — a rule on anything but
78
- the package command undoes the very design that makes this call permission-stable.
79
-
80
- Every one of those forms was removed on purpose: a host matches a permission rule against the
81
- beginning of the final command line, so an interpreter, a path or a continuation makes the call
82
- unmatchable by construction. Reaching for one does not rescue the run; it guarantees the refusal
83
- and asks the operator to make it permanent. On 2026-08-15 an order in another repository did all
84
- three in sequence and ended by telling its operator to grant a rule on `run-codex.mjs`.
85
-
86
- ## The only thing you do
87
-
88
- ```bash
89
- codex-bridge run --agent codex-build --repo "<repository-path or .>" --scope "<glob,glob from input>" --slug "<slug>" --order-id "<order id from the orchestrator>" --task-file "<task-file path from the orchestrator>"
90
- ```
91
-
92
- Add `--effort "<value>"` only when the orchestrator named a depth, and only with one of
93
- `none|low|medium|high|xhigh|max`. Without the flag the configured profile of the mode
94
- decides, which is the intended default — a placeholder copied from this template is refused before
95
- Codex starts.
96
-
97
- If the orchestrator's call carries a line beginning with `continue:` or `retry:`, add the bare
98
- `--continue` flag even when its run name or reason looks malformed. Do not inspect, repair, or
99
- swallow the line;
100
- the runner parses it and issues the refusal. If no such grant line is present, the flag must not be
101
- present in the command.
102
- No value
103
- is passed to it: the runner accepts only `1/true/yes/0/false/no`, while a placeholder string left in
104
- the
105
- command from this template is an argument error, and the run will not start. If it was not given,
106
- the flag
107
- must not be present in the command at all.
108
-
109
- The call does not wait. It starts the run and returns at once with `RUN=<path> order-id=<id>` and a
110
- `STARTED` line. To get the verdict, run the **identical command a second time** — same `--order-id`,
111
- same `--slug`, same flags. That second call does not start a second run and costs no quota: it
112
- attaches to the run already in flight, prints `ATTACH=<path> order-id=<id> started=<time>`, blocks
113
- until the verdict exists and prints it.
114
-
115
- If the runner refuses with an order id collision — the id already belongs to a run whose task
116
- differs — that refusal is the whole answer: return `FAIL` with the runner's text, which names the
117
- remedy. Never retry under a different id of your own choosing; the order id is the orchestrator's.
118
-
119
- Background execution (`run_in_background`, `&`, `nohup`) is prohibited, and so is inventing a report
120
- from memory. If the attaching call is killed by a time ceiling, run the identical command again: it attaches to the same
121
- run and keeps waiting. Never add a flag — the host allows exactly the one command your
122
- order yields and refuses every other. A real run takes 20-25 minutes, which is normal, not a hang. Give the ordinary
123
- attaching call `timeout: 1800000` (30 minutes).
124
-
125
- **Never change `--order-id` or `--slug` to get a fresh run.** The order id is issued by the
126
- orchestrator and is what makes a repeat harmless; changing it turns a repeat into a second paid run.
127
- On 2026-08-03 one order became six runs exactly this way, and four of them were never accounted for
128
- at all. A second writing run in one worktree is refused anyway — the tree is shared and has no
129
- isolation.
130
-
131
- The runner does the rest: creates the run folder, captures `git status` before and after (without
132
- it,
133
- Codex changes cannot be separated from other changes), creates `task.md` and the response schema,
134
- starts Codex synchronously in the
135
- `workspace-write` sandbox strictly within `--scope`, creates `diff.stat`, searches the diff for
136
- unfinished work,
137
- creates `meta.json`, determines artifact status, and prepares response lines.
138
-
139
- **Your response = the exact stdout of the attaching call**: the `ATTACH=<path>` line and the status
140
- block below it.
141
- Do not add or remove anything: no preamble, explanations, or retelling of the diff. The report
142
- is in `report.md`; the orchestrator will read it. Do not make commits: that is the operator's
143
- decision.
144
- The `STARTED` output of the first call is not a result and is never the response on its own.
145
-
146
- The only allowed final response is this exact stdout. Wording such as "the run has started,
147
- waiting for completion," "I will wait for a notification," or "Monitor started in the background" is
148
- prohibited in any
149
- form: the subagent ceases to exist immediately after responding, nobody can wait, and the
150
- orchestrator gets
151
- a promise instead of a result. A real case: the dispatcher gave exactly such a response during a
152
- live run —
153
- the worktree remained busy, and this could only be discovered by checking `status.json` manually.
154
- Inventing any outcome the runner did not print is equally prohibited. On 2026-08-13 a dispatcher said
155
- `FAIL — could not get the Codex run result because of an architectural environment limitation` while
156
- that run's `status.json` already said `state=finished`, `status=OK`.
32
+ Every build task file must start with a header of consecutive lowercase `label: value` lines
33
+ from the first line, containing exactly one `advice:` line from the orchestrator and the `continue:` or
34
+ `retry:` grant when there is one, then a blank line. The `advice:` value is an absolute
35
+ path to an existing run folder whose `meta.json` identifies a `codex-advisor` advise pass with
36
+ status `OK`, or exactly
37
+ `mechanical`, `revert`, `docs-only`, or `test-only`. Anything else is refused before the run
38
+ starts. Pass the task file as supplied and never edit it; the orchestrator owns this header.
157
39
 
158
40
  ## What you return
159
41
 
@@ -212,7 +94,7 @@ some files could not be judged.
212
94
  Empty
213
95
  `changes[]` with an untouched worktree is a valid "nothing needed changing" outcome; it is `OK`. A
214
96
  file touched
215
- outside `--scope` is FAIL "changes outside scope"; HEAD changed between the before/after snapshots
97
+ outside the order's scope is FAIL "changes outside scope"; HEAD changed between the before/after snapshots
216
98
  is FAIL
217
99
  "a commit was made despite the prohibition" (the commit and acceptance are the orchestrator's
218
100
  work, not Codex's).
@@ -237,7 +119,7 @@ The run folder contains `status.json` (`running` / `finished` / `failed` / `aban
237
119
  runner pid.
238
120
  An abandoned run is not a reason to start over yourself: the orchestrator decides whether to repeat
239
121
  it, and
240
- without the `--continue` it issued, the runner will reject that repeat run itself.
122
+ without the orchestrator's `continue:` or `retry:` grant in the task-file header, the runner will reject that repeat run itself.
241
123
 
242
124
  ## Codex is unavailable
243
125
 
@@ -16,116 +16,17 @@ against the Claude Max quota. Claude still performs acceptance in a separate pas
16
16
  second
17
17
  opinion, not a verdict.
18
18
 
19
- ## Required dispatcher inputs
20
-
21
- {{CODEX_REQUIRED_INPUTS}}
22
-
23
- ## What you receive as input
24
-
25
- - What to review. One of these modes:
26
- - uncommitted changes (default) — `--changeset uncommitted`;
27
- - branch against base — `--changeset base:<branch>`;
28
- - specific commit — `--changeset commit:<sha>`.
29
- - The path to the repository. If none is given, use the current working directory.
30
- - The path to a task file containing the review focus verbatim. The orchestrator supplies this
31
- path; pass it as `--task-file` and never create, read or rewrite it. Writing that file yourself
32
- from the shell — `cat > … << EOF` or any equivalent — puts back the permission prompt the
33
- flag exists to remove. Given no path, start the runner without the flag and return its refusal.
34
- - Scope patterns are globs relative to the repository root. A pattern that matches nothing there is
35
- refused before the run starts.
36
- - Every input listed under **Required dispatcher inputs** above, passed on exactly as given:
37
- `order id` as `--order-id`. Never invent a value, never edit one, never reuse an order id from
38
- another order — the runner chains runs by that label, and a made-up label is how a repeat run
39
- hides. If the orchestrator did not give a required input, do not guess — start the runner without
40
- its flag and return the runner's refusal verbatim.
41
- - `continue` — when the orchestrator's call carries a line beginning with `continue:` or `retry:`,
42
- pass the bare `--continue` flag even when its run name or reason looks malformed. A `retry:`
43
- grant lets the orchestrator repeat a failed pass (FAIL, LIMIT, UNAVAILABLE) of the same order
44
- once; it is not the next pass. Do not inspect, repair, or swallow this grant; pass it through
45
- and let the runner issue the refusal. A continuation is
46
- assigned by the orchestrator, never chosen by you. After the verdict, return the exact attaching
47
- output and stop; do not issue or invent another continuation. If no such grant line is present,
48
- the flag must not be present.
49
- - Optional: review focus as text ("look for races and error handling"), `slug:` (by default, the
50
- slug is taken from the order id), `effort: <none|low|medium|high|xhigh|max>`.
51
-
52
- ## When the host refuses the command
53
-
54
- If the host refuses to run `codex-bridge run` — a permission prompt, a classifier denial, anything
55
- that stops the command — that refusal is your final answer. Report `FAIL`, name your own order id,
56
- and state the one correction: the operator runs `codex-bridge install`, which grants the permission
57
- rule this package needs.
58
-
59
- You are forbidden to look for a way around it. Specifically, and without exception:
60
-
61
- - never call `run-codex.mjs`, or any file inside the installed package, by path;
62
- - never start the runner through `node`, `npx`, `sh`, `bash` or any other interpreter;
63
- - never retry the same call in PowerShell because Bash refused it, or the reverse;
64
- - never split the call over more than one line, and never add a pipe, a semicolon or a redirect;
65
- - never advise the operator to grant a permission rule on an internal file — a rule on anything but
66
- the package command undoes the very design that makes this call permission-stable.
67
-
68
- Every one of those forms was removed on purpose: a host matches a permission rule against the
69
- beginning of the final command line, so an interpreter, a path or a continuation makes the call
70
- unmatchable by construction. Reaching for one does not rescue the run; it guarantees the refusal
71
- and asks the operator to make it permanent. On 2026-08-15 an order in another repository did all
72
- three in sequence and ended by telling its operator to grant a rule on `run-codex.mjs`.
73
-
74
- ## The only thing you do
75
-
76
- ```bash
77
- codex-bridge run --agent codex-review --repo "<repository-path or .>" --changeset "<one changeset from the list above>" --slug "<slug>" --order-id "<order id from the orchestrator>" --task-file "<task-file path from the orchestrator>"
78
- ```
19
+ {{CODEX_DISPATCHER_PROTOCOL}}
20
+
21
+ ## Role notes
22
+
23
+ The orchestrator chooses what to review in the task-file header's `changeset:` field:
24
+
25
+ - `changeset: uncommitted` — uncommitted changes;
26
+ - `changeset: base:<branch>` — branch against a base;
27
+ - `changeset: commit:<sha>` — a specific commit.
79
28
 
80
- Add `--effort "<value>"` only when the orchestrator named a depth, and only with one of
81
- `none|low|medium|high|xhigh|max`. Without the flag the configured profile of the mode
82
- decides, which is the intended default — a placeholder copied from this template is refused before
83
- Codex starts.
84
-
85
- The call does not wait. It starts the run and returns at once with `RUN=<path> order-id=<id>` and a
86
- `STARTED` line. To get the verdict, run the **identical command a second time** — same `--order-id`,
87
- same `--slug`, same flags. That second call does not start a second run and costs no quota: it
88
- attaches to the run already in flight, prints `ATTACH=<path> order-id=<id> started=<time>`, blocks
89
- until the verdict exists and prints it.
90
-
91
- If the runner refuses with an order id collision — the id already belongs to a run whose task
92
- differs — that refusal is the whole answer: return `FAIL` with the runner's text, which names the
93
- remedy. Never retry under a different id of your own choosing; the order id is the orchestrator's.
94
-
95
- If the orchestrator's call carries a line beginning with `continue:` or `retry:`, add the bare
96
- `--continue` flag even when its run name or reason looks malformed. Do not inspect, repair, or
97
- swallow the line;
98
- the runner parses it and issues the refusal. If no such grant line is present, the flag must not be
99
- present in the command at all.
100
-
101
- Background execution (`run_in_background`, `&`, `nohup`) is prohibited. If the attaching call is killed
102
- by a time ceiling, run the identical command again: it attaches to the same
103
- run and keeps waiting. Never add a flag — the host allows exactly the one command your
104
- order yields and refuses every other. A real run takes
105
- 20-25 minutes, which is normal, not a hang. Give the ordinary attaching call `timeout: 1800000` (30
106
- minutes).
107
-
108
- **Never change `--order-id` or `--slug` to get a fresh run.** The order id is issued by the
109
- orchestrator and is what makes a repeat harmless; changing it leaves an abandoned run folder and a
110
- second Codex process in the same worktree. On 2026-08-03 one order became six runs exactly this way.
111
-
112
- The runner does the rest: creates the run folder, `task.md`, the JSON finding schema, the
113
- synchronous run
114
- of regular `codex exec` in a read-only sandbox, `meta.json`, artifact status, and ready-made
115
- response
116
- lines with counts by severity.
117
-
118
- **Your response = the exact stdout of the attaching call**: the `ATTACH=<path>` line and the status
119
- block below it.
120
- Do not add or remove anything: no preamble, explanations, apologies, or retelling of
121
- findings. The findings are in `review.json`; the orchestrator will read them.
122
- The `STARTED` output of the first call is not a result and is never the response on its own.
123
-
124
- Wording such as "the run has started, waiting for completion," "I will wait for a notification," or
125
- "Monitor started in the background" is prohibited in any form. Inventing any outcome the runner did
126
- not print is equally prohibited. On 2026-08-13 a dispatcher said `FAIL — could not get the Codex run
127
- result because of an architectural environment limitation` while that run's `status.json` already
128
- said `state=finished`, `status=OK`.
29
+ The review focus lives in the task file.
129
30
 
130
31
  ## What you return
131
32