lazycodex-ai 5.0.0-beta.48 → 5.0.0-beta.49

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 (118) hide show
  1. package/README.ja.md +35 -27
  2. package/README.ko.md +35 -27
  3. package/README.md +19 -34
  4. package/README.ru.md +33 -28
  5. package/README.zh-cn.md +31 -27
  6. package/dist/cli/index.js +19 -15
  7. package/dist/cli-node/index.js +19 -15
  8. package/package.json +1 -1
  9. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +2 -2
  10. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  11. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  12. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  13. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  14. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  15. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  16. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  17. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  18. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
  19. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  20. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  21. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  22. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  23. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  24. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  25. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  26. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  27. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +11 -10
  28. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  29. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  30. package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +1 -1
  31. package/packages/omo-codex/plugin/components/ulw-execute-continuation/AGENTS.md +3 -3
  32. package/packages/omo-codex/plugin/components/ulw-execute-continuation/README.md +3 -3
  33. package/packages/omo-codex/plugin/components/ulw-execute-continuation/directive.md +4 -4
  34. package/packages/omo-codex/plugin/components/ulw-execute-continuation/dist/cli.js +1 -1
  35. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -13
  36. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
  37. package/packages/omo-codex/plugin/components/ulw-execute-continuation/src/codex-hook.ts +1 -1
  38. package/packages/omo-codex/plugin/components/ulw-execute-continuation/src/types.ts +1 -1
  39. package/packages/omo-codex/plugin/components/ulw-execute-continuation/test/cli.test.ts +3 -7
  40. package/packages/omo-codex/plugin/components/ulw-execute-continuation/test/codex-hook.test.ts +16 -0
  41. package/packages/omo-codex/plugin/components/ulw-loop/README.md +2 -2
  42. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +11 -10
  43. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.js +8 -15
  44. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +2 -2
  45. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +1 -1
  46. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +1 -1
  47. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +88 -67
  48. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +3 -4
  49. package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +1 -1
  50. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.js +1 -1
  51. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +13 -16
  52. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.d.ts +2 -0
  53. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +47 -26
  54. package/packages/omo-codex/plugin/components/ulw-loop/dist/status-next-actions.js +2 -2
  55. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.d.ts +1 -0
  56. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.js +14 -4
  57. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +17 -4
  58. package/packages/omo-codex/plugin/components/ulw-loop/package.json +2 -2
  59. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +1 -1
  60. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-template.ts +8 -14
  61. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +2 -2
  62. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +1 -1
  63. package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +5 -1
  64. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +3 -4
  65. package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +1 -1
  66. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-fields.ts +4 -1
  67. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +21 -16
  68. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +52 -25
  69. package/packages/omo-codex/plugin/components/ulw-loop/src/status-next-actions.ts +2 -2
  70. package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +16 -4
  71. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +11 -12
  72. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-fields-messages.test.ts +98 -0
  73. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-lazycodex-surface.test.ts +93 -0
  74. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +9 -4
  75. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +10 -0
  76. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +70 -7
  77. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  78. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  79. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  80. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  81. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  82. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  83. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  84. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +18 -0
  85. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  86. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  87. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  88. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  89. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  90. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  91. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  92. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  93. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  94. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  95. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  96. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  97. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  98. package/packages/omo-codex/plugin/package-lock.json +12 -12
  99. package/packages/omo-codex/plugin/package.json +1 -1
  100. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +61 -33
  101. package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +4 -2
  102. package/packages/omo-codex/plugin/skills/refactor/SKILL.md +4 -2
  103. package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +4 -2
  104. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +13 -3
  105. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +11 -10
  106. package/packages/omo-codex/plugin/skills/ulw-execute/SKILL.md +11 -6
  107. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +24 -0
  108. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +1 -1
  109. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +4 -2
  110. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +4 -2
  111. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +8 -4
  112. package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +62 -0
  113. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +3 -3
  114. package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +23 -1
  115. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +36 -16
  116. package/packages/omo-codex/scripts/install-dist/install-local.mjs +2 -2
  117. package/packages/prompts-core/prompts/ultrawork/codex.md +11 -10
  118. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-ulw-execute-continuation.json +0 -17
@@ -12,17 +12,19 @@ This skill may include examples copied from the OpenCode harness. In Codex, do n
12
12
  | `call_omo_agent(subagent_type="explore", ...)` | `multi_agent_v1.spawn_agent({"message":"TASK: act as an explorer. ...","agent_type":"explorer","fork_context":false})` |
13
13
  | `call_omo_agent(subagent_type="librarian", ...)` | `multi_agent_v1.spawn_agent({"message":"TASK: act as a librarian. ...","agent_type":"librarian","fork_context":false})` |
14
14
  | `task(subagent_type="plan", ...)` | `multi_agent_v1.spawn_agent({"message":"TASK: act as a planning agent. ...","agent_type":"plan","fork_context":false})` |
15
- | `task(subagent_type="oracle", ...)` for final verification | `multi_agent_v1.spawn_agent({"message":"TASK: act as a rigorous reviewer. ...","agent_type":"lazycodex-gate-reviewer","fork_context":false})` |
15
+ | `task(subagent_type="oracle", ...)` for final verification | By default, record a self-review in the notepad: re-read the diff, run diagnostics, and capture evidence for every acceptance criterion. Only when the user demanded strict, rigorous, or high-accuracy review, use `multi_agent_v1.spawn_agent({"message":"TASK: act as a rigorous reviewer. ...","agent_type":"lazycodex-gate-reviewer","fork_context":false})`; include `fork_context: false`. |
16
16
  | `task(category="...", ...)` for implementation or QA | `multi_agent_v1.spawn_agent({"message":"TASK: act as an implementation or QA worker. ...","fork_context":false})` |
