lazycodex-ai 4.18.2 → 4.19.1

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 (225) hide show
  1. package/README.ja.md +6 -6
  2. package/README.ko.md +6 -6
  3. package/README.md +8 -8
  4. package/README.ru.md +6 -6
  5. package/README.zh-cn.md +6 -6
  6. package/dist/cli/index.js +781 -215
  7. package/dist/cli-node/index.js +781 -215
  8. package/package.json +1 -1
  9. package/packages/git-bash-mcp/dist/cli.js +54 -8
  10. package/packages/lsp-daemon/dist/cli.js +319 -51
  11. package/packages/lsp-daemon/dist/client.js +136 -48
  12. package/packages/lsp-daemon/dist/daemon-client.d.ts +0 -10
  13. package/packages/lsp-daemon/dist/daemon-client.js +4 -34
  14. package/packages/lsp-daemon/dist/daemon-failure-result.d.ts +3 -0
  15. package/packages/lsp-daemon/dist/daemon-failure-result.js +38 -0
  16. package/packages/lsp-daemon/dist/daemon-request-error.d.ts +14 -0
  17. package/packages/lsp-daemon/dist/daemon-request-error.js +26 -0
  18. package/packages/lsp-daemon/dist/daemon-server.js +5 -1
  19. package/packages/lsp-daemon/dist/index.js +137 -48
  20. package/packages/lsp-daemon/dist/proxy.d.ts +2 -0
  21. package/packages/lsp-daemon/dist/proxy.js +1 -0
  22. package/packages/lsp-daemon/dist/version-reap.d.ts +26 -0
  23. package/packages/lsp-daemon/dist/version-reap.js +182 -0
  24. package/packages/lsp-tools-mcp/dist/cli.js +61 -10
  25. package/packages/lsp-tools-mcp/dist/lsp/manager.js +6 -1
  26. package/packages/lsp-tools-mcp/dist/mcp.js +61 -10
  27. package/packages/lsp-tools-mcp/dist/tools.js +6 -1
  28. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  29. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +416 -25
  30. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  31. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  32. package/packages/omo-codex/plugin/components/bootstrap/src/setup.ts +22 -2
  33. package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +7 -6
  34. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +638 -267
  35. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +178 -89
  36. package/packages/omo-codex/plugin/components/codegraph/package.json +2 -2
  37. package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +3 -1
  38. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +3 -1
  39. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +98 -32
  40. package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +5 -0
  41. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +15 -6
  42. package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +6 -2
  43. package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +1 -0
  44. package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +1 -1
  45. package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +148 -0
  46. package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +31 -2
  47. package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +1 -1
  48. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +65 -1
  49. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +3 -7
  50. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +1 -1
  51. package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +57 -3
  52. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +41 -0
  53. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +109 -8
  54. package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +2 -2
  55. package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +43 -0
  56. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  57. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  58. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  59. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  60. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  61. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  62. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +1 -0
  63. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
  64. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +80 -40
  65. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  66. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  67. package/packages/omo-codex/plugin/components/rules/dist/cli.js +11 -0
  68. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  69. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  70. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +11 -0
  71. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +60 -0
  72. package/packages/omo-codex/plugin/components/start-work-continuation/AGENTS.md +8 -0
  73. package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.js +147 -60
  74. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
  75. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  76. package/packages/omo-codex/plugin/components/start-work-continuation/src/boulder-reader.ts +3 -71
  77. package/packages/omo-codex/plugin/components/start-work-continuation/src/plan-checklist.ts +171 -0
  78. package/packages/omo-codex/plugin/components/start-work-continuation/test/boulder-reader.test.ts +198 -23
  79. package/packages/omo-codex/plugin/components/start-work-continuation/test/cli.test.ts +4 -3
  80. package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +6 -5
  81. package/packages/omo-codex/plugin/components/start-work-continuation/test/fixtures/plan-scaffold.md +15 -0
  82. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  83. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  84. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  85. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  86. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +10 -10
  87. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-clone-fidelity-reviewer.toml +2 -2
  88. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-code-reviewer.toml +2 -2
  89. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-gate-reviewer.toml +1 -1
  90. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-high.toml +1 -1
  91. package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-worker-medium.toml +2 -2
  92. package/packages/omo-codex/plugin/components/ultrawork/agents/momus.toml +3 -3
  93. package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +1 -1
  94. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +1 -1
  95. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  96. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  97. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +31 -8
  98. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +117 -6
  99. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  100. package/packages/omo-codex/plugin/components/ultrawork/src/codex-hook.ts +1 -1
  101. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +42 -0
  102. package/packages/omo-codex/plugin/components/ulw-loop/README.md +6 -4
  103. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.d.ts +21 -0
  104. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-continuation.js +64 -0
  105. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +15 -2
  106. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-arg-parser.js +1 -1
  107. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +2 -1
  108. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +1 -1
  109. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +3 -3
  110. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.d.ts +3 -0
  111. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.js +85 -0
  112. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.d.ts +0 -1
  113. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.js +13 -33
  114. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +998 -593
  115. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +1 -0
  116. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.d.ts +1 -1
  117. package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.js +2 -0
  118. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +6 -0
  119. package/packages/omo-codex/plugin/components/ulw-loop/dist/goal-status.d.ts +1 -0
  120. package/packages/omo-codex/plugin/components/ulw-loop/dist/goal-status.js +3 -0
  121. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.d.ts +1 -0
  122. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.js +4 -0
  123. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.d.ts +1 -0
  124. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +10 -2
  125. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +1 -1
  126. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-batch.d.ts +15 -0
  127. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-batch.js +84 -0
  128. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-mutations.d.ts +5 -0
  129. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-mutations.js +81 -0
  130. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.js +7 -59
  131. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +12 -4
  132. package/packages/omo-codex/plugin/components/ulw-loop/dist/validation-batch.d.ts +9 -0
  133. package/packages/omo-codex/plugin/components/ulw-loop/dist/validation-batch.js +122 -0
  134. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  135. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  136. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +8 -6
  137. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-continuation.ts +84 -0
  138. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +13 -2
  139. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-arg-parser.ts +1 -1
  140. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +1 -1
  141. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +3 -3
  142. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-steering.ts +49 -0
  143. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +13 -45
  144. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +1 -0
  145. package/packages/omo-codex/plugin/components/ulw-loop/src/constants.ts +2 -0
  146. package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +7 -0
  147. package/packages/omo-codex/plugin/components/ulw-loop/src/goal-status.ts +4 -0
  148. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-crud.ts +4 -1
  149. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +20 -2
  150. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +1 -1
  151. package/packages/omo-codex/plugin/components/ulw-loop/src/steering-batch.ts +125 -0
  152. package/packages/omo-codex/plugin/components/ulw-loop/src/steering-mutations.ts +59 -0
  153. package/packages/omo-codex/plugin/components/ulw-loop/src/steering.ts +6 -58
  154. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +12 -4
  155. package/packages/omo-codex/plugin/components/ulw-loop/src/validation-batch.ts +122 -0
  156. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +76 -0
  157. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-checkpoint-continuation.test.ts +111 -0
  158. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-steering-batch.test.ts +67 -0
  159. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-validation-batch.test.ts +57 -0
  160. package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +1 -0
  161. package/packages/omo-codex/plugin/components/ulw-loop/test/steering-batch.test.ts +152 -0
  162. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +29 -0
  163. package/packages/omo-codex/plugin/components/ulw-loop/test/validation-batch-checkpoint.test.ts +147 -0
  164. package/packages/omo-codex/plugin/components/ulw-loop/test/validation-batch.test.ts +73 -0
  165. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  166. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  167. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  168. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  169. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  170. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  171. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  172. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  173. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  174. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  175. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  176. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +2 -2
  177. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  178. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +2 -2
  179. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  180. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +2 -2
  181. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
  182. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  183. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
  184. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  185. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  186. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  187. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  188. package/packages/omo-codex/plugin/package-lock.json +41 -41
  189. package/packages/omo-codex/plugin/package.json +1 -1
  190. package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +32 -28
  191. package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +17 -45
  192. package/packages/omo-codex/plugin/scripts/migrate-codex-config/toml-section-editor.mjs +455 -0
  193. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +3 -18
  194. package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +43 -0
  195. package/packages/omo-codex/plugin/skills/programming/scripts/typescript/check-no-excuse-rules.ts +35 -5
  196. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +8 -6
  197. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +31 -8
  198. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +117 -6
  199. package/packages/omo-codex/plugin/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  200. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +11 -11
  201. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +26 -0
  202. package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +41 -0
  203. package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +2 -2
  204. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +6 -6
  205. package/packages/omo-codex/plugin/test/multi-agent-v2-regression.test.mjs +3 -3
  206. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +62 -0
  207. package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +271 -14
  208. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +3 -18
  209. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +0 -5
  210. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +293 -0
  211. package/packages/omo-codex/scripts/install-dist/install-local.mjs +401 -22
  212. package/packages/shared-skills/skills/programming/scripts/typescript/check-no-excuse-rules.test.ts +87 -0
  213. package/packages/shared-skills/skills/programming/scripts/typescript/check-no-excuse-rules.ts +35 -5
  214. package/packages/shared-skills/skills/ulw-plan/SKILL.md +31 -8
  215. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +117 -6
  216. package/packages/shared-skills/skills/ulw-plan/scripts/scaffold-plan.mjs +46 -10
  217. package/packages/shared-skills/skills/ulw-research/SKILL.md +3 -3
  218. package/packages/shared-skills/skills/ultraresearch/SKILL.md +0 -10
  219. /package/packages/{shared-skills → omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/SKILL.md +0 -0
  220. /package/packages/{shared-skills → omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/agents/openai.yaml +0 -0
  221. /package/packages/{shared-skills → omo-codex/plugin/components/lcx}/skills/lcx-contribute-bug-fix/scripts/create-pr-body.mjs +0 -0
  222. /package/packages/{shared-skills → omo-codex/plugin/components/lcx}/skills/lcx-doctor/SKILL.md +0 -0
  223. /package/packages/{shared-skills → omo-codex/plugin/components/lcx}/skills/lcx-doctor/agents/openai.yaml +0 -0
  224. /package/packages/{shared-skills → omo-codex/plugin/components/lcx}/skills/lcx-report-bug/SKILL.md +0 -0
  225. /package/packages/{shared-skills → 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
+ }