oh-my-opencode 4.18.2 → 4.19.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.
Files changed (164) hide show
  1. package/README.ja.md +2 -2
  2. package/README.ko.md +2 -2
  3. package/README.md +4 -4
  4. package/README.ru.md +2 -2
  5. package/README.zh-cn.md +2 -2
  6. package/dist/agents/atlas/agent.d.ts +6 -5
  7. package/dist/agents/sisyphus/index.d.ts +5 -0
  8. package/dist/agents/sisyphus/kimi-k3.d.ts +19 -0
  9. package/dist/agents/sisyphus-agent-factory.d.ts +1 -1
  10. package/dist/agents/sisyphus-junior/agent.d.ts +8 -4
  11. package/dist/agents/sisyphus-junior/index.d.ts +2 -0
  12. package/dist/agents/sisyphus-junior/kimi-k3.d.ts +12 -0
  13. package/dist/agents/types.d.ts +2 -2
  14. package/dist/cli/index.js +648 -136
  15. package/dist/cli-node/index.js +648 -136
  16. package/dist/config/index.d.ts +1 -1
  17. package/dist/config/schema/browser-automation.d.ts +1 -0
  18. package/dist/config/schema/commands.d.ts +1 -3
  19. package/dist/config/schema/default-mode.d.ts +1 -1
  20. package/dist/config/schema/goal.d.ts +7 -0
  21. package/dist/config/schema/hooks.d.ts +1 -1
  22. package/dist/config/schema/oh-my-opencode-config.d.ts +6 -10
  23. package/dist/config/schema/ralph-loop.d.ts +1 -1
  24. package/dist/config/schema.d.ts +1 -1
  25. package/dist/create-hooks.d.ts +1 -1
  26. package/dist/features/builtin-commands/templates/goal.d.ts +1 -0
  27. package/dist/features/builtin-commands/templates/stop-continuation.d.ts +1 -1
  28. package/dist/features/builtin-commands/types.d.ts +1 -1
  29. package/dist/hooks/auto-slash-command/executor.d.ts +1 -0
  30. package/dist/hooks/goal/command-arguments.d.ts +13 -0
  31. package/dist/hooks/goal/controller.d.ts +26 -0
  32. package/dist/hooks/goal/index.d.ts +23 -0
  33. package/dist/hooks/goal/prompt.d.ts +3 -0
  34. package/dist/hooks/goal/store.d.ts +8 -0
  35. package/dist/hooks/goal/tools.d.ts +10 -0
  36. package/dist/hooks/goal/types.d.ts +93 -0
  37. package/dist/hooks/goal/validation.d.ts +4 -0
  38. package/dist/hooks/index.d.ts +1 -0
  39. package/dist/hooks/keyword-detector/hook.d.ts +1 -2
  40. package/dist/hooks/ralph-loop/types.d.ts +1 -1
  41. package/dist/index.js +3515 -4365
  42. package/dist/oh-my-opencode.schema.json +23 -19
  43. package/dist/plugin/chat-message/loop-commands.d.ts +1 -1
  44. package/dist/plugin/chat-message/types.d.ts +23 -10
  45. package/dist/plugin/hooks/create-core-hooks.d.ts +1 -1
  46. package/dist/plugin/hooks/create-session-hooks.d.ts +3 -2
  47. package/dist/plugin/hooks/create-transform-hooks.d.ts +0 -2
  48. package/dist/plugin/stop-continuation.d.ts +2 -2
  49. package/dist/shared/system-directive.d.ts +0 -1
  50. package/dist/skills/ulw-plan/SKILL.md +11 -7
  51. package/dist/skills/ulw-plan/references/full-workflow.md +117 -6
  52. package/dist/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  53. package/dist/skills/ulw-research/SKILL.md +3 -3
  54. package/dist/tools/delegate-task/types.d.ts +0 -1
  55. package/dist/tui.js +73 -25
  56. package/package.json +14 -14
  57. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  58. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +352 -17
  59. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  60. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  61. package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +7 -6
  62. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +97 -30
  63. package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
  64. package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +1 -1
  65. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  66. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  67. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  68. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  69. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  70. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  71. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +1 -0
  72. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
  73. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  74. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  75. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  76. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  77. package/packages/omo-codex/plugin/components/start-work-continuation/AGENTS.md +8 -0
  78. package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.js +147 -60
  79. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
  80. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  81. package/packages/omo-codex/plugin/components/start-work-continuation/src/boulder-reader.ts +3 -71
  82. package/packages/omo-codex/plugin/components/start-work-continuation/src/plan-checklist.ts +171 -0
  83. package/packages/omo-codex/plugin/components/start-work-continuation/test/boulder-reader.test.ts +198 -23
  84. package/packages/omo-codex/plugin/components/start-work-continuation/test/cli.test.ts +4 -3
  85. package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +6 -5
  86. package/packages/omo-codex/plugin/components/start-work-continuation/test/fixtures/plan-scaffold.md +15 -0
  87. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  88. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  89. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  90. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  91. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +10 -10
  92. package/packages/omo-codex/plugin/components/ultrawork/agents/momus.toml +3 -3
  93. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  94. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  95. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +11 -7
  96. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +117 -6
  97. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  98. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  99. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  100. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  101. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  102. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  103. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  104. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  105. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  106. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  107. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  108. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  109. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  110. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  111. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  112. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  113. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  114. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  115. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  116. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
  117. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  118. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
  119. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  120. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  121. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  122. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  123. package/packages/omo-codex/plugin/package-lock.json +13 -13
  124. package/packages/omo-codex/plugin/package.json +1 -1
  125. package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +32 -28
  126. package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +17 -45
  127. package/packages/omo-codex/plugin/scripts/migrate-codex-config/toml-section-editor.mjs +455 -0
  128. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +3 -18
  129. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +11 -7
  130. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +117 -6
  131. package/packages/omo-codex/plugin/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  132. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +2 -2
  133. package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +2 -2
  134. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +6 -6
  135. package/packages/omo-codex/plugin/test/multi-agent-v2-regression.test.mjs +3 -3
  136. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +62 -0
  137. package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +271 -14
  138. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +3 -18
  139. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +0 -5
  140. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +293 -0
  141. package/packages/omo-codex/scripts/install-config.test.mjs +10 -10
  142. package/packages/omo-codex/scripts/install-dist/install-local.mjs +353 -18
  143. package/packages/omo-codex/scripts/install-generated-bundle.test.mjs +39 -2
  144. package/packages/shared-skills/skills/ulw-plan/SKILL.md +11 -7
  145. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +117 -6
  146. package/packages/shared-skills/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  147. package/packages/shared-skills/skills/ulw-research/SKILL.md +3 -3
  148. package/dist/features/builtin-commands/templates/ralph-loop.d.ts +0 -3
  149. package/dist/skills/ultraresearch/SKILL.md +0 -10
  150. package/packages/shared-skills/skills/lcx-contribute-bug-fix/SKILL.md +0 -273
  151. package/packages/shared-skills/skills/lcx-contribute-bug-fix/agents/openai.yaml +0 -12
  152. package/packages/shared-skills/skills/lcx-contribute-bug-fix/scripts/create-pr-body.mjs +0 -107
  153. package/packages/shared-skills/skills/lcx-doctor/SKILL.md +0 -128
  154. package/packages/shared-skills/skills/lcx-doctor/agents/openai.yaml +0 -11
  155. package/packages/shared-skills/skills/lcx-report-bug/SKILL.md +0 -268
  156. package/packages/shared-skills/skills/lcx-report-bug/agents/openai.yaml +0 -11
  157. package/packages/shared-skills/skills/ultraresearch/SKILL.md +0 -10
  158. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/SKILL.md +0 -0
  159. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/agents/openai.yaml +0 -0
  160. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/scripts/create-pr-body.mjs +0 -0
  161. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-doctor/SKILL.md +0 -0
  162. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-doctor/agents/openai.yaml +0 -0
  163. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-report-bug/SKILL.md +0 -0
  164. /package/{dist → packages/omo-codex/plugin/components/lcx}/skills/lcx-report-bug/agents/openai.yaml +0 -0