17
17
  | `background_output(task_id="...")` | `multi_agent_v1.wait_agent(...)` for mailbox signals |
18
18
  | `team_*(...)` | Use Codex native subagents via `multi_agent_v1.spawn_agent` and `multi_agent_v1.wait_agent`; use `multi_agent_v1.send_input` and `multi_agent_v1.close_agent` only when exposed in the active tools list |
19
19
 
20
20
  Role-specific behavior must be described in a self-contained `message`. Use `fork_context: false` to start the child with only the initial prompt (no parent history); use `fork_context: true` only when full parent history is truly required. Include any required conversation context, files, diffs, constraints, and requested skill names directly in the spawned agent's `message`. OMO installs these selectable agent roles into `~/.codex/agents/`: `explorer`, `librarian`, `plan`, `momus`, `metis`, `lazycodex-code-reviewer`, `lazycodex-qa-executor`, and `lazycodex-gate-reviewer` - pass the matching name as `agent_type` so the child gets that role's model and instructions. If the spawn tool exposes no `agent_type` parameter, omit it and describe the role inside `message`. If a code block below conflicts with this section, this section wins.
21
21
 
22
- Codex exposes ONE of two subagent tool surfaces per session; check your own tool list and route accordingly. If `multi_agent_v1.*` tools exist, use the table above as written. If instead a flat `spawn_agent` with a required `task_name` exists (`multi_agent_v2`), rewrite every `multi_agent_v1.*` example: `multi_agent_v1.spawn_agent({...,"fork_context":false})` becomes `spawn_agent({"task_name":"<lowercase_digits_underscores>","message":...,"agent_type":...,"fork_turns":"none"})` (`"all"` only when full parent history is truly required); `send_input` becomes `send_message`; do not call `close_agent`/`resume_agent` (finished agents end on their own; `followup_task` re-tasks one, `interrupt_agent` stops one); `wait_agent` takes only `timeout_ms` and returns on any child mailbox activity. On the v2 surface `agent_type` may be ABSENT from the spawn schema (verified 2026-07-11: only `fork_turns`/`message`/`task_name`) — when absent, omit it and describe the role inside `message`; installed role TOMLs cannot be selected on that surface. If a code block below conflicts with this section, this section wins.
22
+ Codex exposes ONE of two subagent tool surfaces per session; check your own tool list and route accordingly. If `multi_agent_v1.*` tools exist, use the table above as written. If instead a flat `spawn_agent` with a required `task_name` exists (`multi_agent_v2`), rewrite every `multi_agent_v1.*` example: `multi_agent_v1.spawn_agent({...,"fork_context":false})` becomes `spawn_agent({"task_name":"<lowercase_digits_underscores>","message":...,"agent_type":...,"fork_turns":"none"})` (`"all"` only when full parent history is truly required); `send_input` becomes `send_message`; do not call `close_agent`/`resume_agent` (finished agents end on their own; `followup_task` re-tasks one, `interrupt_agent` stops one); `wait_agent` takes only `timeout_ms` and returns on any child mailbox activity. On the v2 surface `agent_type` may be ABSENT from the spawn schema (verified 2026-07-11: only `fork_turns`/`message`/`task_name`) — when absent, omit it and describe the role inside `message`; installed role TOMLs cannot be selected on that surface. If a code block below conflicts with this section, this section wins. `fork_context` is rejected on `multi_agent_v2` (`fork_context is not supported in MultiAgentV2; use fork_turns instead`).
23
23
 
24
24
  When translating `load_skills=[...]`, include the requested skill names in the spawned agent's `message`. If a code block below conflicts with this section, this section wins.
25
25
 
26
+ Omit optional keys you do not set. Never send `items: []`, `message: ""`, `model: ""`, `reasoning_effort: ""`, or `service_tier: ""` — Codex rejects them (`Items can't be empty`, `reasoning_effort must not be empty`).
27
+
26
28
  For work likely to exceed one wait cycle, require the child to send `WORKING: <task> - <current phase>` before long passes and `BLOCKED: <reason>` only when progress stops. A `multi_agent_v1.wait_agent` timeout only means no new mailbox update arrived; back off between waits (double the timeout up to ~5 minutes) instead of spinning short cycles. Treat a running child as alive. Fallback only when the child is completed without the deliverable, ack-only after followup, explicitly `BLOCKED:`, or no longer running.
27
29
 
28
30
  ---
@@ -12,17 +12,19 @@ This skill may include examples copied from the OpenCode harness. In Codex, do n
12
12
  | `call_omo_agent(subagent_type="explore", ...)` | `multi_agent_v1.spawn_agent({"message":"TASK: act as an explorer. ...","agent_type":"explorer","fork_context":false})` |
13
13
  | `call_omo_agent(subagent_type="librarian", ...)` | `multi_agent_v1.spawn_agent({"message":"TASK: act as a librarian. ...","agent_type":"librarian","fork_context":false})` |
14
14
  | `task(subagent_type="plan", ...)` | `multi_agent_v1.spawn_agent({"message":"TASK: act as a planning agent. ...","agent_type":"plan","fork_context":false})` |
15
- | `task(subagent_type="oracle", ...)` for final verification | `multi_agent_v1.spawn_agent({"message":"TASK: act as a rigorous reviewer. ...","agent_type":"lazycodex-gate-reviewer","fork_context":false})` |
15
+ | `task(subagent_type="oracle", ...)` for final verification | By default, record a self-review in the notepad: re-read the diff, run diagnostics, and capture evidence for every acceptance criterion. Only when the user demanded strict, rigorous, or high-accuracy review, use `multi_agent_v1.spawn_agent({"message":"TASK: act as a rigorous reviewer. ...","agent_type":"lazycodex-gate-reviewer","fork_context":false})`; include `fork_context: false`. |
16
16
  | `task(category="...", ...)` for implementation or QA | `multi_agent_v1.spawn_agent({"message":"TASK: act as an implementation or QA worker. ...","fork_context":false})` |
17
17
  | `background_output(task_id="...")` | `multi_agent_v1.wait_agent(...)` for mailbox signals |
18
18
  | `team_*(...)` | Use Codex native subagents via `multi_agent_v1.spawn_agent` and `multi_agent_v1.wait_agent`; use `multi_agent_v1.send_input` and `multi_agent_v1.close_agent` only when exposed in the active tools list |
19
19
 
20
20
  Role-specific behavior must be described in a self-contained `message`. Use `fork_context: false` to start the child with only the initial prompt (no parent history); use `fork_context: true` only when full parent history is truly required. Include any required conversation context, files, diffs, constraints, and requested skill names directly in the spawned agent's `message`. OMO installs these selectable agent roles into `~/.codex/agents/`: `explorer`, `librarian`, `plan`, `momus`, `metis`, `lazycodex-code-reviewer`, `lazycodex-qa-executor`, and `lazycodex-gate-reviewer` - pass the matching name as `agent_type` so the child gets that role's model and instructions. If the spawn tool exposes no `agent_type` parameter, omit it and describe the role inside `message`. If a code block below conflicts with this section, this section wins.
21
21
 
22
- Codex exposes ONE of two subagent tool surfaces per session; check your own tool list and route accordingly. If `multi_agent_v1.*` tools exist, use the table above as written. If instead a flat `spawn_agent` with a required `task_name` exists (`multi_agent_v2`), rewrite every `multi_agent_v1.*` example: `multi_agent_v1.spawn_agent({...,"fork_context":false})` becomes `spawn_agent({"task_name":"<lowercase_digits_underscores>","message":...,"agent_type":...,"fork_turns":"none"})` (`"all"` only when full parent history is truly required); `send_input` becomes `send_message`; do not call `close_agent`/`resume_agent` (finished agents end on their own; `followup_task` re-tasks one, `interrupt_agent` stops one); `wait_agent` takes only `timeout_ms` and returns on any child mailbox activity. On the v2 surface `agent_type` may be ABSENT from the spawn schema (verified 2026-07-11: only `fork_turns`/`message`/`task_name`) — when absent, omit it and describe the role inside `message`; installed role TOMLs cannot be selected on that surface. If a code block below conflicts with this section, this section wins.
22
+ Codex exposes ONE of two subagent tool surfaces per session; check your own tool list and route accordingly. If `multi_agent_v1.*` tools exist, use the table above as written. If instead a flat `spawn_agent` with a required `task_name` exists (`multi_agent_v2`), rewrite every `multi_agent_v1.*` example: `multi_agent_v1.spawn_agent({...,"fork_context":false})` becomes `spawn_agent({"task_name":"<lowercase_digits_underscores>","message":...,"agent_type":...,"fork_turns":"none"})` (`"all"` only when full parent history is truly required); `send_input` becomes `send_message`; do not call `close_agent`/`resume_agent` (finished agents end on their own; `followup_task` re-tasks one, `interrupt_agent` stops one); `wait_agent` takes only `timeout_ms` and returns on any child mailbox activity. On the v2 surface `agent_type` may be ABSENT from the spawn schema (verified 2026-07-11: only `fork_turns`/`message`/`task_name`) — when absent, omit it and describe the role inside `message`; installed role TOMLs cannot be selected on that surface. If a code block below conflicts with this section, this section wins. `fork_context` is rejected on `multi_agent_v2` (`fork_context is not supported in MultiAgentV2; use fork_turns instead`).
23
23
 
24
24
  When translating `load_skills=[...]`, include the requested skill names in the spawned agent's `message`. If a code block below conflicts with this section, this section wins.
25
25
 
26
+ Omit optional keys you do not set. Never send `items: []`, `message: ""`, `model: ""`, `reasoning_effort: ""`, or `service_tier: ""` — Codex rejects them (`Items can't be empty`, `reasoning_effort must not be empty`).
27
+
26
28
  For work likely to exceed one wait cycle, require the child to send `WORKING: <task> - <current phase>` before long passes and `BLOCKED: <reason>` only when progress stops. A `multi_agent_v1.wait_agent` timeout only means no new mailbox update arrived; back off between waits (double the timeout up to ~5 minutes) instead of spinning short cycles. Treat a running child as alive. Fallback only when the child is completed without the deliverable, ack-only after followup, explicitly `BLOCKED:`, or no longer running.
27
29
 
28
30
  # Visual QA - Dual-Oracle Web and TUI Verification
@@ -63,7 +63,7 @@ test("#given aggregate Stop hooks #when inspected #then ulw-execute continuation
63
63
  assert.ok(stopCommands.some((command) => command.includes("ulw-loop/dist/cli.js\" hook stop")));
64
64
  });
65
65
 