@@ -0,0 +1,293 @@
1
+ import assert from "node:assert/strict";
2
+ import { readFile } from "node:fs/promises";
3
+ import { dirname, join } from "node:path";
4
+ import test from "node:test";
5
+ import { fileURLToPath } from "node:url";
6
+
7
+ const pluginRoot = dirname(dirname(fileURLToPath(import.meta.url)));
8
+ const repositoryRoot = dirname(dirname(dirname(pluginRoot)));
9
+
10
+ const surfaces = [
11
+ {
12
+ name: "shared OpenCode",
13
+ skillPath: join(repositoryRoot, "packages", "shared-skills", "skills", "ulw-plan", "SKILL.md"),
14
+ workflowPath: join(repositoryRoot, "packages", "shared-skills", "skills", "ulw-plan", "references", "full-workflow.md"),
15
+ independentReviewer: "oracle",
16
+ reviewRoots: {
17
+ momus: "<literal-canonical-source-workspace-root>",
18
+ independent: "<literal-canonical-source-workspace-root>",
19
+ },
20
+ runtimeHomes: { momus: null, independent: null },
21
+ },
22
+ {
23
+ name: "Codex",
24
+ skillPath: join(pluginRoot, "components", "ultrawork", "skills", "ulw-plan", "SKILL.md"),
25
+ workflowPath: join(pluginRoot, "components", "ultrawork", "skills", "ulw-plan", "references", "full-workflow.md"),
26
+ independentReviewer: "codex-cli:gpt-5.6-sol:xhigh",
27
+ reviewRoots: {
28
+ momus: "<literal-canonical-source-workspace-root>",
29
+ independent: "<literal-canonical-disposable-review-workspace-root>",
30
+ },
31
+ runtimeHomes: { momus: null, independent: "<literal-isolated-codex-home>" },
32
+ },
33
+ ];
34
+
35
+ function readJsonContract(workflow, contractName) {
36
+ const fence = "```";
37
+ const pattern = new RegExp(`<!-- ${contractName} -->\\s*${fence}json\\s*([\\s\\S]*?)\\s*${fence}`);
38
+ const match = workflow.match(pattern);
39
+ assert.ok(match, `missing ${contractName}`);
40
+ return JSON.parse(match[1]);
41
+ }
42
+
43
+ function matchesCas(state, expected, clauses) {
44
+ return clauses.every((clause) => {
45
+ const separator = clause.indexOf("=");
46
+ if (separator !== -1) {
47
+ const key = clause.slice(0, separator);
48
+ const value = clause.slice(separator + 1);
49
+ return state[key] === value;
50
+ }
51
+ return Object.hasOwn(expected, clause) && state[clause] === expected[clause];
52
+ });
53
+ }
54
+
55
+ for (const surface of surfaces) {
56
+ test(`#given ${surface.name} #when deeper review becomes required before plan completion #then durable request state covers explicit and automatic review without inventing a digest`, async () => {
57
+ const skill = await readFile(surface.skillPath, "utf8");
58
+ const workflow = await readFile(surface.workflowPath, "utf8");
59
+ const contract = readJsonContract(workflow, "ulw-plan-review-request-state-contract");
60
+
61
+ assert.equal(contract.transition, "replace");
62
+ assert.equal(contract.phase, "review_requested");
63
+ assert.deepEqual(contract.applies_when, ["explicit_review_modifier_before_complete_plan", "intent=unclear_and_nontrivial"]);
64
+ assert.match(skill, /Include `--review-required`[\s\S]{0,180}non-Trivial UNCLEAR/);
65
+ assert.match(workflow, /--draft-only/);
66
+ assert.equal(contract.atomic, true);
67
+ assert.equal(contract.review_required, true);
68
+ assert.equal(contract.plan_path, ".omo/plans/<slug>.md");
69
+ assert.equal(contract.plan_sha256, null);
70
+ assert.equal(contract.review_round_id, null);
71
+ assert.deepEqual(contract.pending_action_policy, {
72
+ review_required: "write and review .omo/plans/<slug>.md",
73
+ otherwise: "write .omo/plans/<slug>.md",
74
+ });
75
+ assert.equal(contract["pending-action"], contract.pending_action_policy.review_required);
76
+ assert.deepEqual(Object.keys(contract.review).sort(), ["independent", "momus"]);
77
+
78
+ for (const lane of Object.values(contract.review)) {
79
+ assert.deepEqual(lane, {
80
+ status: "pending",
81
+ workspace_root: null,
82
+ runtime_home: null,
83
+ target: ".omo/plans/<slug>.md",
84
+ round_id: null,
85
+ plan_sha256: null,
86
+ launch_id: null,
87
+ session: null,
88
+ result: null,
89
+ });
90
+ }
91
+ });
92
+
93
+ test(`#given a complete ${surface.name} plan #when a fresh review round starts #then both lanes persist literal workspace and artifact bindings`, async () => {
94
+ const workflow = await readFile(surface.workflowPath, "utf8");
95
+ const contract = readJsonContract(workflow, "ulw-plan-review-round-state-contract");
96
+
97
+ assert.equal(contract.transition, "replace");
98
+ assert.equal(contract.phase, "review_round_initialized");
99
+ assert.deepEqual(contract.applies_when, [
100
+ "complete_plan_after_review_request",
101
+ "explicit_review_modifier_with_complete_plan",
102
+ "retry_after_plan_change",
103
+ ]);
104
+ assert.equal(contract.atomic, true);
105
+ assert.equal(contract.review_required, true);
106
+ assert.equal(contract.plan_path, ".omo/plans/<slug>.md");
107
+ assert.equal(contract.plan_sha256, "<sha256-of-complete-plan>");
108
+ assert.equal(contract.review_round_id, "<fresh-unique-round-id>");
109
+ assert.equal(contract.round_status, "active");
110
+ assert.deepEqual(contract.completion_cas, [
111
+ "status=in_flight",
112
+ "workspace_root",
113
+ "runtime_home",
114
+ "target",
115
+ "launch_id",
116
+ "round_id",
117
+ "plan_sha256",
118
+ "session",
119
+ "receipt_identity=session",
120
+ "live_plan_sha256=plan_sha256",
121
+ "echoed_binding",
122
+ "terminal_transition=in_flight->approved|changes_requested|inconclusive",
123
+ ]);
124
+ assert.equal(contract["pending-action"], "review .omo/plans/<slug>.md");
125
+
126
+ for (const [laneName, lane] of Object.entries(contract.review)) {
127
+ assert.deepEqual(lane, {
128
+ status: "pending",
129
+ workspace_root: surface.reviewRoots[laneName],
130
+ runtime_home: surface.runtimeHomes[laneName],
131
+ target: ".omo/plans/<validated-slug>.md",
132
+ round_id: "<review-round-id>",
133
+ plan_sha256: "<plan-sha256>",
134
+ launch_id: null,
135
+ session: null,
136
+ result: null,
137
+ });
138
+ }
139
+ });
140
+
141
+ test(`#given a ${surface.name} review round #when launch, interruption, completion, or compaction occurs #then the durable transition table fails closed`, async () => {
142
+ const workflow = await readFile(surface.workflowPath, "utf8");
143
+ const contract = readJsonContract(workflow, "ulw-plan-review-lifecycle-state-contract");
144
+
145
+ assert.deepEqual(contract.transitions.launch, {
146
+ from: "pending",
147
+ to: "launching",
148
+ cas: ["round_status=active", "status=pending", "workspace_root", "runtime_home", "target", "round_id", "plan_sha256"],
149
+ writes: ["launch_id=<fresh-launch-id>"],
150
+ });
151
+ assert.deepEqual(contract.transitions.receipt, {
152
+ from: "launching",
153
+ to: "in_flight",
154
+ cas: [
155
+ "round_status=active",
156
+ "status=launching",
157
+ "workspace_root",
158
+ "runtime_home",
159
+ "target",
160
+ "round_id",
161
+ "plan_sha256",
162
+ "launch_id",
163
+ ],
164
+ writes: ["session=<session-or-process-receipt>"],
165
+ });
166
+ assert.deepEqual(contract.transitions.complete, {
167
+ from: "in_flight",
168
+ to: ["approved", "changes_requested", "inconclusive"],
169
+ one_shot: true,
170
+ cas: [
171
+ "round_status=active",
172
+ "workspace_root",
173
+ "runtime_home",
174
+ "target",
175
+ "launch_id",
176
+ "round_id",
177
+ "plan_sha256",
178
+ "session",
179
+ "receipt_identity=session",
180
+ "live_plan_sha256=plan_sha256",
181
+ "echoed_binding",
182
+ ],
183
+ });
184
+ assert.deepEqual(contract.transitions.launch_interrupted, {
185
+ from: { round_status: "active", lane_status: "launching" },
186
+ to: {
187
+ round_status: "inconclusive",
188
+ lane_status: "inconclusive",
189
+ result: "launch_interrupted_without_receipt",
190
+ },
191
+ cas: [
192
+ "round_status=active",
193
+ "status=launching",
194
+ "workspace_root",
195
+ "runtime_home",
196
+ "target",
197
+ "round_id",
198
+ "plan_sha256",
199
+ "launch_id",
200
+ ],
201
+ invalidates_other_lane: true,
202
+ next: "fresh_review_round",
203
+ });
204
+ assert.deepEqual(contract.resume_after_compaction, {
205
+ pending: "dispatch_with_launch_cas",
206
+ launching: "apply_launch_interrupted_transition",
207
+ in_flight: "wait_for_matching_completion_only",
208
+ "approved|changes_requested|inconclusive": "do_not_mutate",
209
+ "round_status=inconclusive": "start_fresh_review_round",
210
+ });
211
+ assert.deepEqual(contract.rejected_completions, ["duplicate", "late", "stale", "mismatched"]);
212
+ });
213
+
214
+ test(`#given ${surface.name} round R2 replaced R1 #when a delayed R1 launch or receipt arrives #then identity-bound CAS leaves R2 unchanged`, async () => {
215
+ const workflow = await readFile(surface.workflowPath, "utf8");
216
+ const contract = readJsonContract(workflow, "ulw-plan-review-lifecycle-state-contract");
217
+ const currentRound = {
218
+ round_status: "active",
219
+ status: "pending",
220
+ workspace_root: surface.reviewRoots.independent,
221
+ runtime_home: surface.runtimeHomes.independent,
222
+ target: ".omo/plans/demo.md",
223
+ round_id: "round-r2",
224
+ plan_sha256: "sha-r2",
225
+ launch_id: null,
226
+ };
227
+ const staleRound = {
228
+ ...currentRound,
229
+ round_id: "round-r1",
230
+ plan_sha256: "sha-r1",
231
+ launch_id: "launch-r1",
232
+ };
233
+
234
+ assert.equal(matchesCas(currentRound, currentRound, contract.transitions.launch.cas), true);
235
+ assert.equal(matchesCas(currentRound, staleRound, contract.transitions.launch.cas), false);
236
+
237
+ const launchedCurrentRound = { ...currentRound, status: "launching", launch_id: "launch-r2" };
238
+ assert.equal(matchesCas(launchedCurrentRound, launchedCurrentRound, contract.transitions.receipt.cas), true);
239
+ assert.equal(matchesCas(launchedCurrentRound, staleRound, contract.transitions.receipt.cas), false);
240
+ assert.equal(matchesCas(launchedCurrentRound, staleRound, contract.transitions.launch_interrupted.cas), false);
241
+ });
242
+
243
+ test(`#given ${surface.name} independent reviewers #when exact-path retrieval drifts #then intake fails closed without alternate artifact recovery`, async () => {
244
+ const workflow = await readFile(surface.workflowPath, "utf8");
245
+ const contract = readJsonContract(workflow, "ulw-plan-review-intake-contract");
246
+
247
+ assert.equal(contract.independent_reviewer, surface.independentReviewer);
248
+ assert.deepEqual(contract.lanes, ["momus", "independent"]);
249
+ assert.equal(contract.binding, "substitute_literals_before_dispatch");
250
+ assert.equal(contract.workspace_root, "<literal-canonical-review-workspace-root>");
251
+ assert.equal(contract.runtime_home, "<literal-runtime-home-or-null>");
252
+ assert.equal(contract.target, "<literal-.omo/plans/validated-slug.md>");
253
+ assert.equal(contract.first_action, "read_exact_plan_path");
254
+ assert.equal(contract.read_mechanism, "open_workspace_root_then_openat_no_follow_each_segment_fstat_read_hash");
255
+ assert.equal(contract.artifact_identity, "<literal-plan-sha256>");
256
+ assert.equal(contract.round_identity, "<literal-review-round-id>");
257
+ assert.equal(contract.launch_identity, "<literal-launch-id>");
258
+ assert.deepEqual(contract.required_echo, [
259
+ "workspace_root",
260
+ "runtime_home",
261
+ "target",
262
+ "artifact_identity",
263
+ "round_identity",
264
+ "launch_identity",
265
+ ]);
266
+ assert.deepEqual(contract.required_receipt, ["session_or_process_identity"]);
267
+ assert.deepEqual(contract.pre_read_validation.sort(), [
268
+ "descriptor_relative_no_follow_each_segment",
269
+ "open_workspace_root_directory_descriptor",
270
+ "regular_file",
271
+ "workspace_relative_canonical_equality",
272
+ ]);
273
+ assert.equal(contract.drift_verdict, "INCONCLUSIVE");
274
+ assert.deepEqual(contract.drift_conditions.sort(), [
275
+ "ancestor_descriptor_mismatch",
276
+ "digest_mismatch",
277
+ "incomplete_retrieval",
278
+ "launch_identity_mismatch",
279
+ "path_mismatch",
280
+ "read_failure",
281
+ "receipt_identity_mismatch",
282
+ "runtime_home_mismatch",
283
+ "stale_or_different_artifact",
284
+ "unsafe_path",
285
+ ]);
286
+ assert.deepEqual(contract.forbidden_fallbacks.sort(), [
287
+ "alternate_files",
288
+ "memory",
289
+ "search",
290
+ "summaries",
291
+ ]);
292
+ });
293
+ }
@@ -29,9 +29,9 @@ test("#given empty Codex config #when script installer updates config #then sets
29
29
  assert.doesNotMatch(config, /^\s*multi_agent_mode\s*=/m);
30
30
  assert.doesNotMatch(config, /^\s*max_threads\s*=/m);
31
31
  assert.match(config, /\[features\.multi_agent_v2\]/);
32
- const v2Section = multiAgentV2Section(config);
32
+ const v2Section = multiAgentV2Section(config);
33
33
  assert.doesNotMatch(v2Section, /^enabled\s*=/m);
34
- assert.match(v2Section, /max_concurrent_threads_per_session = 1000/);
34
+ assert.match(v2Section, /max_concurrent_threads_per_session = 16/);
35
35
  });
36
36
 
37
37
  test("#given queue multi-agent mode #when script installer updates config #then removes unsupported root key", async () => {
@@ -313,8 +313,8 @@ test("#given existing MultiAgentV2 table #when script installer updates config #
313
313
  assert.match(config, /\[features\.multi_agent_v2\]/);
314
314
  assert.doesNotMatch(sectionText(config, "[features.multi_agent_v2]"), /enabled = true/);
315
315
  assert.match(config, /usage_hint_enabled = false/);
316
- assert.match(config, /max_concurrent_threads_per_session = 1000/);
317
- assert.doesNotMatch(config, /max_concurrent_threads_per_session = 4/);
316
+ assert.match(config, /max_concurrent_threads_per_session = 4/);
317
+ assert.doesNotMatch(config, /max_concurrent_threads_per_session = 1000/);
318
318
  });
319
319
 
320
320
  test("#given empty Codex config #when script installer updates config #then sets the generated MultiAgentV2 thread limit", async () => {
@@ -337,7 +337,7 @@ test("#given empty Codex config #when script installer updates config #then sets
337
337
  const config = await readFile(configPath, "utf8");
338
338
  const v2Section = config.slice(config.indexOf("[features.multi_agent_v2]"));
339
339
  assert.doesNotMatch(config, /^\s*max_threads\s*=/m);
340
- assert.match(v2Section, /max_concurrent_threads_per_session = 1000/);
340
+ assert.match(v2Section, /max_concurrent_threads_per_session = 16/);
341
341
  assert.doesNotMatch(v2Section, /hide_spawn_agent_metadata/);
342
342
  });
343
343
 
@@ -401,10 +401,10 @@ test("#given legacy boolean MultiAgentV2 flag and table #when script installer u
401
401
  const config = await readFile(configPath, "utf8");
402
402
  assert.doesNotMatch(config, /^multi_agent_v2\s*=/m);
403
403
  assert.match(config, /\[features\.multi_agent_v2\]/);
404
- const v2Section = multiAgentV2Section(config);
404
+ const v2Section = multiAgentV2Section(config);
405
405
  assert.doesNotMatch(v2Section, /^enabled\s*=/m);
406
406
  assert.match(v2Section, /usage_hint_enabled = false/);
407
- assert.match(v2Section, /max_concurrent_threads_per_session = 1000/);
407
+ assert.match(v2Section, /max_concurrent_threads_per_session = 16/);
408
408
  });
409
409
 
410
410
  test("#given legacy boolean MultiAgentV2 flag false #when script installer updates config #then normalizes to a disabled table config", async () => {
@@ -440,7 +440,7 @@ test("#given legacy boolean MultiAgentV2 flag false #when script installer updat
440
440
  assert.match(config, /\[features\.multi_agent_v2\]/);
441
441
  const disabledV2Section = multiAgentV2Section(config);
442
442
  assert.match(disabledV2Section, /^enabled = false$/m);
443
- assert.match(disabledV2Section, /^max_concurrent_threads_per_session = 1000$/m);
443
+ assert.match(disabledV2Section, /^max_concurrent_threads_per_session = 16$/m);
444
444
  });
445
445
 
446
446
  test("#given legacy agents max_threads #when script installer updates config #then raises the root subagent thread cap", async () => {
@@ -474,9 +474,9 @@ test("#given legacy agents max_threads #when script installer updates config #th
474
474
  // then
475
475
  const config = await readFile(configPath, "utf8");
476
476
  assert.match(config, /\[features\.multi_agent_v2\]/);
477
- const v2Section = multiAgentV2Section(config);
477
+ const v2Section = multiAgentV2Section(config);
478
478
  assert.doesNotMatch(v2Section, /^enabled\s*=/m);
479
- assert.match(v2Section, /max_concurrent_threads_per_session = 1000/);
479
+ assert.match(v2Section, /max_concurrent_threads_per_session = 16/);
480
480
  assert.match(config, /\[agents\]/);
481
481
  assert.match(config, /max_threads = 1000/);
482
482
  assert.doesNotMatch(config, /max_threads = 16/);