66
- test("#given aggregate SubagentStop hooks #when inspected #then ulw-execute and LazyCodex executor verifier are separate groups", async () => {
66
+ test("#given aggregate SubagentStop hooks #when inspected #then only LazyCodex executor verification remains", async () => {
67
67
  // given
68
68
  const manifests = await readAggregateHookManifests();
69
69
 
@@ -77,9 +77,8 @@ test("#given aggregate SubagentStop hooks #when inspected #then ulw-execute and
77
77
  );
78
78
 
79
79
  // then
80
- assert.equal(subagentStopGroups.length, 2);
81
- assert.equal(subagentStopGroups[0]?.matcher, undefined);
82
- assert.equal(subagentStopGroups[1]?.matcher, "^lazycodex-worker-(low|medium|high)$");
80
+ assert.equal(subagentStopGroups.length, 1);
81
+ assert.equal(subagentStopGroups[0]?.matcher, "^lazycodex-worker-(low|medium|high)$");
83
82
  assert.equal(verifierGroups.length, 1);
84
83
  assert.equal(verifierGroups[0]?.groupIndex, 0);
85
84
  assert.equal(verifierGroups[0]?.handler.timeout, 10);
@@ -160,6 +159,11 @@ test("#given aggregate OMO plugin is enabled #when hooks are inspected #then she
160
159
  "^(spawn_agent|collaborationspawn_agent|collaboration\\.spawn_agent)$",
161
160
  ]);
162
161
  assert.match(text, /hook pre-tool-use-spawn/);
162
+ const admissionGroups = manifests.flatMap(({ hooks }) => hooks.hooks.PostToolUse ?? [])
163
+ .filter((group) => group.hooks.some((hook) => hook.command.endsWith(" hook post-tool-use-spawn")));
164
+ assert.equal(admissionGroups.length, 1);
165
+ assert.equal(admissionGroups[0].matcher, preToolUseGroups[2].matcher);
166
+ assert.match(admissionGroups[0].hooks[0].commandWindows, /hook post-tool-use-spawn$/);
163
167
  });
164
168
 
165
169
  test("#given aggregate OMO plugin has a dedicated ultrawork trigger #when hooks are inspected #then ulw-loop does not duplicate ultrawork injection", async () => {
@@ -1,8 +1,48 @@
1
1
  import assert from "node:assert/strict";
2
2
  import { join } from "node:path";
3
+ import { existsSync, readFileSync } from "node:fs";
3
4
 
4
5
  export function componentHookContractCases(tempRoot) {
6
+ const spawnPayload = {
7
+ cwd: tempRoot, hook_event_name: "PreToolUse", model: "gpt-6-astra",
8
+ permission_mode: "default", session_id: "s-spawn-admission", tool_input: { message: "scan" },
9
+ tool_name: "spawn_agent", tool_use_id: "spawn-1", transcript_path: null, turn_id: "t-spawn",
10
+ };
11
+ const marker = join(tempRoot, "plugin-data", "spawn-breaker", "s-spawn-admission.json");
5
12
  return [
13
+ {
14
+ name: "ulw-loop post-tool-use successful admission is silent",
15
+ component: "ulw-loop", event: "post-tool-use-spawn",
16
+ payload: { ...spawnPayload, hook_event_name: "PostToolUse", tool_response: { agent_id: "worker-1" } },
17
+ assertOutput(stdout) { assert.equal(stdout, ""); assert.equal(existsSync(marker), false); },
18
+ },
19
+ {
20
+ name: "ulw-loop post-tool-use failed admission records silently",
21
+ component: "ulw-loop", event: "post-tool-use-spawn",
22
+ payload: { ...spawnPayload, hook_event_name: "PostToolUse", tool_response: "AgentLimitReached" },
23
+ assertOutput(stdout) {
24
+ assert.equal(stdout, "");
25
+ const recorded = JSON.parse(readFileSync(marker, "utf8"));
26
+ assert.deepEqual(Object.keys(recorded).sort(), ["at", "reason"]);
27
+ assert.equal(recorded.reason, "AgentLimitReached");
28
+ assert.equal(Number.isFinite(Date.parse(recorded.at)), true);
29
+ },
30
+ },
31
+ {
32
+ name: "ulw-loop admission breaker denies without a plan",
33
+ component: "ulw-loop", event: "pre-tool-use-spawn", payload: spawnPayload,
34
+ assertOutput(stdout) {
35
+ const output = JSON.parse(stdout).hookSpecificOutput;
36
+ assert.equal(output.hookEventName, "PreToolUse");
37
+ assert.equal(output.permissionDecision, "deny");
38
+ },
39
+ },
40
+ {
41
+ name: "ulw-loop clean session admission is silent",
42
+ component: "ulw-loop", event: "pre-tool-use-spawn",
43
+ payload: { ...spawnPayload, session_id: "s-spawn-clean" },
44
+ assertOutput(stdout) { assert.equal(stdout, ""); },
45
+ },
6
46
  {
7
47
  name: "rules session-start",
8
48
  component: "rules",
@@ -219,5 +259,27 @@ export function componentHookContractCases(tempRoot) {
219
259
  assert.equal(stdout, "");
220
260
  },
221
261
  },
262
+ {
263
+ name: "ulw-execute-continuation subagent-stop compatibility no-op",
264
+ component: "ulw-execute-continuation",
265
+ event: "subagent-stop",
266
+ payload: {
267
+ hook_event_name: "SubagentStop",
268
+ agent_id: "agent-task12",
269
+ agent_type: "lazycodex-worker-low",
270
+ session_id: "s-task12",
271
+ turn_id: "t-task12",
272
+ transcript_path: join(tempRoot, "transcript.jsonl"),
273
+ agent_transcript_path: join(tempRoot, "agent-transcript.jsonl"),
274
+ cwd: tempRoot,
275
+ model: "gpt-5.5",
276
+ permission_mode: "default",
277
+ stop_hook_active: false,
278
+ last_assistant_message: "done",
279
+ },
280
+ assertOutput(stdout) {
281
+ assert.equal(stdout, "");
282
+ },
283
+ },
222
284
  ];
223
285
  }
@@ -14,6 +14,7 @@ const root = dirname(dirname(fileURLToPath(import.meta.url)));
14
14
  const repoRoot = join(root, "..", "..", "..");
15
15
 
16
16
  const AGGREGATE_EXPECTED_LABELS = new Map([
17
+ ["hooks/post-tool-use-recording-spawn-admission.json:PostToolUse:0:0", "Recording Spawn Admission"],
17
18
  ["hooks/hooks.json:SessionStart:0:0", "Loading Project Rules"],
18
19
  ["hooks/hooks.json:SessionStart:1:0", "Recording Session Telemetry"],
19
20
  ["hooks/hooks.json:SessionStart:2:0", "Checking Auto Update"],
@@ -30,11 +31,11 @@ const AGGREGATE_EXPECTED_LABELS = new Map([
30
31
  ["hooks/hooks.json:PostCompact:1:0", "Resetting Project Rule Cache"],
31
32
  ["hooks/hooks.json:PostCompact:2:0", "Resetting LSP Diagnostics Cache"],
32
33
  ["hooks/hooks.json:Stop:0:0", "Checking Ulw-Execute Continuation"],
33
- ["hooks/hooks.json:SubagentStop:0:0", "Checking Ulw-Execute Continuation"],
34
- ["hooks/hooks.json:SubagentStop:1:0", "Verifying LazyCodex Executor Evidence"],
34
+ ["hooks/hooks.json:SubagentStop:0:0", "Verifying LazyCodex Executor Evidence"],
35
35
  ]);
36
36
 
37
37
  const COMPONENT_EXPECTED_LABELS = new Map([
38
+ ["components/ulw-loop/hooks/hooks.json:PostToolUse:0:0", "Recording Spawn Admission"],
38
39
  ["components/comment-checker/hooks/hooks.json:PostToolUse:0:0", "Checking Comments"],
39
40
  ["components/lsp/hooks/hooks.json:PostToolUse:0:0", "Checking LSP Diagnostics"],
40
41
  ["components/lsp/hooks/hooks.json:PostCompact:0:0", "Resetting LSP Diagnostics Cache"],
@@ -47,7 +48,6 @@ const COMPONENT_EXPECTED_LABELS = new Map([
47
48
  ["components/ulw-loop/hooks/hooks.json:UserPromptSubmit:0:0", "Checking Ulw-Loop Steering"],
48
49
  ["components/ulw-loop/hooks/hooks.json:PreToolUse:0:0", "Enforcing Unlimited Ulw-Loop Budget"],
49
50
  ["components/ulw-execute-continuation/hooks/hooks.json:Stop:0:0", "Checking Ulw-Execute Continuation"],
50
- ["components/ulw-execute-continuation/hooks/hooks.json:SubagentStop:0:0", "Checking Ulw-Execute Continuation"],
51
51
  [
52
52
  "components/lazycodex-executor-verify/hooks/hooks.json:SubagentStop:0:0",
53
53
  "Verifying LazyCodex Executor Evidence",
@@ -9,8 +9,12 @@ import { fileURLToPath } from "node:url";
9
9
  import { canonicalUltraworkDirectiveRelativePath } from "../scripts/canonical-ultrawork-directive.mjs";
10
10
 
11
11
  import {
12
+ applyCodexSkillOverlays,
12
13
  codexHarnessToolCompatibility,
13
14
  insertCodexCompatibilityGuidance,
15
+ reviewWorkAnchor,
16
+ ulwExecuteOriginalCompletion,
17
+ ulwExecuteOriginalHardRule,
14
18
  } from "../scripts/sync-skills.mjs";
15
19
 
16
20
  const frontmatter = "---\nname: fixture-sentinel\n---\n\n";
@@ -18,6 +22,7 @@ const opencodeExample = "# SENTINEL_SECTION\ntask(SENTINEL_INPUT)\n";
18
22
  const pluginRoot = dirname(dirname(fileURLToPath(import.meta.url)));
19
23
  const repositoryRoot = join(pluginRoot, "..", "..");
20
24
  const opencodeToolPattern = /\b(?:call_omo_agent|background_output|team_[a-z_]+|task)\s*\(/;
25
+ const sharedSkillsRoot = join(repositoryRoot, "shared-skills", "skills");
21
26
 
22
27
  test("#given sentinel OpenCode tool content #when compatibility guidance is inserted #then the production artifact is placed after frontmatter and before the tool token", () => {
23
28
  const input = `${frontmatter}${opencodeExample}`;
@@ -28,6 +33,23 @@ test("#given sentinel OpenCode tool content #when compatibility guidance is inse
28
33
  assert.ok(actual.indexOf(codexHarnessToolCompatibility) < actual.indexOf(opencodeExample));
29
34
  });
30
35
 
36
+ test("#given shared skill source anchors #when Codex overlays are applied #then exact anchors transform and match the generated artifacts", async () => {
37
+ const ulwExecuteSource = await readFile(join(sharedSkillsRoot, "ulw-execute", "SKILL.md"), "utf8");
38
+ const reviewWorkSource = await readFile(join(sharedSkillsRoot, "review-work", "SKILL.md"), "utf8");
39
+
40
+ assert.ok(ulwExecuteSource.includes(ulwExecuteOriginalCompletion), "ulw-execute completion anchor drifted from shared source");
41
+ assert.ok(ulwExecuteSource.includes(ulwExecuteOriginalHardRule), "ulw-execute hard-rule anchor drifted from shared source");
42
+ assert.ok(reviewWorkSource.includes(reviewWorkAnchor), "review-work anchor drifted from shared source");
43
+
44
+ for (const [skillName, source] of [["ulw-execute", ulwExecuteSource], ["review-work", reviewWorkSource]]) {
45
+ const compatible = insertCodexCompatibilityGuidance(source);
46
+ const overlaid = applyCodexSkillOverlays(skillName, compatible);
47
+ assert.notEqual(overlaid, compatible, `${skillName} overlay must change the shared source`);
48
+ assert.equal(applyCodexSkillOverlays(skillName, overlaid), overlaid, `${skillName} overlay must be idempotent`);
49
+ assert.equal(await readFile(join(pluginRoot, "skills", skillName, "SKILL.md"), "utf8"), overlaid);
50
+ }
51
+ });
52
+
31
53
  test("#given already transformed sentinel content #when compatibility guidance is inserted again #then the transform is idempotent", () => {
32
54
  const once = insertCodexCompatibilityGuidance(`${frontmatter}${opencodeExample}`);
33
55
 
@@ -99,7 +121,7 @@ test("#given the aggregate sync implementation #when its skill adaptation pipeli
99
121
 
100
122
  assert.match(
101
123
  script,
102
- /applyCodexSkillOverlays\(\s*skillName,\s*insertCodexCompatibilityGuidance\(content\),?\s*\)/,
124
+ /applyCodexSkillOverlays\(\s*skillName,\s*insertCodexCompatibilityGuidance\(content,\s*needsSpawnPayloadGuidance\),?\s*\)/,
103
125
  );
104
126
  assert.match(script, /await adaptSkillForCodex\(skillName\)/);
105
127
  });
@@ -57,6 +57,8 @@ export const canonicalUltraworkDirectiveRelativePath = join(
57
57
  );
58
58
 
59
59
  const codexCompatibilityEndMarkers = [
60
+ "Omit optional keys you do not set. Never send `items: []`, `message: \"\"`, `model: \"\"`, `reasoning_effort: \"\"`, or `service_tier: \"\"` — Codex rejects them (`Items can't be empty`, `reasoning_effort must not be empty`).\n\nFor work likely to exceed one wait cycle, require the child to send `WORKING: <task> - <current phase>` before long passes and `BLOCKED: <reason>` only when progress stops. A `multi_agent_v1.wait_agent` timeout only means no new mailbox update arrived; back off between waits (double the timeout up to ~5 minutes) instead of spinning short cycles. Treat a running child as alive. Fallback only when the child is completed without the deliverable, ack-only after followup, explicitly `BLOCKED:`, or no longer running.\n\n",
61
+ "On the v2 surface `agent_type` may be ABSENT from the spawn schema (verified 2026-07-11: only `fork_turns`/`message`/`task_name`) — when absent, omit it and describe the role inside `message`; installed role TOMLs cannot be selected on that surface. If a code block below conflicts with this section, this section wins. `fork_context` is rejected on `multi_agent_v2` (`fork_context is not supported in MultiAgentV2; use fork_turns instead`).\n\n",
60
62
  "For work likely to exceed one wait cycle, require the child to send `WORKING: <task> - <current phase>` before long passes and `BLOCKED: <reason>` only when progress stops. A `multi_agent_v1.wait_agent` timeout only means no new mailbox update arrived. Treat a running child as alive. Fallback only when the child is completed without the deliverable, ack-only after followup, explicitly `BLOCKED:`, or no longer running.\n\n",
61
63
  "On `multi_agent_v2` sessions the same `agent_type` applies (the OMO installer exposes it) with `fork_turns` instead of `fork_context`. If a code block below conflicts with this section, this section wins.\n\n",
62
64
  "Role-specific behavior must be described in a self-contained `message`. Use `fork_context: false` to start the child with only the initial prompt (no parent history); use `fork_context: true` only when full parent history is truly required. Include any required conversation context, files, diffs, constraints, and requested skill names directly in the spawned agent's `message`. If a code block below conflicts with this section, this section wins.\n\n",
@@ -82,31 +84,49 @@ export function removeCodexCompatibilityGuidance(content) {
82
84
  const ulwExecuteOriginalCompletion = `When all top-level checkboxes in \`## TODOs\` and \`## Final Verification Wave\` are complete:
83
85
 
84
86
  1. Run the plan's final verification commands.
85
- 2. For PR/branch work, finish the lifecycle from the task-owned worktree: sync \`.omo/\` state back to the main repo, create or update the PR, wait for review/verification gates, merge by default unless explicitly opted out, and remove the worktree only after successful merge or explicit handoff.
87
+ 2. For PR/branch work, finish the lifecycle from the last phase's worktree: sync \`.omo/\` state back to the main repo, create or update the PR, wait for review/verification gates, merge by default unless explicitly opted out, and remove the worktree only after successful merge or explicit handoff.
86
88
  3. Remove or mark the Boulder work as completed.
87
89
  4. Print an \`ORCHESTRATION COMPLETE\` block with the plan path, verification commands, artifacts, and cleanup receipts.`;
88
90
 
89
91
  const ulwExecuteCodexCompletion = `When all top-level checkboxes in \`## TODOs\` and \`## Final Verification Wave\` are complete:
90
92
 
91
93
  1. Run the plan's final verification commands.
92
- 2. Complete the **Global Review and Debugging Gate** before any completion claim, PR creation, PR handoff, branch handoff, or merge:
93
- - Invoke the \`review-work\` skill with the final diff, changed files, user goal, constraints, run command, and verification evidence. Both review lanes - the manual QA matrix and the gate review - must PASS. A timeout, missing deliverable, ack-only child, \`BLOCKED:\`, or inconclusive lane is a gate failure, not approval.
94
- - Each passing review lane binds to the exact full commit SHA it reviewed. Immediately append a durable record to \`.omo/ulw-execute/ledger.jsonl\` with the lane name, full SHA, PASS verdict, and report artifact/source. Before same-SHA reuse after any continuation or compaction, re-read the ledger record and require the exact lane/SHA pair; memory, chat history, or an unstamped report is not coverage. New commits require fresh applicable lane coverage.
95
- - Run a debugging-oriented runtime audit even when the review passes: name at least three plausible failure hypotheses for the changed surface, run the distinguishing checks against the actual artifact, and append a separate durable record with the audit name, exact full SHA, verdict, and evidence artifact/source to \`.omo/ulw-execute/ledger.jsonl\`. Reuse it only after re-reading an exact audit/SHA match.
96
- - If any review lane or debugging hypothesis fails, invoke the \`debugging\` skill, confirm root cause with runtime evidence, add the minimal failing test or reproduction, fix it, rerun the affected verification, then rerun the Global Review and Debugging Gate.
97
- - Evidence hygiene is mandatory: redact or mask secrets and sensitive user data before writing \`.omo/ulw-execute/ledger.jsonl\`, a PR body, or a handoff. Never include raw tokens, credentials, auth headers, cookies, API keys, env dumps, private logs, or PII; use concise summaries, lengths, hashes, or short non-sensitive prefixes instead.
98
- - If the work includes creating, updating, or handing off a PR, refresh \`git status\` and the PR/branch state from the task-owned worktree after the gate, and include only redacted review/debugging evidence in the PR body or handoff.
99
- 3. Finish the PR/branch lifecycle from its task-owned worktree: sync \`.omo/\` state back to the main repo, create or update the PR when requested, wait for CI/review/Cubic gates, merge by default unless explicitly opted out, and remove the worktree only after successful merge or explicit handoff.
100
- 4. Remove or mark the Boulder work as completed.
101
- 5. Print an \`ORCHESTRATION COMPLETE\` block with the plan path, verification commands, Global Review and Debugging Gate verdict, artifacts, and cleanup receipts.`;
102
-
103
- const ulwExecuteOriginalHardRule = "- No completion claim while an applicable ultraqa adversarial class was never probed. Each applicable class needs a captured observable result; each skipped class needs a one-line not-applicable reason in the ledger.\n- No PR/branch implementation, review, or merge in the main worktree; use the task-owned git worktree.\n- No unprefixed session ids in Boulder state. Sessions are always recorded as `codex:<session_id>`.";
104
-
105
- const ulwExecuteCodexHardRule = "- No completion claim while an applicable ultraqa adversarial class was never probed. Each applicable class needs a captured observable result; each skipped class needs a one-line not-applicable reason in the ledger.\n- No `ORCHESTRATION COMPLETE`, final response, PR creation, PR handoff, or merge before the Global Review and Debugging Gate passes with recorded evidence.\n- No PR/branch implementation or review in the main worktree; create or use a task-owned git worktree first.\n- No unprefixed session ids in Boulder state. Sessions are always recorded as `codex:<session_id>`.";
94
+ 2. Record a self-review in the notepad: re-read the diff, run diagnostics, and capture evidence for every acceptance criterion. Run your own manual QA on the real surface.
95
+ 3. Only when the user demanded strict, rigorous, or high-accuracy review, spawn ONE \`lazycodex-gate-reviewer\`; otherwise your self-review is the final verification.
96
+ 4. Finish the PR/branch lifecycle from its task-owned worktree: sync \`.omo/\` state back to the main repo, create or update the PR, wait for review/verification gates, merge by default unless explicitly opted out, and remove the worktree only after successful merge or explicit handoff.
97
+ 5. Remove or mark the Boulder work as completed.
98
+ 6. Print an \`ORCHESTRATION COMPLETE\` block with the plan path, verification commands, artifacts, and cleanup receipts.`;
99
+
100
+ const ulwExecuteOriginalHardRule = `- No production change before a failing-first proof exists (unit test at a seam, otherwise the failing Manual-QA scenario), and no change to existing behavior before a baseline characterization test pins the current behavior and passes on the unchanged code.
101
+ - No \`--dry-run\` as completion evidence.
102
+ - No tests-only completion claim. A Manual-QA artifact is required.
103
+ - **NO DIRECT IMPLEMENTATION BY THE ORCHESTRATOR.** Root NEVER edits product files, writes tests, or runs QA itself — a spawned worker does.
104
+ - No completion claim while an applicable ultraqa adversarial class was never probed. Each applicable class needs a captured observable result; each skipped class needs a one-line not-applicable reason in the ledger.
105
+ - No implementation, review, or merge in the main checkout; every phase works in its task-owned worktree.
106
+ - No unprefixed session ids in Boulder state. Sessions are always recorded as \`codex:<session_id>\`.
107
+ - No stale-memory execution. The plan and ledger are the durable source of truth.`;
108
+
109
+ const ulwExecuteCodexHardRule = `- No production change before a failing-first proof exists (unit test at a seam, otherwise the failing Manual-QA scenario), and no change to existing behavior before a baseline characterization test pins the current behavior and passes on the unchanged code.
110
+ - No \`--dry-run\` as completion evidence.
111
+ - No tests-only completion claim. A Manual-QA artifact is required.
112
+ - **NO DIRECT IMPLEMENTATION BY THE ORCHESTRATOR.** Root NEVER edits product files, writes tests, or runs QA itself — a spawned worker does.
113
+ - No completion claim while an applicable ultraqa adversarial class was never probed. Each applicable class needs a captured observable result; each skipped class needs a one-line not-applicable reason in the ledger.
114
+ - No implementation, review, or merge in the main checkout; every phase works in a task-owned worktree.
115
+ - No unprefixed session ids in Boulder state. Sessions are always recorded as \`codex:<session_id>\`.
116
+ - No stale-memory execution. The plan and ledger are the durable source of truth.
117
+ - Codex final verification is the exception to the delegated-QA-only rule above: perform your own manual QA on the real surface and record a self-review before completion.`;
106
118
 
107
119
  const reviewWorkCodexGate = `
120
+ On Codex, use \`review-work\` only when the user asks for a review or demands
121
+ strict, rigorous, or high-accuracy verification, not automatically for a PR or
122
+ completion claim. Your own manual QA and the main session's self-review are
123
+ the default. Spawn ONE \`lazycodex-gate-reviewer\` only for an explicit demand
124
+ for strict review; otherwise run the review checklist inline and record the
125
+ main session's verdict instead of spawning or waiting for a reviewer. These
126
+ Codex rules override the mandatory-reviewer instructions in the shared skill.
127
+
108
128
  When \`review-work\` is used as a final implementation, PR, or \`$ulw-execute\`
109
- gate, it is blocking. A timeout, missing deliverable, ack-only response,
129
+ gate, the selected review is blocking. A timeout, missing deliverable, ack-only response,
110
130
  explicit \`BLOCKED:\`, or inconclusive lane is not a pass. Treat that lane as
111
131
  failed, investigate the underlying uncertainty with the \`debugging\` skill when
112
132
  runtime behavior may be wrong, fix with evidence, and rerun the affected lane
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // omo-codex-install:81cf03496fa0db52b428d9e5f1d2a022f753fe60530d84f72d767af03333373f:d9847212c69382c8b1ef908ee03c5b079dc818a67781f34f9cc324074120ee89
2
+ // omo-codex-install:81cf03496fa0db52b428d9e5f1d2a022f753fe60530d84f72d767af03333373f:68365e4c1ec89226f01d55d21613f2b3a049a5669f4e6e3ff7c15b088c6eaa59
3
3
  var __defProp = Object.defineProperty;
4
4
  var __returnValue = (v) => v;
5
5
  function __exportSetter(name, newValue) {
@@ -7977,7 +7977,7 @@ var package_default;
7977
7977
  var init_package = __esm(() => {
7978
7978
  package_default = {
7979
7979
  name: "@oh-my-opencode/omo-codex",
7980
- version: "5.0.0-beta.48",
7980
+ version: "5.0.0-beta.49",
7981
7981
  type: "module",
7982
7982
  private: true,
7983
7983
  description: "Codex harness adapter for oh-my-openagent. Vendored Codex plugin namespace (omo) + TypeScript installer + telemetry.",
@@ -46,8 +46,8 @@ first-class for CLI- or data-shaped work; self-review recorded in the
46
46
  notepad instead of the reviewer loop.
47
47
  HEAVY — anything a fact above names: 3+ success criteria (happy,
48
48
  edge, regression, adversarial risk), each with its own channel
49
- scenario and both evidence pieces; reviewer loop until unconditional
50
- approval.
49
+ scenario and both evidence pieces; when the verification gate is
50
+ triggered, run the reviewer loop until unconditional approval.
51
51
 
52
52
  # Manual-QA channels
53
53
  Run real-surface proof yourself through the channel that faithfully
@@ -385,16 +385,17 @@ BLOCKED: <reason>`. After four silent or ack-only checks, close the lane as
385
385
  inconclusive, record that it is not approval, and respawn smaller only
386
386
  if the deliverable is still required.
387
387
 
388
- # Verification gate (TRIGGERED, NOT OPTIONAL)
388
+ # Verification gate (TRIGGERED ONLY ON EXPLICIT DEMAND)
389
389
 
390
- Trigger when ANY apply:
391
- - Tier is HEAVY.
392
- - User demanded strict, rigorous, or proper review.
393
- LIGHT tier records a self-review in the notepad instead: re-read the
394
- diff, run diagnostics, confirm each criterion's evidence, and state in
395
- one line why the tier held.
390
+ Trigger ONLY when the user explicitly demanded strict, rigorous, proper,
391
+ or high-accuracy review of this work, in any language (for example,
392
+ 고정밀 or 엄격). The tier alone never triggers the gate. HEAVY without
393
+ such a demand records the same self-review as LIGHT.
394
+ LIGHT and non-triggered HEAVY work records a self-review in the notepad
395
+ instead: re-read the diff, run diagnostics, confirm each criterion's
396
+ evidence, and state in one line why the tier held.
396
397
 
397
- Procedure (NON-NEGOTIABLE):
398
+ When triggered, follow this procedure (NON-NEGOTIABLE):
398
399
  1. Spawn a child with `fork_context: false` and a self-contained reviewer
399
400
  assignment in `message`. The `multi_agent_v1.spawn_agent` schema cannot select a
400
401
  TOML-backed reviewer role, so paste the reviewer requirements into
@@ -1,17 +0,0 @@
1
- {
2
- "hooks": {
3
- "SubagentStop": [
4
- {
5
- "hooks": [
6
- {
7
- "type": "command",
8
- "command": "node \"${PLUGIN_ROOT}/components/ulw-execute-continuation/dist/cli.js\" hook subagent-stop",
9
- "timeout": 10,
10
- "statusMessage": "(OmO 5.0.0-beta.48) Checking Ulw-Execute Continuation",
11
- "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\ulw-execute-continuation\\dist\\cli.js\" hook subagent-stop"
12
- }
13
- ]
14
- }
15
- ]
16
- }
17
- }