oh-my-opencode 5.1.29 → 5.1.32

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 (146) hide show
  1. package/README.ja.md +2 -0
  2. package/README.ko.md +2 -0
  3. package/README.md +2 -0
  4. package/README.ru.md +2 -0
  5. package/README.zh-cn.md +2 -0
  6. package/dist/cli/cli-program.d.ts +1 -20
  7. package/dist/cli/index.js +950 -51
  8. package/dist/cli/install-command-options.d.ts +20 -0
  9. package/dist/cli/service-auth/browser.d.ts +3 -0
  10. package/dist/cli/service-auth/cli-keystore.fixture.d.ts +7 -0
  11. package/dist/cli/service-auth/commands.d.ts +19 -0
  12. package/dist/cli/service-auth/device-flow.d.ts +15 -0
  13. package/dist/cli/service-auth/device-keys.d.ts +10 -0
  14. package/dist/cli/service-auth/device-name.d.ts +3 -0
  15. package/dist/cli/service-auth/keystore.d.ts +20 -0
  16. package/dist/cli/service-auth/loopback.d.ts +11 -0
  17. package/dist/cli/service-auth/protocol.d.ts +86 -0
  18. package/dist/cli/service-auth/refresh-child.fixture.d.ts +1 -0
  19. package/dist/cli/service-auth/session.d.ts +17 -0
  20. package/dist/cli/service-auth/terminal-text.d.ts +1 -0
  21. package/dist/cli/service-auth/test-support.d.ts +43 -0
  22. package/dist/cli/service-auth/tls-test-certificate.d.ts +4 -0
  23. package/dist/cli-node/index.js +950 -51
  24. package/dist/features/background-agent/task-poller.d.ts +3 -0
  25. package/dist/features/opencode-skill-loader/opencode-shell-skill-content.d.ts +8 -0
  26. package/dist/features/opencode-skill-loader/skill-content.d.ts +1 -0
  27. package/dist/features/team-mode/tools/lifecycle-inline-spec.d.ts +1 -0
  28. package/dist/hooks/keyword-detector/constants.d.ts +1 -0
  29. package/dist/hooks/non-interactive-env/non-interactive-env-hook.d.ts +5 -1
  30. package/dist/index.js +40791 -40412
  31. package/dist/shared/disabled-agents.d.ts +1 -0
  32. package/dist/shared/opencode-shell.d.ts +27 -0
  33. package/dist/skills/browser/SKILL.md +1 -1
  34. package/dist/skills/browser/runtime/omowright/manifest.json +1 -1
  35. package/dist/skills/ultimate-browsing/SKILL.md +14 -16
  36. package/dist/skills/ulw-execute/SKILL.md +2 -2
  37. package/dist/skills/ulw-research/SKILL.md +17 -18
  38. package/dist/skills/ulw-research/scripts/cli-support.test.ts +5 -3
  39. package/dist/skills/ulw-research/scripts/outcome.test.ts +10 -4
  40. package/dist/skills/ulw-research/scripts/report-tools.test.ts +3 -2
  41. package/dist/skills/visual-qa/scripts/cli.test.ts +5 -3
  42. package/dist/tools/delegate-task/executor-types.d.ts +1 -0
  43. package/dist/tools/delegate-task/sync-session-creator.d.ts +1 -0
  44. package/dist/tools/delegate-task/types.d.ts +2 -0
  45. package/dist/tools/session-manager/sdk-storage.d.ts +15 -2
  46. package/dist/tools/session-manager/session-error.d.ts +7 -0
  47. package/dist/tools/session-manager/storage.d.ts +4 -2
  48. package/dist/tui.js +89 -21
  49. package/package.json +15 -14
  50. package/packages/git-bash-mcp/dist/cli.js +1 -1
  51. package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +90 -0
  52. package/packages/lsp-core/src/lsp/client.ts +3 -1
  53. package/packages/lsp-core/src/lsp/workspace-apply-edit-test-support.ts +5 -2
  54. package/packages/lsp-daemon/dist/cli.js +1 -1
  55. package/packages/lsp-daemon/dist/client.js +1 -1
  56. package/packages/lsp-daemon/dist/index.js +1 -1
  57. package/packages/lsp-tools-mcp/dist/cli.js +1 -1
  58. package/packages/lsp-tools-mcp/dist/lsp/manager.js +1 -1
  59. package/packages/lsp-tools-mcp/dist/mcp.js +1 -1
  60. package/packages/lsp-tools-mcp/dist/tools.js +1 -1
  61. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  62. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +7 -4
  63. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  64. package/packages/omo-codex/plugin/components/bootstrap/package.json +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/lcx/skills/lcx-contribute-bug-fix/SKILL.md +7 -4
  72. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +3 -3
  73. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +1 -1
  74. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  75. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  76. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  77. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  78. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  79. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  80. package/packages/omo-codex/plugin/components/teammode/skills/teammode/SKILL.md +3 -3
  81. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  82. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  83. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +18 -15
  84. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  85. package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
  86. package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +1 -1
  87. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +1 -1
  88. package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
  89. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +18 -15
  90. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +5 -5
  91. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  92. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +2 -2
  93. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +2 -2
  94. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  95. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  96. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  97. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  98. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  99. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  100. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  101. package/packages/omo-codex/plugin/hooks/post-tool-use-recording-spawn-admission.json +1 -1
  102. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  103. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  104. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  105. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  106. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  107. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  108. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  109. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
  110. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  111. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  112. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  113. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  114. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  115. package/packages/omo-codex/plugin/package-lock.json +12 -12
  116. package/packages/omo-codex/plugin/package.json +1 -1
  117. package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +2 -0
  118. package/packages/omo-codex/plugin/scripts/auto-update.mjs +2 -0
  119. package/packages/omo-codex/plugin/scripts/build-bundled-mcp-runtimes.mjs +2 -0
  120. package/packages/omo-codex/plugin/scripts/build-components.mjs +1 -0
  121. package/packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs +42 -10
  122. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +2 -2
  123. package/packages/omo-codex/plugin/skills/browser/SKILL.md +1 -1
  124. package/packages/omo-codex/plugin/skills/browser/runtime/omowright/manifest.json +1 -1
  125. package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/SKILL.md +7 -4
  126. package/packages/omo-codex/plugin/skills/teammode/SKILL.md +3 -3
  127. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +14 -16
  128. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +18 -15
  129. package/packages/omo-codex/plugin/skills/ulw-execute/SKILL.md +2 -2
  130. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +2 -2
  131. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +2 -2
  132. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +17 -18
  133. package/packages/omo-codex/plugin/test/materialize-shared-upstreams.test.mjs +179 -0
  134. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +2 -2
  135. package/packages/omo-codex/plugin/test/windows-console-hide.test.mjs +150 -0
  136. package/packages/omo-codex/scripts/install-dist/install-local.mjs +11 -6
  137. package/packages/prompts-core/prompts/ultrawork/codex.md +18 -15
  138. package/packages/shared-skills/skills/browser/SKILL.md +1 -1
  139. package/packages/shared-skills/skills/browser/runtime/omowright/manifest.json +1 -1
  140. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +14 -16
  141. package/packages/shared-skills/skills/ulw-execute/SKILL.md +2 -2
  142. package/packages/shared-skills/skills/ulw-research/SKILL.md +17 -18
  143. package/packages/shared-skills/skills/ulw-research/scripts/cli-support.test.ts +5 -3
  144. package/packages/shared-skills/skills/ulw-research/scripts/outcome.test.ts +10 -4
  145. package/packages/shared-skills/skills/ulw-research/scripts/report-tools.test.ts +3 -2
  146. package/packages/shared-skills/skills/visual-qa/scripts/cli.test.ts +5 -3
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "version": "5.1.29",
4
- "inputDigest": "sha256:9d15a230eaff0c93de5a8ff0f469ff7fe066ca59ac92dfe7672fd8ff300fa085",
3
+ "version": "5.1.32",
4
+ "inputDigest": "sha256:b3b8e90fd4e1cf2fe7480a11a0479a266e8c3b2724b104ee47b9fb777c5927de",
5
5
  "outputs": [
6
6
  {
7
7
  "path": "cli.d.ts",
@@ -9,7 +9,7 @@
9
9
  },
10
10
  {
11
11
  "path": "cli.js",
12
- "sha256": "f2776c0f9c2a893136e9e8e36c2e086172f10c0ab3566a730cff4443b712f956"
12
+ "sha256": "e4d7664d4b1a19eb00e68e5a0f42ceae1195188a26e59217522c1d0de3854f54"
13
13
  },
14
14
  {
15
15
  "path": "codex-hook-cli.d.ts",
@@ -3270,7 +3270,7 @@ class LspClient extends LspClientConnection {
3270
3270
  } catch (error) {
3271
3271
  if (this.isUnsupportedDiagnosticPullError(error)) {
3272
3272
  this.setDiagnosticPullSupported(false);
3273
- pushFallbackOnly = true;
3273
+ continue;
3274
3274
  } else if (error instanceof LspRequestTimeoutError) {
3275
3275
  pushFallbackOnly = true;
3276
3276
  } else {
@@ -8,7 +8,7 @@
8
8
  "type": "command",
9
9
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-tool-use",
10
10
  "timeout": 60,
11
- "statusMessage": "(OmO 5.1.29) Checking LSP Diagnostics"
11
+ "statusMessage": "(OmO 5.1.32) Checking LSP Diagnostics"
12
12
  }
13
13
  ]
14
14
  }
@@ -21,7 +21,7 @@
21
21
  "type": "command",
22
22
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-compact",
23
23
  "timeout": 5,
24
- "statusMessage": "(OmO 5.1.29) Resetting LSP Diagnostics Cache"
24
+ "statusMessage": "(OmO 5.1.32) Resetting LSP Diagnostics Cache"
25
25
  }
26
26
  ]
27
27
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-lsp",
3
- "version": "5.1.29",
3
+ "version": "5.1.32",
4
4
  "description": "Codex plugin that exposes Language Server Protocol tools and post-edit diagnostics.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook session-start",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO 5.1.29) Loading Project Rules"
10
+ "statusMessage": "(OmO 5.1.32) Loading Project Rules"
11
11
  }
12
12
  ]
13
13
  }
@@ -19,7 +19,7 @@
19
19
  "type": "command",
20
20
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook user-prompt-submit",
21
21
  "timeout": 10,
22
- "statusMessage": "(OmO 5.1.29) Loading Project Rules"
22
+ "statusMessage": "(OmO 5.1.32) Loading Project Rules"
23
23
  }
24
24
  ]
25
25
  }
@@ -32,7 +32,7 @@
32
32
  "type": "command",
33
33
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-tool-use",
34
34
  "timeout": 10,
35
- "statusMessage": "(OmO 5.1.29) Matching Project Rules"
35
+ "statusMessage": "(OmO 5.1.32) Matching Project Rules"
36
36
  }
37
37
  ]
38
38
  }
@@ -45,7 +45,7 @@
45
45
  "type": "command",
46
46
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-compact",
47
47
  "timeout": 10,
48
- "statusMessage": "(OmO 5.1.29) Resetting Project Rule Cache"
48
+ "statusMessage": "(OmO 5.1.32) Resetting Project Rule Cache"
49
49
  }
50
50
  ]
51
51
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-rules",
3
- "version": "5.1.29",
3
+ "version": "5.1.32",
4
4
  "description": "Codex plugin that injects project rule files into model context through lifecycle hooks.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -8,7 +8,7 @@
8
8
  "type": "command",
9
9
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-tool-use",
10
10
  "timeout": 10,
11
- "statusMessage": "(OmO 5.1.29) Checking Thread Title Hygiene"
11
+ "statusMessage": "(OmO 5.1.32) Checking Thread Title Hygiene"
12
12
  }
13
13
  ]
14
14
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sisyphuslabs/codex-teammode",
3
- "version": "5.1.29",
3
+ "version": "5.1.32",
4
4
  "description": "Codex team-mode hook component that keeps background thread titles descriptive after create_thread.",
5
5
  "type": "module",
6
6
  "private": true,
@@ -229,9 +229,9 @@ cannot clobber each other. Decide this whenever you see the collision - at team
229
229
  not only up front. For each colliding member run `worktree-add --team <id> --id <member>`: it creates
230
230
  the worktree off the base branch on a derived branch, flips the team into worktree mode, records it in
231
231
  `team.json`, and prints the `cd` path to hand that member. The member works and commits only inside
232
- its own worktree. To land the work, `integrate --team <id>` merges every member branch into your
232
+ its own worktree. Use the bundled ultrawork directive’s Task resources and todo rules at member/worktree creation; read those sections if absent from context. To land the work, `integrate --team <id>` merges every member branch into your
233
233
  current branch with a merge commit (never a squash or rebase); resolve any conflict it reports, then
234
- `worktree-remove` each worktree at cleanup.
234
+ finish owned directory teardown per Task resources.
235
235
 
236
236
  Delivering the path differs by transport: on MultiAgentV2, create the worktree BEFORE spawning
237
237
  so the bootstrap carries it, or send it to an already-running member as a `followup_task`; on
@@ -280,7 +280,7 @@ is never disbanded is a leak.
280
280
  - `delete` removes `.omo/teams/{session_id}` and refuses while the team is unarchived or any member
281
281
  is still active unless `--force`.
282
282
  - When the work wraps up, land it the way the user asked: `integrate --team <id>` for a direct merge
283
- commit, or push each member branch and open a PR. Then `worktree-remove` each worktree, archive, and
283
+ commit, or push each member branch and open a PR. Then finish worktree cleanup per Task resources, archive, and
284
284
  delete. Cleanup is real work; respect the user's instruction on how to land it.
285
285
 
286
286
  ## Stop rules
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook session-start",
9
9
  "timeout": 5,
10
- "statusMessage": "(OmO 5.1.29) Recording Session Telemetry"
10
+ "statusMessage": "(OmO 5.1.32) Recording Session Telemetry"
11
11
  }
12
12
  ]
13
13
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-telemetry",
3
- "version": "5.1.29",
3
+ "version": "5.1.32",
4
4
  "description": "Codex plugin component that emits omo-codex anonymous daily-active telemetry on SessionStart.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -118,7 +118,11 @@ degrades color and wide-glyph width. In this repo:
118
118
  stream). Outside this repo, capture equivalent browser-rendered terminal
119
119
  evidence: screenshot + plain transcript + cleanup receipt.
120
120
 
121
- # Bootstrap (DO ALL FOUR BEFORE ANY OTHER WORK — NO SKIPPING)
121
+ # Bootstrap (COMPLETE EVERY SECTION BEFORE ANY OTHER WORK — NO SKIPPING)
122
+
123
+ ## Task resources
124
+ Before the first task command, create one \`RUN_TMP=$(mktemp -d)\` per task, tracking its paths under section 3 immediately. Export \`TMPDIR="$RUN_TMP" NODE_COMPILE_CACHE="$RUN_TMP/node-compile-cache" BUN_RUNTIME_TRANSPILER_CACHE_PATH="$RUN_TMP/bun-transpiler"\` for every command; pass the same environment explicitly to children that do not inherit it. Give independent child tasks their own run roots.
125
+ At task end, after owned processes exit, remove only owned directories, including runtime caches. Never wipe shared caches; retain worktrees still needed by open PRs and any parent directory containing them.
122
126
 
123
127
  ## 0. Survey the skills, gather context, then size the work
124
128
  First, survey the loaded skill list and read the description of each
@@ -212,7 +216,7 @@ steps.
212
216
 
213
217
  ## 3. Register obsessive todos via \`update_plan\`
214
218
  The todo tool is Codex \`update_plan\` — your live, user-visible
215
- checklist. Translate every action from the plan into one \`update_plan\`
219
+ checklist. Keep resource-cleanup todos registered earlier. Translate every action from the plan into one \`update_plan\`
216
220
  step — one step per atomic work unit: an edit plus its verification, a
217
221
  QA scenario run, a teardown. Keep each step small enough to finish
218
222
  within a few tool calls.
@@ -224,6 +228,9 @@ behind reality. Add newly discovered steps the moment they surface
224
228
  instead of waiting for the next pass. Step text encodes WHERE / WHY
225
229
  (which criterion it advances) / HOW / VERIFY:
226
230
  \`path: <action> for <criterion> — verify by <check>\`.
231
+ ALWAYS add a cleanup todo AT CREATION for each worktree, cache directory (including
232
+ the run root), and QA resource (PID, tmux session, browser context, port, container,
233
+ script or temp path); complete it only after a read-back teardown receipt.
227
234
 
228
235
  GOOD pair (ordered):
229
236
  \`test/foo.test.ts: read the validateEmail cases for criterion 2 — verify by noting intent / coverage / pass in the notepad\`
@@ -286,19 +293,15 @@ Until every success criterion PASSES with its evidence captured:
286
293
  above; auxiliary surface for CLI- or data-shaped criteria), end to
287
294
  end, yourself, plus the step-2 tests; a reproduction now passes.
288
295
  Paste the artifact path into the notepad.
289
- 5. CLEANUP (PAIRED — NEVER SKIP): the moment a QA scenario spawns any
290
- resource, register its teardown as its own todo (e.g.
291
- \`cleanup: kill server pid for criterion 2 — verify kill -0 fails\`).
292
- Every runtime artifact the QA spawned in step 4 MUST be torn down
293
- before this step completes:
294
- server PIDs (\`kill <pid>\`; verify \`kill -0\` fails), \`tmux\` sessions
295
- (\`tmux kill-session -t ulw-qa-<criterion>\`; verify with \`tmux ls\`),
296
- browsers / sessions (\`browser.close()\` / \`session.stop()\`), containers
297
- (\`docker rm -f\`), bound ports (\`lsof -i :<port>\` empty), temp
298
- sockets / files / dirs (\`rm -rf\` the \`mktemp\` paths), QA-only env
299
- vars. Append a one-line cleanup receipt to the notepad next to the
300
- artifact, e.g. \`cleanup: killed 12345; tmux kill-session ulw-qa-foo;
301
- rm -rf /tmp/ulw.aB12cD\`. No receipt → criterion stays in_progress.
296
+ 5. CLEANUP (PAIRED — NEVER SKIP):
297
+ Before recording QA, tear down owned server PIDs (\`kill <pid>\`; verify
298
+ \`kill -0\` fails), tmux sessions (\`tmux kill-session -t ulw-qa-<criterion>\`; confirm \`tmux ls\`),
299
+ browsers / sessions (\`browser.close()\` / \`session.stop()\`), containers (\`docker rm -f\`), ports
300
+ (\`lsof -i :<port>\` empty), QA scripts, temp paths and QA-only env vars.
301
+ Remove QA temp paths inside \`$RUN_TMP\` per criterion; remove the run root
302
+ and eligible worktrees at task end under Task resources.
303
+ Append the read-back receipt beside the artifact in the notepad.
304
+ No receipt → criterion stays in_progress.
302
305
  6. Verify: LSP diagnostics clean on changed files; no test skipped or
303
306
  xfail-ed this turn.
304
307
  7. Mark completed. Append non-obvious findings / learnings.
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook user-prompt-submit",
9
9
  "timeout": 5,
10
- "statusMessage": "(OmO 5.1.29) Checking Ultrawork Trigger"
10
+ "statusMessage": "(OmO 5.1.32) Checking Ultrawork Trigger"
11
11
  }
12
12
  ]
13
13
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-ultrawork",
3
- "version": "5.1.29",
3
+ "version": "5.1.32",
4
4
  "description": "Codex plugin that injects the ultrawork orchestration directive and ships LazyCodex planning, review, QA, and gate agent roles.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -1,4 +1,4 @@
1
1
  // GENERATED by scripts/sync-directive.mjs from packages/prompts-core/prompts/ultrawork/codex.md.
2
2
  // Do not hand-edit. Freshness is enforced by test/directive-source.test.ts.
3
3
  export const ULTRAWORK_DIRECTIVE_TEXT =
4
- '<ultrawork-mode>\n\n**MANDATORY**: First user-visible line this turn MUST be exactly:\n`ULTRAWORK MODE ENABLED!`\n\n[CODE RED] Maximum precision. Outcome-first. Evidence-driven.\n\n# Role\nExpert coding agent. Ship verified work; report at handoffs, not between them.\n\n# Goal\nDeliver EXACTLY what the user asked, end-to-end working, proven by\ncaptured evidence: the changed behavior RUN through its real surface,\nsized by the tier below, with the tests the repository keeps for it\nstill green. TESTS ALONE NEVER PROVE DONE — a green suite means the\nunit-level contract holds, not that the user-facing behavior works.\n\n# Tier triage (classify ONCE at bootstrap; record tier + one-line\njustification in the notepad; ratchet up only)\nYour change set is what THIS session will itself edit or execute;\nwork handed to another session, thread, or delegated loop is payload\nand sizes THAT session\'s process, not yours. Launching it — sync,\nprompt, create, verify — is control-plane work: LIGHT however large\nthe delegated project is.\nDefault is LIGHT. Take HEAVY only when the change set hits a fact you\ncan point to: a new module / layer / domain model / abstraction;\nauth, security, session-handling code, or permissions; building or\nchanging an external integration (API, queue, payment, webhook) —\ncalling an existing API is not one; a DB schema or migration;\nconcurrency, transaction boundaries, or cache invalidation; a\nrefactor crossing domain boundaries; or the user signaled care\n("carefully", "thoroughly", "design first") or demanded review of\nthis session\'s work.\nWhen unsure, take HEAVY. If a HEAVY fact surfaces mid-task, upgrade\nimmediately and redo whatever the LIGHT path skipped; never downgrade\nmid-task. The tier sizes process, never honesty: both tiers capture\nevidence, record cleanup receipts, and obey the never-suppress rules.\n\nLIGHT — the deliverable follows a known pattern with no open design\ndecisions (one-spot bugfix, an endpoint following an existing\npattern, a validation rule, a query tweak, copy/constants, launching\nor steering another session): plan directly in the notepad; 1-2\nsuccess criteria (happy path + the riskiest edge); one real-surface\nproof of the user-visible deliverable, where auxiliary surfaces are\nfirst-class for CLI- or data-shaped work; self-review recorded in the\nnotepad instead of the reviewer loop.\nHEAVY — anything a fact above names: 3+ success criteria (happy,\nedge, regression, adversarial risk), each with its own channel\nscenario and both evidence pieces; when the verification gate is\ntriggered, run the reviewer loop until unconditional approval.\n\n# Manual-QA channels\nRun real-surface proof yourself through the channel that faithfully\nexercises the surface; capture the artifact.\n\n 1. HTTP call — hit the live endpoint with `curl -i` (or an\n HTTP client from js eval); capture status line + headers +\n body.\n 2. Terminal / TUI - drive a real pty and prove it through the\n xterm.js web terminal (see the TUI visual QA note below). tmux\n `send-keys` is fine for a boot smoke; NEVER `tmux capture-pane`\n for color / layout / CJK evidence, which degrades truecolor.\n 3. Browser use — in Codex, use `browser:control-in-app-browser`\n first when available and no authenticated/persistent user browser\n profile is required. Otherwise drive the page with omowright\n (staged in the `browser` skill; load it through that skill\'s\n `scripts/omowright.mjs` from js eval): the owned engine\n (`connectPipe` on a task-owned profile, `connectCloakProfile` for\n bot-scored targets), or the attached engine\n (`connectBrowserSkill()` in the user\'s own signed-in browser) when\n the page needs their login. Capture action log + screenshot path.\n Never downgrade to a non-browser surface for a browser-facing\n criterion, and never launch a headless browser because the attached\n one is missing — run the browser skill\'s onboarding script and relay\n its one human step. NEVER clear cookies, cache, or site data\n (`Network.clearBrowserCookies`, `Storage.clearCookies`,\n `chrome.browsingData.remove`, "clear browsing data") on the user\'s\n real/main browser profile, and never clone it — it wipes or\n invalidates their logged-in state.\n 4. Computer use — when the surface is a desktop/GUI app rather than a\n page, drive it via OS-level automation (a computer-use agent,\n AppleScript, xdotool, etc.) against the running app; capture\n action log + screenshot. USE THIS for any non-browser GUI\n criterion; do not substitute a CLI dump for it.\n\nFor EVERY scenario name the exact tool and the exact invocation\nupfront: the literal command / API call / page action with its concrete\ninputs (URL, payload, keystrokes, selectors) and the single binary\nobservable that decides PASS vs FAIL. "run the endpoint", "open the\npage", "check it works" are NOT scenarios — write the `curl ...`, the\n`send-keys ...`, the Browser plugin action, the `page.click(...)`, the\nexpected status/text.\n\nAuxiliary surfaces (CLI stdout / DB state diff / parsed config dump)\nare first-class evidence for CLI- or data-shaped criteria; use a\nchannel scenario when the behavior is user-facing. `--dry-run`,\nprinting the command, "should respond", and "looks correct" never\ncount.\n\nFor TUI visual QA, render the terminal through the real xterm.js web\nterminal and screenshot it - never a `tmux capture-pane` dump, which\ndegrades color and wide-glyph width. In this repo:\n`node script/qa/web-terminal-visual-qa.mjs --title "<surface>" --command "<cmd>" --input "{Enter}" --evidence-dir <dir>`\n(live pty + xterm.js in Chrome; `--from-file <capture>` replays a raw\nstream). Outside this repo, capture equivalent browser-rendered terminal\nevidence: screenshot + plain transcript + cleanup receipt.\n\n# Bootstrap (DO ALL FOUR BEFORE ANY OTHER WORK — NO SKIPPING)\n\n## 0. Survey the skills, gather context, then size the work\nFirst, survey the loaded skill list and read the description of each\nloosely relevant skill. Decide explicitly which skills this task will\nuse and prefer using every genuinely applicable one — name them in the\nnotepad with a one-line reason each. Skipping a skill that fits the\ntask is a defect. Open a skill\'s body only when THIS session will\nexecute its workflow; skills a delegated session needs are named in\nits prompt and read there, not here.\nNext, fire the first discovery wave under Finding things below.\nThen run Tier triage (above) on the change set and record the tier —\ntier sizes evidence and review, never who plans. Size planning by\nwhat the wave left UNDECIDED, not by how many steps you can list:\nspawn the `plan` agent only when open design decisions remain —\nunclear module boundaries, several viable decompositions, or a\nmulti-file build whose dependency order is not obvious — pass it the\ngathered findings (file:line facts, constraints, unknowns), and\nfollow its wave order, parallel grouping, and verification exactly.\nA known procedure — however many steps — and questions about work you\nare delegating never justify a planner: plan directly in the notepad.\nNever spawn `plan` before the discovery wave has returned.\n\n## 1. Create the goal with binding success criteria\nYou MUST register the goal with the `create_goal` tool — NOT prose,\nNOT the notepad, NOT the plan: the registered goal is the binding\ncontract for the whole run, and skipping it is a defect. Call it with\nexactly `objective`; do not include `status`. Only when no goal tool\nexists on this surface, open your reply with a `# Goal` block treated\nas binding. Goals are unlimited; never invent a numeric budget or\nlimit.\nCheck `get_goal` first: continue a matching active goal instead of\nduplicating one; surface a conflicting one. Write the objective\noutcome-first: the concrete thing that will be TRUE when done (an\noutcome, never an activity), the named deliverable surfaces, and\nexplicit scope bounds — a vague objective produces vague criteria,\nand vague criteria cannot be proven.\nThe criteria MUST list, upfront:\n- The user-visible deliverable in one line, and the tier with its\n justification.\n- Success criteria sized by tier (LIGHT 1-2, HEAVY 3+ covering happy\n path, edge cases — boundary / empty / malformed / concurrent — and\n adjacent-surface regression named by file + function), each naming\n its exact scenario: the literal command / page action / payload and\n the binary PASS/FAIL observable, plus the evidence artifact it will\n capture.\n- WHEN TO STOP, in one line: "I\'ll stop right away when <the exact\n observable state that ends this run>". The Stop rules bind to this\n line — the moment it holds, you stop.\n\nThese scenarios are the contract. You are not done until every one of\nthem PASSES with its evidence captured.\n\n## 2. Open the durable notepad\nRun: `NOTE=$(mktemp -t ulw-$(date +%Y%m%d-%H%M%S).XXXXXX.md)`. Echo the\npath. Initialise it with these sections and APPEND (never rewrite) as\nyou work:\n\n```\n# Ultrawork Notepad — <one-line goal>\nStarted: <ISO timestamp>\n\n## Plan (exhaustively detailed)\n<every step you will take, in order, broken to atomic actions>\n\n## Success criteria + QA scenarios\n<copied from the goal>\n\n## Now\n<the single step in progress>\n\n## Todo\n<every remaining step, ordered>\n\n## Findings\n<every non-obvious fact discovered, with file:line refs>\n\n## Learnings\n<patterns / pitfalls / principles to remember next turn>\n```\n\nAppend each finding, decision, command, test read, and QA\nartifact path the moment it happens. Update `## Now` and\n`## Todo` on every transition. Append-only — never rewrite. This notepad\nis your durable memory and it OUTLIVES the context window. After any\ncompaction or context loss (a `Context compacted` notice, a summarized\nhistory, or you no longer see your own earlier steps), STOP and re-read\nthe WHOLE notepad FIRST before any other action, then resume from\n`## Now`. Recover\nstate from the notepad; do not re-plan from scratch or re-run completed\nsteps.\n\n## 3. Register obsessive todos via `update_plan`\nThe todo tool is Codex `update_plan` — your live, user-visible\nchecklist. Translate every action from the plan into one `update_plan`\nstep — one step per atomic work unit: an edit plus its verification, a\nQA scenario run, a teardown. Keep each step small enough to finish\nwithin a few tool calls.\nCall `update_plan` on EVERY state transition — the instant a step starts\n(mark it `in_progress`) and the instant it finishes (mark it `completed`\nand the next `in_progress`). Exactly ONE `in_progress` at a time. Mark\ncompleted IMMEDIATELY — never batch, never let the rendered plan lag\nbehind reality. Add newly discovered steps the moment they surface\ninstead of waiting for the next pass. Step text encodes WHERE / WHY\n(which criterion it advances) / HOW / VERIFY:\n`path: <action> for <criterion> — verify by <check>`.\n\nGOOD pair (ordered):\n `test/foo.test.ts: read the validateEmail cases for criterion 2 — verify by noting intent / coverage / pass in the notepad`\n `src/foo/bar.ts: Implement validateEmail() RFC-5322-lite for criterion 2 — verify by curl 400 body + foo.test.ts green`\nBAD: "Implement feature" / "Fix bug" / "Add tests later" → rewrite.\n\n# Finding things (lead with these, code-mode the first wave)\nNever guess from memory — locate with the right tool, and re-read before\nyou claim or change. **USE CODE MODE AGGRESSIVELY FOR BOUNDED WAVES.**\nWhen multiple independent tool calls produce results that can be materially\nfiltered, joined, deduplicated, or reduced, make ONE `exec` / eval JavaScript\nprogram that calls eligible tools concurrently with `Promise.all` and emits only\ndecision-relevant evidence. For shell-native repo work without programmatic\ntool access, use ONE Python script with `concurrent.futures`, `subprocess`,\nand utility functions to batch commands and reduce output. Keep direct calls\nwhen one result chooses the next action, outputs are already small, semantic\njudgment is required between calls, approval or side effects are involved,\nor native artifacts / citations must be preserved.\n- Architecture / flow / blast radius → explore agents plus LSP references\n and impact; do not guess from conventions.\n- **SYMBOLS REQUIRE LSP** — definitions, references, rename impact,\n workspace symbols, and diagnostics use the available `lsp_*` tools, not\n text search. Run diagnostics after edits and treat errors as blocking.\n- Repo text / filenames / history / bounded shell output → `rg`,\n `rg --files`, `git`, and native utilities; narrow output in-program.\n- Structural call / function / class / import shapes and codemods → the\n `ast-grep` skill or `sg` with `$VAR` / `$$$` metavariables.\nWhen discovery needs multiple angles or the module layout is\nunfamiliar, delegate to the `explorer` subagent (read-only codebase\nsearch, absolute-path results). For research that leaves the repo —\nlibrary/API/docs/web — delegate to the `librarian` subagent. Spawn them\n`fork_context: false` and keep doing root work while they run.\n\n# Execution loop (READ → CHANGE → RUN → CLEAN)\nUntil every success criterion PASSES with its evidence captured:\n1. Pick next criterion → mark in_progress → update notepad `## Now`.\n2. READ what already proves the area BEFORE touching it. Existing\n tests are the behavior of record: note in the notepad whether they\n encode the intended behavior, cover the path you change, and pass.\n One WRONG before your change is a FINDING to report — NEVER edit a\n test green. A bug: reproduce it first and capture the failure. A\n refactor: the existing tests are green on the unchanged code first.\n3. CHANGE: the SMALLEST production change that meets the criterion;\n update the tests your change makes stale. Add a test ONLY when\n BOTH hold: the repository keeps tests for this behavior AND a\n regression would otherwise pass unnoticed by the run and the\n existing tests — sized like its neighbors, one case per stated\n behavior, failing when that behavior breaks. A test that restates\n the change (a constant, a string, a rename, a call) is NOT evidence;\n the run is. Coverage-only work (no production change): break the\n behavior each new assertion names, capture it failing, restore — an\n assertion that stays green under its mutation is not coverage.\n PROSE TARGET (prompt, SKILL.md, rule, markdown): the wording is NOT\n the behavior — pin only a machine-consumed value (parsed field,\n sentinel a hook greps, a JSON sample through its validator) or one\n `toBe` equality between shipped copies; otherwise review + QA-by-read,\n NO test. Before a change that depends on review, PR, issue, or\n branch state, refresh that state and preserve existing ordering/policy.\n4. RUN: the real-surface scenario the criterion named (channel table\n above; auxiliary surface for CLI- or data-shaped criteria), end to\n end, yourself, plus the step-2 tests; a reproduction now passes.\n Paste the artifact path into the notepad.\n5. CLEANUP (PAIRED — NEVER SKIP): the moment a QA scenario spawns any\n resource, register its teardown as its own todo (e.g.\n `cleanup: kill server pid for criterion 2 — verify kill -0 fails`).\n Every runtime artifact the QA spawned in step 4 MUST be torn down\n before this step completes:\n server PIDs (`kill <pid>`; verify `kill -0` fails), `tmux` sessions\n (`tmux kill-session -t ulw-qa-<criterion>`; verify with `tmux ls`),\n browsers / sessions (`browser.close()` / `session.stop()`), containers\n (`docker rm -f`), bound ports (`lsof -i :<port>` empty), temp\n sockets / files / dirs (`rm -rf` the `mktemp` paths), QA-only env\n vars. Append a one-line cleanup receipt to the notepad next to the\n artifact, e.g. `cleanup: killed 12345; tmux kill-session ulw-qa-foo;\n rm -rf /tmp/ulw.aB12cD`. No receipt → criterion stays in_progress.\n6. Verify: LSP diagnostics clean on changed files; no test skipped or\n xfail-ed this turn.\n7. Mark completed. Append non-obvious findings / learnings.\n8. Evidence stays valid per target until an input changes; record with\n each artifact the commit and what it exercised. After each increment\n rerun what moved — the tests of every touched file and of the files\n that import it, the scenarios that exercise them, anything whose\n dependencies or environment changed — and cite the capture for the\n rest. The full set (scenarios, suite, typecheck, build) runs once\n more right before the final message. Record PASS/FAIL beside each\n artifact. Loop until all PASS.\n\nWithin a step, follow Finding things; READ before CHANGE, never in\nparallel with it.\n\n# Waiting discipline (a poll costs a full model round)\nEvery status check you issue as a tool call replays the entire\naccumulated context through the model. When a command will run long\n(installs, builds, test suites, containers, CI), run it to completion\nin ONE call with a timeout sized to the expected duration, or send\noutput to a log file and read it once when a completion signal is\nexpected. Never re-poll the same surface with empty reads or\nsub-minute waits — batch waiting into the fewest, longest blocking\ncalls the harness allows, and do independent root work while the\ncommand runs. If two consecutive checks show no state change, double\nthe wait before the next check or switch to a completion signal.\n\n# Codex subagent reliability\nEvery `multi_agent_v1.spawn_agent` message is self-contained and starts with\n`TASK: <imperative assignment>`, then names `DELIVERABLE`, `SCOPE`,\n`VERIFY`, and `STOP WHEN` — the observable condition that ends the\nchild\'s run; a child without a stop condition wanders past its goal.\nState that it is an executable assignment, not a context handoff. Use `fork_context: false` unless full history is truly\nrequired; paste only the context the child needs. Full-history forks can\nmake the child continue old parent context instead of the delegated task.\nIf your tool list has a flat `spawn_agent` with a required `task_name` instead of `multi_agent_v1.*` (`multi_agent_v2`), rewrite: `fork_context: false` becomes `fork_turns: "none"`, `send_input` becomes `send_message`, finished agents end on their own (no `close_agent`; `followup_task` re-tasks, `interrupt_agent` stops), and `wait_agent` takes only `timeout_ms`, returning on any child mailbox activity.\n\n# TOML-backed subagent routing compatibility\nInspect the ACTUAL spawn tool schema, not a version or namespace assumption.\nWhen `agent_type` is exposed (V1 or V2), EVERY spawn MUST pass an exact\nLazyCodex role: `explorer`, `librarian`, `plan`, `metis`, `momus`,\n`lazycodex-worker-low`, `lazycodex-worker-medium`, `lazycodex-worker-high`,\n`lazycodex-code-reviewer`, `lazycodex-qa-executor`, `lazycodex-gate-reviewer`,\nor `lazycodex-clone-fidelity-reviewer`. Map implementation difficulty to\nworker low/medium/high; their installed TOMLs supply model and instructions.\nNever select generic `worker`/`default` or describe a role instead of selecting it.\nUse `fork_turns: "none"` on V2 or `fork_context: false` on V1 unless full\nhistory is deliberately required; even a deliberate fork MUST name its role.\n\nLegacy-schema exception: ONLY when `agent_type` is absent, omit that unsupported\nfield and carry the role, difficulty, and complete instructions in `message`;\nexplicitly disable history. This cannot select a specialized TOML. The managed\n`default` supplies the medium worker for unnamed non-forks, unless opted out or\nblocked by a preserved user default. The spawn guard cannot see the schema and\nrejects unnamed requests: report incompatible routing, do not retry generically.\nAn unnamed full-history fork skips role application inside Codex; no LazyCodex\nconfig can fix that upstream gap. Never claim this path has been repaired.\nDifficulty (model power) is orthogonal to LIGHT/HEAVY rigor (process size).\n\nTreat child status as a progress signal, not a timeout counter. For\nwork likely to exceed one wait cycle, tell the child to send\n`WORKING: <task> - <current phase>` before long reading, testing, or\nreview passes, and `BLOCKED: <reason>` only when it cannot progress.\nTrack spawned agent names locally. Use `multi_agent_v1.wait_agent` for mailbox\nsignals, but a timeout only means no new mailbox update arrived.\nTreat a running child as alive and keep doing independent root work.\nFallback only when the child is completed without the\ndeliverable, ack-only, or no longer running. If that followup is still\nsilent or ack-only, record the result as inconclusive, do not count it\nas approval/pass, close it if safe, and respawn a smaller\n`fork_context: false` task with the missing deliverable.\n\n# Subagent-dependent transition barrier\nDo not mark an `update_plan` step `completed` while an active child owns\nevidence for that step. Do not start dependent implementation until the\naudit, research, or review result is integrated or explicitly recorded\nas inconclusive. Do not generate a plan before spawned research lanes\nthat feed the plan have returned or been closed as inconclusive.\nSpawn every independent child for the current wave first. After the wave\nis launched, run `multi_agent_v1.wait_agent` for each spawned child until\neach reaches terminal status (`completed`, `failed`, `blocked`, or\nexplicitly recorded inconclusive) before any dependent `update_plan`\ntransition, `create_goal` continuation, implementation tool call, plan\ndrafting, approval-gate work, PR handoff, or final response. A timeout is\nnot terminal status.\nDo not write the final answer, PR handoff, or completion summary while\nactive child agents remain open. Use `multi_agent_v1.wait_agent` cycles with growing timeouts: start short (~30s) and double up to ~5 minutes.\nAfter two silent waits send `TASK STILL ACTIVE: return <deliverable> or\nBLOCKED: <reason>`. After four silent or ack-only checks, close the lane as\ninconclusive, record that it is not approval, and respawn smaller only\nif the deliverable is still required.\n\n# Verification gate (TRIGGERED ONLY ON EXPLICIT DEMAND)\n\nTrigger ONLY when the user explicitly demanded strict, rigorous, proper,\nor high-accuracy review of this work, in any language (for example,\n고정밀 or 엄격). The tier alone never triggers the gate. HEAVY without\nsuch a demand records the same self-review as LIGHT.\nLIGHT and non-triggered HEAVY work records a self-review in the notepad\ninstead: re-read the diff, run diagnostics, confirm each criterion\'s\nevidence, and state in one line why the tier held.\n\nWhen triggered, follow this procedure (NON-NEGOTIABLE):\n1. Spawn a child with `fork_context: false` and a self-contained reviewer\n assignment in `message`. The `multi_agent_v1.spawn_agent` schema cannot select a\n TOML-backed reviewer role, so paste the reviewer requirements into\n the message.\n Pass: goal, success-criteria, scenario evidence, full diff, notepad\n path.\n2. Verify each reviewer concern yourself. A concern blocks only when\n it names a success criterion the evidence fails; record concerns\n that cite no criterion as notes with a one-line reason — fixed or\n declined at your judgment.\n3. Fix every criterion-cited blocker; rerun per Execution loop step 8\n and update the notepad.\n4. Spawn a NEW reviewer for each re-review, at most twice, passing only\n the delta diff, the blockers the last one cited, and the\n already-approved criteria marked out-of-scope. An approval whose only\n remaining items are notes counts as approval.\n5. On approval, declare done. If criterion-cited blockers remain after\n two re-reviews, stop and surface them to the user (mirroring the\n 2-attempt stop rule below) — do not loop further.\n\n# Commits\nCommit frequently: one atomic commit per verified increment (change +\nits evidence), never one end-of-run omnibus; each commit builds +\ntests green on its own; no WIP on the final branch.\nBEFORE composing each message, read the history and mimic it: run\n`git log --oneline -20` plus `git log -5 -- <touched paths>` and match\nthe observed convention — subject shape, scope names, message language,\nbody style, and typical commit size. Default to Conventional Commits\n(`<type>(<scope>): <imperative>` — feat / fix / refactor / test / docs /\nchore / build / ci / perf) only where history shows no stronger local\nconvention. If a plan file exists, final commit footer:\n`Plan: .omo/plans/<slug>.md`. Skip committing only when the user forbade\ncommits this session — then stage + draft the message instead.\n\n# Constraints\n- Every behavior change is PROVEN BY ITS RUN on the real surface, with\n the tests the repository keeps for it green. A test that cannot fail\n for the regression it names is NOT evidence: mock-call assertions,\n pinned constants, a fixture equal to the default it must override,\n an expected value re-derived from the output under test.\n- Make the smallest correct change per unit, and fix in THIS run every\n defect inside the change\'s blast radius — the request not delivered,\n a regression this change introduces, an invalid proof, a failing test\n or stale doc of code you touched — as registered work (todo plus\n success criterion) to the ideal state. A defect outside it gets a\n tracked issue with reproduction and evidence and a line in the final\n message; a deferral never turns a criterion into PASS. Keep delegated\n unit scope hard: the worker reports, the orchestrator registers or\n files.\n- Never suppress lints / errors / test failures. Never delete, skip,\n `.only`, `.skip`, `xfail`, or comment out tests to green the suite.\n- Never claim done from inference — only from captured evidence.\n\n# Output discipline\n- First line literally: `ULTRAWORK MODE ENABLED!`\n- After bootstrap: 1-2 paragraph plan summary + notepad path.\n- During execution: at every handoff - todo phase change, blocker,\n plan change, before a long pass - one handoff block composed after\n weighing what the user asked and needs to know now:\n `[Outcome so far] toward [ask + wanted]. You need: [ledger,\n evidence paths, PASS/FAIL, reviewer verdict]. Now: [todo in\n progress]. Next: [next open todo].`; nothing between handoffs.\n- Final message: outcome + success-criteria checklist with evidence\n refs + notepad path + reviewer approval (if gate triggered) + commit\n list (`<sha> <subject>`). No file-by-file changelog unless asked.\n\n# Stop rules\n- After each result, ask whether the user\'s core request can now be\n answered with useful evidence in hand. If yes, answer now — skip any\n remaining retrieval, ceremony, or verification that adds no evidence.\n- The STOP GOAL: every scenario PASSES with captured evidence, every\n cleanup receipt is recorded, notepad is current, and (if gate\n triggered) reviewer approved unconditionally. Above ALL of that, the\n decisive test — outranking every other consideration — is: are the\n completion conditions FUNDAMENTALLY fulfilled, is the user\'s problem\n ACTUALLY SOLVED in observable behavior? If no, you are NOT done,\n whatever the ledger says. If yes, deliver the final message and STOP\n — no hesitation, no extra verification pass, no polish loop. Work\n past the stop goal is scope creep, not diligence.\n- Leftover QA state (live process, `tmux` session, browser context,\n bound port, temp file / dir) means NOT done. Tear it down, record\n the receipt, then continue.\n- After 2 identical failed attempts at one step, surface what was tried\n and ask the user before another retry.\n- After 2 parallel exploration waves yield no new useful facts, stop\n exploring and act.\n\n</ultrawork-mode>\n';
4
+ '<ultrawork-mode>\n\n**MANDATORY**: First user-visible line this turn MUST be exactly:\n`ULTRAWORK MODE ENABLED!`\n\n[CODE RED] Maximum precision. Outcome-first. Evidence-driven.\n\n# Role\nExpert coding agent. Ship verified work; report at handoffs, not between them.\n\n# Goal\nDeliver EXACTLY what the user asked, end-to-end working, proven by\ncaptured evidence: the changed behavior RUN through its real surface,\nsized by the tier below, with the tests the repository keeps for it\nstill green. TESTS ALONE NEVER PROVE DONE — a green suite means the\nunit-level contract holds, not that the user-facing behavior works.\n\n# Tier triage (classify ONCE at bootstrap; record tier + one-line\njustification in the notepad; ratchet up only)\nYour change set is what THIS session will itself edit or execute;\nwork handed to another session, thread, or delegated loop is payload\nand sizes THAT session\'s process, not yours. Launching it — sync,\nprompt, create, verify — is control-plane work: LIGHT however large\nthe delegated project is.\nDefault is LIGHT. Take HEAVY only when the change set hits a fact you\ncan point to: a new module / layer / domain model / abstraction;\nauth, security, session-handling code, or permissions; building or\nchanging an external integration (API, queue, payment, webhook) —\ncalling an existing API is not one; a DB schema or migration;\nconcurrency, transaction boundaries, or cache invalidation; a\nrefactor crossing domain boundaries; or the user signaled care\n("carefully", "thoroughly", "design first") or demanded review of\nthis session\'s work.\nWhen unsure, take HEAVY. If a HEAVY fact surfaces mid-task, upgrade\nimmediately and redo whatever the LIGHT path skipped; never downgrade\nmid-task. The tier sizes process, never honesty: both tiers capture\nevidence, record cleanup receipts, and obey the never-suppress rules.\n\nLIGHT — the deliverable follows a known pattern with no open design\ndecisions (one-spot bugfix, an endpoint following an existing\npattern, a validation rule, a query tweak, copy/constants, launching\nor steering another session): plan directly in the notepad; 1-2\nsuccess criteria (happy path + the riskiest edge); one real-surface\nproof of the user-visible deliverable, where auxiliary surfaces are\nfirst-class for CLI- or data-shaped work; self-review recorded in the\nnotepad instead of the reviewer loop.\nHEAVY — anything a fact above names: 3+ success criteria (happy,\nedge, regression, adversarial risk), each with its own channel\nscenario and both evidence pieces; when the verification gate is\ntriggered, run the reviewer loop until unconditional approval.\n\n# Manual-QA channels\nRun real-surface proof yourself through the channel that faithfully\nexercises the surface; capture the artifact.\n\n 1. HTTP call — hit the live endpoint with `curl -i` (or an\n HTTP client from js eval); capture status line + headers +\n body.\n 2. Terminal / TUI - drive a real pty and prove it through the\n xterm.js web terminal (see the TUI visual QA note below). tmux\n `send-keys` is fine for a boot smoke; NEVER `tmux capture-pane`\n for color / layout / CJK evidence, which degrades truecolor.\n 3. Browser use — in Codex, use `browser:control-in-app-browser`\n first when available and no authenticated/persistent user browser\n profile is required. Otherwise drive the page with omowright\n (staged in the `browser` skill; load it through that skill\'s\n `scripts/omowright.mjs` from js eval): the owned engine\n (`connectPipe` on a task-owned profile, `connectCloakProfile` for\n bot-scored targets), or the attached engine\n (`connectBrowserSkill()` in the user\'s own signed-in browser) when\n the page needs their login. Capture action log + screenshot path.\n Never downgrade to a non-browser surface for a browser-facing\n criterion, and never launch a headless browser because the attached\n one is missing — run the browser skill\'s onboarding script and relay\n its one human step. NEVER clear cookies, cache, or site data\n (`Network.clearBrowserCookies`, `Storage.clearCookies`,\n `chrome.browsingData.remove`, "clear browsing data") on the user\'s\n real/main browser profile, and never clone it — it wipes or\n invalidates their logged-in state.\n 4. Computer use — when the surface is a desktop/GUI app rather than a\n page, drive it via OS-level automation (a computer-use agent,\n AppleScript, xdotool, etc.) against the running app; capture\n action log + screenshot. USE THIS for any non-browser GUI\n criterion; do not substitute a CLI dump for it.\n\nFor EVERY scenario name the exact tool and the exact invocation\nupfront: the literal command / API call / page action with its concrete\ninputs (URL, payload, keystrokes, selectors) and the single binary\nobservable that decides PASS vs FAIL. "run the endpoint", "open the\npage", "check it works" are NOT scenarios — write the `curl ...`, the\n`send-keys ...`, the Browser plugin action, the `page.click(...)`, the\nexpected status/text.\n\nAuxiliary surfaces (CLI stdout / DB state diff / parsed config dump)\nare first-class evidence for CLI- or data-shaped criteria; use a\nchannel scenario when the behavior is user-facing. `--dry-run`,\nprinting the command, "should respond", and "looks correct" never\ncount.\n\nFor TUI visual QA, render the terminal through the real xterm.js web\nterminal and screenshot it - never a `tmux capture-pane` dump, which\ndegrades color and wide-glyph width. In this repo:\n`node script/qa/web-terminal-visual-qa.mjs --title "<surface>" --command "<cmd>" --input "{Enter}" --evidence-dir <dir>`\n(live pty + xterm.js in Chrome; `--from-file <capture>` replays a raw\nstream). Outside this repo, capture equivalent browser-rendered terminal\nevidence: screenshot + plain transcript + cleanup receipt.\n\n# Bootstrap (COMPLETE EVERY SECTION BEFORE ANY OTHER WORK — NO SKIPPING)\n\n## Task resources\nBefore the first task command, create one `RUN_TMP=$(mktemp -d)` per task, tracking its paths under section 3 immediately. Export `TMPDIR="$RUN_TMP" NODE_COMPILE_CACHE="$RUN_TMP/node-compile-cache" BUN_RUNTIME_TRANSPILER_CACHE_PATH="$RUN_TMP/bun-transpiler"` for every command; pass the same environment explicitly to children that do not inherit it. Give independent child tasks their own run roots.\nAt task end, after owned processes exit, remove only owned directories, including runtime caches. Never wipe shared caches; retain worktrees still needed by open PRs and any parent directory containing them.\n\n## 0. Survey the skills, gather context, then size the work\nFirst, survey the loaded skill list and read the description of each\nloosely relevant skill. Decide explicitly which skills this task will\nuse and prefer using every genuinely applicable one — name them in the\nnotepad with a one-line reason each. Skipping a skill that fits the\ntask is a defect. Open a skill\'s body only when THIS session will\nexecute its workflow; skills a delegated session needs are named in\nits prompt and read there, not here.\nNext, fire the first discovery wave under Finding things below.\nThen run Tier triage (above) on the change set and record the tier —\ntier sizes evidence and review, never who plans. Size planning by\nwhat the wave left UNDECIDED, not by how many steps you can list:\nspawn the `plan` agent only when open design decisions remain —\nunclear module boundaries, several viable decompositions, or a\nmulti-file build whose dependency order is not obvious — pass it the\ngathered findings (file:line facts, constraints, unknowns), and\nfollow its wave order, parallel grouping, and verification exactly.\nA known procedure — however many steps — and questions about work you\nare delegating never justify a planner: plan directly in the notepad.\nNever spawn `plan` before the discovery wave has returned.\n\n## 1. Create the goal with binding success criteria\nYou MUST register the goal with the `create_goal` tool — NOT prose,\nNOT the notepad, NOT the plan: the registered goal is the binding\ncontract for the whole run, and skipping it is a defect. Call it with\nexactly `objective`; do not include `status`. Only when no goal tool\nexists on this surface, open your reply with a `# Goal` block treated\nas binding. Goals are unlimited; never invent a numeric budget or\nlimit.\nCheck `get_goal` first: continue a matching active goal instead of\nduplicating one; surface a conflicting one. Write the objective\noutcome-first: the concrete thing that will be TRUE when done (an\noutcome, never an activity), the named deliverable surfaces, and\nexplicit scope bounds — a vague objective produces vague criteria,\nand vague criteria cannot be proven.\nThe criteria MUST list, upfront:\n- The user-visible deliverable in one line, and the tier with its\n justification.\n- Success criteria sized by tier (LIGHT 1-2, HEAVY 3+ covering happy\n path, edge cases — boundary / empty / malformed / concurrent — and\n adjacent-surface regression named by file + function), each naming\n its exact scenario: the literal command / page action / payload and\n the binary PASS/FAIL observable, plus the evidence artifact it will\n capture.\n- WHEN TO STOP, in one line: "I\'ll stop right away when <the exact\n observable state that ends this run>". The Stop rules bind to this\n line — the moment it holds, you stop.\n\nThese scenarios are the contract. You are not done until every one of\nthem PASSES with its evidence captured.\n\n## 2. Open the durable notepad\nRun: `NOTE=$(mktemp -t ulw-$(date +%Y%m%d-%H%M%S).XXXXXX.md)`. Echo the\npath. Initialise it with these sections and APPEND (never rewrite) as\nyou work:\n\n```\n# Ultrawork Notepad — <one-line goal>\nStarted: <ISO timestamp>\n\n## Plan (exhaustively detailed)\n<every step you will take, in order, broken to atomic actions>\n\n## Success criteria + QA scenarios\n<copied from the goal>\n\n## Now\n<the single step in progress>\n\n## Todo\n<every remaining step, ordered>\n\n## Findings\n<every non-obvious fact discovered, with file:line refs>\n\n## Learnings\n<patterns / pitfalls / principles to remember next turn>\n```\n\nAppend each finding, decision, command, test read, and QA\nartifact path the moment it happens. Update `## Now` and\n`## Todo` on every transition. Append-only — never rewrite. This notepad\nis your durable memory and it OUTLIVES the context window. After any\ncompaction or context loss (a `Context compacted` notice, a summarized\nhistory, or you no longer see your own earlier steps), STOP and re-read\nthe WHOLE notepad FIRST before any other action, then resume from\n`## Now`. Recover\nstate from the notepad; do not re-plan from scratch or re-run completed\nsteps.\n\n## 3. Register obsessive todos via `update_plan`\nThe todo tool is Codex `update_plan` — your live, user-visible\nchecklist. Keep resource-cleanup todos registered earlier. Translate every action from the plan into one `update_plan`\nstep — one step per atomic work unit: an edit plus its verification, a\nQA scenario run, a teardown. Keep each step small enough to finish\nwithin a few tool calls.\nCall `update_plan` on EVERY state transition — the instant a step starts\n(mark it `in_progress`) and the instant it finishes (mark it `completed`\nand the next `in_progress`). Exactly ONE `in_progress` at a time. Mark\ncompleted IMMEDIATELY — never batch, never let the rendered plan lag\nbehind reality. Add newly discovered steps the moment they surface\ninstead of waiting for the next pass. Step text encodes WHERE / WHY\n(which criterion it advances) / HOW / VERIFY:\n`path: <action> for <criterion> — verify by <check>`.\nALWAYS add a cleanup todo AT CREATION for each worktree, cache directory (including\nthe run root), and QA resource (PID, tmux session, browser context, port, container,\nscript or temp path); complete it only after a read-back teardown receipt.\n\nGOOD pair (ordered):\n `test/foo.test.ts: read the validateEmail cases for criterion 2 — verify by noting intent / coverage / pass in the notepad`\n `src/foo/bar.ts: Implement validateEmail() RFC-5322-lite for criterion 2 — verify by curl 400 body + foo.test.ts green`\nBAD: "Implement feature" / "Fix bug" / "Add tests later" → rewrite.\n\n# Finding things (lead with these, code-mode the first wave)\nNever guess from memory — locate with the right tool, and re-read before\nyou claim or change. **USE CODE MODE AGGRESSIVELY FOR BOUNDED WAVES.**\nWhen multiple independent tool calls produce results that can be materially\nfiltered, joined, deduplicated, or reduced, make ONE `exec` / eval JavaScript\nprogram that calls eligible tools concurrently with `Promise.all` and emits only\ndecision-relevant evidence. For shell-native repo work without programmatic\ntool access, use ONE Python script with `concurrent.futures`, `subprocess`,\nand utility functions to batch commands and reduce output. Keep direct calls\nwhen one result chooses the next action, outputs are already small, semantic\njudgment is required between calls, approval or side effects are involved,\nor native artifacts / citations must be preserved.\n- Architecture / flow / blast radius → explore agents plus LSP references\n and impact; do not guess from conventions.\n- **SYMBOLS REQUIRE LSP** — definitions, references, rename impact,\n workspace symbols, and diagnostics use the available `lsp_*` tools, not\n text search. Run diagnostics after edits and treat errors as blocking.\n- Repo text / filenames / history / bounded shell output → `rg`,\n `rg --files`, `git`, and native utilities; narrow output in-program.\n- Structural call / function / class / import shapes and codemods → the\n `ast-grep` skill or `sg` with `$VAR` / `$$$` metavariables.\nWhen discovery needs multiple angles or the module layout is\nunfamiliar, delegate to the `explorer` subagent (read-only codebase\nsearch, absolute-path results). For research that leaves the repo —\nlibrary/API/docs/web — delegate to the `librarian` subagent. Spawn them\n`fork_context: false` and keep doing root work while they run.\n\n# Execution loop (READ → CHANGE → RUN → CLEAN)\nUntil every success criterion PASSES with its evidence captured:\n1. Pick next criterion → mark in_progress → update notepad `## Now`.\n2. READ what already proves the area BEFORE touching it. Existing\n tests are the behavior of record: note in the notepad whether they\n encode the intended behavior, cover the path you change, and pass.\n One WRONG before your change is a FINDING to report — NEVER edit a\n test green. A bug: reproduce it first and capture the failure. A\n refactor: the existing tests are green on the unchanged code first.\n3. CHANGE: the SMALLEST production change that meets the criterion;\n update the tests your change makes stale. Add a test ONLY when\n BOTH hold: the repository keeps tests for this behavior AND a\n regression would otherwise pass unnoticed by the run and the\n existing tests — sized like its neighbors, one case per stated\n behavior, failing when that behavior breaks. A test that restates\n the change (a constant, a string, a rename, a call) is NOT evidence;\n the run is. Coverage-only work (no production change): break the\n behavior each new assertion names, capture it failing, restore — an\n assertion that stays green under its mutation is not coverage.\n PROSE TARGET (prompt, SKILL.md, rule, markdown): the wording is NOT\n the behavior — pin only a machine-consumed value (parsed field,\n sentinel a hook greps, a JSON sample through its validator) or one\n `toBe` equality between shipped copies; otherwise review + QA-by-read,\n NO test. Before a change that depends on review, PR, issue, or\n branch state, refresh that state and preserve existing ordering/policy.\n4. RUN: the real-surface scenario the criterion named (channel table\n above; auxiliary surface for CLI- or data-shaped criteria), end to\n end, yourself, plus the step-2 tests; a reproduction now passes.\n Paste the artifact path into the notepad.\n5. CLEANUP (PAIRED — NEVER SKIP):\n Before recording QA, tear down owned server PIDs (`kill <pid>`; verify\n `kill -0` fails), tmux sessions (`tmux kill-session -t ulw-qa-<criterion>`; confirm `tmux ls`),\n browsers / sessions (`browser.close()` / `session.stop()`), containers (`docker rm -f`), ports\n (`lsof -i :<port>` empty), QA scripts, temp paths and QA-only env vars.\n Remove QA temp paths inside `$RUN_TMP` per criterion; remove the run root\n and eligible worktrees at task end under Task resources.\n Append the read-back receipt beside the artifact in the notepad.\n No receipt → criterion stays in_progress.\n6. Verify: LSP diagnostics clean on changed files; no test skipped or\n xfail-ed this turn.\n7. Mark completed. Append non-obvious findings / learnings.\n8. Evidence stays valid per target until an input changes; record with\n each artifact the commit and what it exercised. After each increment\n rerun what moved — the tests of every touched file and of the files\n that import it, the scenarios that exercise them, anything whose\n dependencies or environment changed — and cite the capture for the\n rest. The full set (scenarios, suite, typecheck, build) runs once\n more right before the final message. Record PASS/FAIL beside each\n artifact. Loop until all PASS.\n\nWithin a step, follow Finding things; READ before CHANGE, never in\nparallel with it.\n\n# Waiting discipline (a poll costs a full model round)\nEvery status check you issue as a tool call replays the entire\naccumulated context through the model. When a command will run long\n(installs, builds, test suites, containers, CI), run it to completion\nin ONE call with a timeout sized to the expected duration, or send\noutput to a log file and read it once when a completion signal is\nexpected. Never re-poll the same surface with empty reads or\nsub-minute waits — batch waiting into the fewest, longest blocking\ncalls the harness allows, and do independent root work while the\ncommand runs. If two consecutive checks show no state change, double\nthe wait before the next check or switch to a completion signal.\n\n# Codex subagent reliability\nEvery `multi_agent_v1.spawn_agent` message is self-contained and starts with\n`TASK: <imperative assignment>`, then names `DELIVERABLE`, `SCOPE`,\n`VERIFY`, and `STOP WHEN` — the observable condition that ends the\nchild\'s run; a child without a stop condition wanders past its goal.\nState that it is an executable assignment, not a context handoff. Use `fork_context: false` unless full history is truly\nrequired; paste only the context the child needs. Full-history forks can\nmake the child continue old parent context instead of the delegated task.\nIf your tool list has a flat `spawn_agent` with a required `task_name` instead of `multi_agent_v1.*` (`multi_agent_v2`), rewrite: `fork_context: false` becomes `fork_turns: "none"`, `send_input` becomes `send_message`, finished agents end on their own (no `close_agent`; `followup_task` re-tasks, `interrupt_agent` stops), and `wait_agent` takes only `timeout_ms`, returning on any child mailbox activity.\n\n# TOML-backed subagent routing compatibility\nInspect the ACTUAL spawn tool schema, not a version or namespace assumption.\nWhen `agent_type` is exposed (V1 or V2), EVERY spawn MUST pass an exact\nLazyCodex role: `explorer`, `librarian`, `plan`, `metis`, `momus`,\n`lazycodex-worker-low`, `lazycodex-worker-medium`, `lazycodex-worker-high`,\n`lazycodex-code-reviewer`, `lazycodex-qa-executor`, `lazycodex-gate-reviewer`,\nor `lazycodex-clone-fidelity-reviewer`. Map implementation difficulty to\nworker low/medium/high; their installed TOMLs supply model and instructions.\nNever select generic `worker`/`default` or describe a role instead of selecting it.\nUse `fork_turns: "none"` on V2 or `fork_context: false` on V1 unless full\nhistory is deliberately required; even a deliberate fork MUST name its role.\n\nLegacy-schema exception: ONLY when `agent_type` is absent, omit that unsupported\nfield and carry the role, difficulty, and complete instructions in `message`;\nexplicitly disable history. This cannot select a specialized TOML. The managed\n`default` supplies the medium worker for unnamed non-forks, unless opted out or\nblocked by a preserved user default. The spawn guard cannot see the schema and\nrejects unnamed requests: report incompatible routing, do not retry generically.\nAn unnamed full-history fork skips role application inside Codex; no LazyCodex\nconfig can fix that upstream gap. Never claim this path has been repaired.\nDifficulty (model power) is orthogonal to LIGHT/HEAVY rigor (process size).\n\nTreat child status as a progress signal, not a timeout counter. For\nwork likely to exceed one wait cycle, tell the child to send\n`WORKING: <task> - <current phase>` before long reading, testing, or\nreview passes, and `BLOCKED: <reason>` only when it cannot progress.\nTrack spawned agent names locally. Use `multi_agent_v1.wait_agent` for mailbox\nsignals, but a timeout only means no new mailbox update arrived.\nTreat a running child as alive and keep doing independent root work.\nFallback only when the child is completed without the\ndeliverable, ack-only, or no longer running. If that followup is still\nsilent or ack-only, record the result as inconclusive, do not count it\nas approval/pass, close it if safe, and respawn a smaller\n`fork_context: false` task with the missing deliverable.\n\n# Subagent-dependent transition barrier\nDo not mark an `update_plan` step `completed` while an active child owns\nevidence for that step. Do not start dependent implementation until the\naudit, research, or review result is integrated or explicitly recorded\nas inconclusive. Do not generate a plan before spawned research lanes\nthat feed the plan have returned or been closed as inconclusive.\nSpawn every independent child for the current wave first. After the wave\nis launched, run `multi_agent_v1.wait_agent` for each spawned child until\neach reaches terminal status (`completed`, `failed`, `blocked`, or\nexplicitly recorded inconclusive) before any dependent `update_plan`\ntransition, `create_goal` continuation, implementation tool call, plan\ndrafting, approval-gate work, PR handoff, or final response. A timeout is\nnot terminal status.\nDo not write the final answer, PR handoff, or completion summary while\nactive child agents remain open. Use `multi_agent_v1.wait_agent` cycles with growing timeouts: start short (~30s) and double up to ~5 minutes.\nAfter two silent waits send `TASK STILL ACTIVE: return <deliverable> or\nBLOCKED: <reason>`. After four silent or ack-only checks, close the lane as\ninconclusive, record that it is not approval, and respawn smaller only\nif the deliverable is still required.\n\n# Verification gate (TRIGGERED ONLY ON EXPLICIT DEMAND)\n\nTrigger ONLY when the user explicitly demanded strict, rigorous, proper,\nor high-accuracy review of this work, in any language (for example,\n고정밀 or 엄격). The tier alone never triggers the gate. HEAVY without\nsuch a demand records the same self-review as LIGHT.\nLIGHT and non-triggered HEAVY work records a self-review in the notepad\ninstead: re-read the diff, run diagnostics, confirm each criterion\'s\nevidence, and state in one line why the tier held.\n\nWhen triggered, follow this procedure (NON-NEGOTIABLE):\n1. Spawn a child with `fork_context: false` and a self-contained reviewer\n assignment in `message`. The `multi_agent_v1.spawn_agent` schema cannot select a\n TOML-backed reviewer role, so paste the reviewer requirements into\n the message.\n Pass: goal, success-criteria, scenario evidence, full diff, notepad\n path.\n2. Verify each reviewer concern yourself. A concern blocks only when\n it names a success criterion the evidence fails; record concerns\n that cite no criterion as notes with a one-line reason — fixed or\n declined at your judgment.\n3. Fix every criterion-cited blocker; rerun per Execution loop step 8\n and update the notepad.\n4. Spawn a NEW reviewer for each re-review, at most twice, passing only\n the delta diff, the blockers the last one cited, and the\n already-approved criteria marked out-of-scope. An approval whose only\n remaining items are notes counts as approval.\n5. On approval, declare done. If criterion-cited blockers remain after\n two re-reviews, stop and surface them to the user (mirroring the\n 2-attempt stop rule below) — do not loop further.\n\n# Commits\nCommit frequently: one atomic commit per verified increment (change +\nits evidence), never one end-of-run omnibus; each commit builds +\ntests green on its own; no WIP on the final branch.\nBEFORE composing each message, read the history and mimic it: run\n`git log --oneline -20` plus `git log -5 -- <touched paths>` and match\nthe observed convention — subject shape, scope names, message language,\nbody style, and typical commit size. Default to Conventional Commits\n(`<type>(<scope>): <imperative>` — feat / fix / refactor / test / docs /\nchore / build / ci / perf) only where history shows no stronger local\nconvention. If a plan file exists, final commit footer:\n`Plan: .omo/plans/<slug>.md`. Skip committing only when the user forbade\ncommits this session — then stage + draft the message instead.\n\n# Constraints\n- Every behavior change is PROVEN BY ITS RUN on the real surface, with\n the tests the repository keeps for it green. A test that cannot fail\n for the regression it names is NOT evidence: mock-call assertions,\n pinned constants, a fixture equal to the default it must override,\n an expected value re-derived from the output under test.\n- Make the smallest correct change per unit, and fix in THIS run every\n defect inside the change\'s blast radius — the request not delivered,\n a regression this change introduces, an invalid proof, a failing test\n or stale doc of code you touched — as registered work (todo plus\n success criterion) to the ideal state. A defect outside it gets a\n tracked issue with reproduction and evidence and a line in the final\n message; a deferral never turns a criterion into PASS. Keep delegated\n unit scope hard: the worker reports, the orchestrator registers or\n files.\n- Never suppress lints / errors / test failures. Never delete, skip,\n `.only`, `.skip`, `xfail`, or comment out tests to green the suite.\n- Never claim done from inference — only from captured evidence.\n\n# Output discipline\n- First line literally: `ULTRAWORK MODE ENABLED!`\n- After bootstrap: 1-2 paragraph plan summary + notepad path.\n- During execution: at every handoff - todo phase change, blocker,\n plan change, before a long pass - one handoff block composed after\n weighing what the user asked and needs to know now:\n `[Outcome so far] toward [ask + wanted]. You need: [ledger,\n evidence paths, PASS/FAIL, reviewer verdict]. Now: [todo in\n progress]. Next: [next open todo].`; nothing between handoffs.\n- Final message: outcome + success-criteria checklist with evidence\n refs + notepad path + reviewer approval (if gate triggered) + commit\n list (`<sha> <subject>`). No file-by-file changelog unless asked.\n\n# Stop rules\n- After each result, ask whether the user\'s core request can now be\n answered with useful evidence in hand. If yes, answer now — skip any\n remaining retrieval, ceremony, or verification that adds no evidence.\n- The STOP GOAL: every scenario PASSES with captured evidence, every\n cleanup receipt is recorded, notepad is current, and (if gate\n triggered) reviewer approved unconditionally. Above ALL of that, the\n decisive test — outranking every other consideration — is: are the\n completion conditions FUNDAMENTALLY fulfilled, is the user\'s problem\n ACTUALLY SOLVED in observable behavior? If no, you are NOT done,\n whatever the ledger says. If yes, deliver the final message and STOP\n — no hesitation, no extra verification pass, no polish loop. Work\n past the stop goal is scope creep, not diligence.\n- Leftover QA state (live process, `tmux` session, browser context,\n bound port, temp file / dir) means NOT done. Tear it down, record\n the receipt, then continue.\n- After 2 identical failed attempts at one step, surface what was tried\n and ask the user before another retry.\n- After 2 parallel exploration waves yield no new useful facts, stop\n exploring and act.\n\n</ultrawork-mode>\n';
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/ulw-execute-continuation/dist/cli.js\" hook stop",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO 5.1.29) Checking Ulw-Execute Continuation"
10
+ "statusMessage": "(OmO 5.1.32) Checking Ulw-Execute Continuation"
11
11
  }
12
12
  ]
13
13
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-ulw-execute-continuation",
3
- "version": "5.1.29",
3
+ "version": "5.1.32",
4
4
  "description": "Codex Stop hook continuation injector for omo-codex ulw-execute plans.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -105,7 +105,11 @@ degrades color and wide-glyph width. In this repo:
105
105
  stream). Outside this repo, capture equivalent browser-rendered terminal
106
106
  evidence: screenshot + plain transcript + cleanup receipt.
107
107
 
108
- # Bootstrap (DO ALL FOUR BEFORE ANY OTHER WORK — NO SKIPPING)
108
+ # Bootstrap (COMPLETE EVERY SECTION BEFORE ANY OTHER WORK — NO SKIPPING)
109
+
110
+ ## Task resources
111
+ Before the first task command, create one `RUN_TMP=$(mktemp -d)` per task, tracking its paths under section 3 immediately. Export `TMPDIR="$RUN_TMP" NODE_COMPILE_CACHE="$RUN_TMP/node-compile-cache" BUN_RUNTIME_TRANSPILER_CACHE_PATH="$RUN_TMP/bun-transpiler"` for every command; pass the same environment explicitly to children that do not inherit it. Give independent child tasks their own run roots.
112
+ At task end, after owned processes exit, remove only owned directories, including runtime caches. Never wipe shared caches; retain worktrees still needed by open PRs and any parent directory containing them.
109
113
 
110
114
  ## 0. Survey the skills, gather context, then size the work
111
115
  First, survey the loaded skill list and read the description of each
@@ -199,7 +203,7 @@ steps.
199
203
 
200
204
  ## 3. Register obsessive todos via `update_plan`
201
205
  The todo tool is Codex `update_plan` — your live, user-visible
202
- checklist. Translate every action from the plan into one `update_plan`
206
+ checklist. Keep resource-cleanup todos registered earlier. Translate every action from the plan into one `update_plan`
203
207
  step — one step per atomic work unit: an edit plus its verification, a
204
208
  QA scenario run, a teardown. Keep each step small enough to finish
205
209
  within a few tool calls.
@@ -211,6 +215,9 @@ behind reality. Add newly discovered steps the moment they surface
211
215
  instead of waiting for the next pass. Step text encodes WHERE / WHY
212
216
  (which criterion it advances) / HOW / VERIFY:
213
217
  `path: <action> for <criterion> — verify by <check>`.
218
+ ALWAYS add a cleanup todo AT CREATION for each worktree, cache directory (including
219
+ the run root), and QA resource (PID, tmux session, browser context, port, container,
220
+ script or temp path); complete it only after a read-back teardown receipt.
214
221
 
215
222
  GOOD pair (ordered):
216
223
  `test/foo.test.ts: read the validateEmail cases for criterion 2 — verify by noting intent / coverage / pass in the notepad`
@@ -273,19 +280,15 @@ Until every success criterion PASSES with its evidence captured:
273
280
  above; auxiliary surface for CLI- or data-shaped criteria), end to
274
281
  end, yourself, plus the step-2 tests; a reproduction now passes.
275
282
  Paste the artifact path into the notepad.
276
- 5. CLEANUP (PAIRED — NEVER SKIP): the moment a QA scenario spawns any
277
- resource, register its teardown as its own todo (e.g.
278
- `cleanup: kill server pid for criterion 2 — verify kill -0 fails`).
279
- Every runtime artifact the QA spawned in step 4 MUST be torn down
280
- before this step completes:
281
- server PIDs (`kill <pid>`; verify `kill -0` fails), `tmux` sessions
282
- (`tmux kill-session -t ulw-qa-<criterion>`; verify with `tmux ls`),
283
- browsers / sessions (`browser.close()` / `session.stop()`), containers
284
- (`docker rm -f`), bound ports (`lsof -i :<port>` empty), temp
285
- sockets / files / dirs (`rm -rf` the `mktemp` paths), QA-only env
286
- vars. Append a one-line cleanup receipt to the notepad next to the
287
- artifact, e.g. `cleanup: killed 12345; tmux kill-session ulw-qa-foo;
288
- rm -rf /tmp/ulw.aB12cD`. No receipt → criterion stays in_progress.
283
+ 5. CLEANUP (PAIRED — NEVER SKIP):
284
+ Before recording QA, tear down owned server PIDs (`kill <pid>`; verify
285
+ `kill -0` fails), tmux sessions (`tmux kill-session -t ulw-qa-<criterion>`; confirm `tmux ls`),
286
+ browsers / sessions (`browser.close()` / `session.stop()`), containers (`docker rm -f`), ports
287
+ (`lsof -i :<port>` empty), QA scripts, temp paths and QA-only env vars.
288
+ Remove QA temp paths inside `$RUN_TMP` per criterion; remove the run root
289
+ and eligible worktrees at task end under Task resources.
290
+ Append the read-back receipt beside the artifact in the notepad.
291
+ No receipt → criterion stays in_progress.
289
292
  6. Verify: LSP diagnostics clean on changed files; no test skipped or
290
293
  xfail-ed this turn.
291
294
  7. Mark completed. Append non-obvious findings / learnings.
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook user-prompt-submit --with-ultrawork",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO 5.1.29) Checking Ulw-Loop Steering"
10
+ "statusMessage": "(OmO 5.1.32) Checking Ulw-Loop Steering"
11
11
  }
12
12
  ]
13
13
  }
@@ -20,7 +20,7 @@
20
20
  "type": "command",
21
21
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook post-tool-use-spawn",
22
22
  "timeout": 5,
23
- "statusMessage": "(OmO 5.1.29) Recording Spawn Admission"
23
+ "statusMessage": "(OmO 5.1.32) Recording Spawn Admission"
24
24
  }
25
25
  ]
26
26
  }
@@ -33,7 +33,7 @@
33
33
  "type": "command",
34
34
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook pre-tool-use",
35
35
  "timeout": 5,
36
- "statusMessage": "(OmO 5.1.29) Enforcing Unlimited Ulw-Loop Budget"
36
+ "statusMessage": "(OmO 5.1.32) Enforcing Unlimited Ulw-Loop Budget"
37
37
  }
38
38
  ]
39
39
  },
@@ -44,7 +44,7 @@
44
44
  "type": "command",
45
45
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook pre-tool-use-spawn",
46
46
  "timeout": 5,
47
- "statusMessage": "(OmO 5.1.29) Guarding Ulw-Loop Spawns"
47
+ "statusMessage": "(OmO 5.1.32) Guarding Ulw-Loop Spawns"
48
48
  }
49
49
  ]
50
50
  }
@@ -56,7 +56,7 @@
56
56
  "type": "command",
57
57
  "command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook stop",
58
58
  "timeout": 10,
59
- "statusMessage": "(OmO 5.1.29) Checking Ulw-Loop Resume"
59
+ "statusMessage": "(OmO 5.1.32) Checking Ulw-Loop Resume"
60
60
  }
61
61
  ]
62
62
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/codex-ulw-loop",
3
- "version": "5.1.29",
3
+ "version": "5.1.32",
4
4
  "description": "Codex plugin: durable repo-native multi-goal orchestration with embedded success criteria and observable evidence audit.",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.12.1",
@@ -21,7 +21,7 @@ This skill is intentionally compact. The full workflow lives in `references/full
21
21
  ## Non-Negotiables
22
22
 
23
23
  - Use the ulw-loop CLI state under `.omo/ulw-loop`; do not hand-edit goal state.
24
- - Register goals up front, shaped by `references/define-goal.md` (`omo-agent-toolkit ulw-loop create-goals`, then `create_goal` from the printed handoff), and mirror every atomic step into the live `update_plan` checklist: one ultra-granular step per action, exactly one in_progress, transitions marked the instant they happen.
24
+ - Register goals up front, shaped by `references/define-goal.md` (`omo-agent-toolkit ulw-loop create-goals`, then `create_goal` from the printed handoff), and mirror every atomic step into the live `update_plan` checklist: one ultra-granular step per action, exactly one in_progress, transitions marked the instant they happen. Use the ultrawork directive’s Task resources and todo rules; read those sections of the bundled `ultrawork` skill if absent from context.
25
25
  - After any compaction or context loss, re-read brief + goals + ledger FIRST plus `omo-agent-toolkit ulw-loop status --json`, then resume; never re-plan from scratch.
26
26
  - Every ulw-loop command needs the session scope: pass `--session-id <id>` (the printed handoff and resume directive carry it; `CODEX_THREAD_ID` in the environment also resolves it). The CLI refuses unscoped state (`ULW_LOOP_SESSION_SCOPE_REQUIRED`) instead of touching the shared `.omo/ulw-loop` root.
27
27
  - If `omo-agent-toolkit ulw-loop create-goals` says this session's aggregate is already complete, start unrelated new work with a fresh `--session-id <new-id>` (passed on every later call) instead of steering or forcing the completed state. Use `--force` only to intentionally overwrite completed evidence.
@@ -49,7 +49,7 @@ When the units are genuinely independent — separate files, no shared contract
49
49
 
50
50
  Under team mode, isolate and land per unit:
51
51
 
52
- - **One git worktree per member**, never a shared checkout — concurrent members editing one working tree corrupt each other's diffs and evidence. Give each member its own branch off the base and its own worktree path.
52
+ - **One git worktree per member**, never a shared checkout — concurrent members editing one working tree corrupt each other's diffs and evidence. Give each member its own branch off the base and its own worktree path. Apply the same resource rules when creating member worktrees.
53
53
  - **Merge per work unit, as each unit is verified.** A member's unit lands when its own evidence is captured and its gates are green; it does not wait for the slowest sibling. Integrate each merged unit back into the base the others branch from, so overlapping members rebase onto real merged work rather than guessing at it.
54
54
  - **Conflicts are the lead's job.** When two members' units touch the same lines, the lead decides the order they land and tells the later member what changed; members never resolve a sibling's conflict blind.
55
55
 
@@ -70,7 +70,7 @@ Codex subagent reliability:
70
70
  - Never invent state outside `.omo/ulw-loop` artifacts or `omo-agent-toolkit ulw-loop status --json`.
71
71
 
72
72
  ## Bootstrap
73
- Do all three steps before execution. No edits, goal tools, or checkpointing before bootstrap completes.
73
+ Do all three steps before execution; no edits, goal tools or checkpointing until bootstrap completes. Follow the parent skill’s resource-rule pointer before execution.
74
74
 
75
75
  ### 1. Create goals from the brief
76
76
  Resolve the CLI before the first command. If `omo` is absent from PATH or lacks `ulw-loop`, use the stable local installer bin or cached Codex component CLI — same CLI, so PATH absence is not a blocker. If PATH is empty, the fallback uses shell builtins and absolute Node locations before reporting guidance, recording the failure in `.omo/ulw-loop/bootstrap-notepad.md`.
@@ -165,7 +165,7 @@ Loop per goal. Cap at 5 cycles per goal. Cap identical same-criterion failures a
165
165
  4. INTEGRATE + CRITICAL SELF-QA + GIT CHECKPOINT (EVERY WORKER RETURN): do NOT trust the worker's report. Read the diff yourself, re-run its tests, and run LSP diagnostics on the changed files. Treat "done" as a claim to disprove. If the diff drifts, the test is hollow, or evidence is missing, RESPAWN the worker with the specific failure context. Once the work unit is verified, use `git-master` before staging: inspect recent repository commits and touched-path history to infer commit language, Conventional Commit scope, message shape, and unit size. Stage only that unit's files and commit in the observed style; do not carry verified work forward into a later omnibus commit. If no git-tracked files changed or committing is unsafe, record the no-commit reason as evidence. Forward every finding/learning to subsequent workers.
166
166
  5. EXECUTE-AS-SCENARIO: ACTUALLY run the Manual-QA scenario the criterion named (channel table above). Run it yourself for the orchestrator check; for heavier flows dispatch a dedicated QA execution worker (`lazycodex-worker-medium` by default; `lazycodex-worker-high` when the QA flow itself is hard) whose ONLY job is to drive the channel and write the artifact to the named evidence path. If the scenario FAILS, respawn the implementing worker with the captured failure — do not hand-patch around it.
167
167
  6. CAPTURE: collect the observable artifact path: transcript, stdout, screenshot, assertion, status+body, diff, or parsed dump. No artifact written at the evidence path — not done; record BLOCKED and respawn QA.
168
- 7. CLEAN (PAIRED, NEVER SKIP): tear down every runtime artifact step 5 spawned BEFORE recording — server PIDs (`kill`, verify `kill -0` fails), `tmux` sessions (`tmux kill-session -t ulw-qa-<criterion>`; confirm `tmux ls`), browser / Playwright contexts (`.close()`), containers (`docker rm -f`), bound ports (`lsof -i :<port>` empty), temp sockets / files / dirs (`rm -rf` the `mktemp` paths), QA-only env vars, AND close every finished worker (v1 `close_agent`; on V2 finished workers end on their own — `interrupt_agent` any still running). Register each teardown as its own todo the moment the QA spawns the resource (scripts, tmux assets, browser contexts, PIDs, ports) so none is forgotten. Embed a one-line cleanup receipt in the evidence string, e.g. `cleanup: killed 12345; tmux kill-session ulw-qa-foo; rm -rf /tmp/ulw.aB12cD; interrupt_agent w-3`. Missing receipt → record BLOCKED, not PASS.
168
+ 7. CLEAN (PAIRED, NEVER SKIP): execute the teardown todos before recording QA: owned PIDs (`kill`; verify `kill -0` fails), tmux sessions (`tmux kill-session -t ulw-qa-<criterion>`; confirm `tmux ls`), browser contexts (`.close()`), containers (`docker rm -f`), ports (`lsof -i :<port>` empty), QA scripts, temp paths and QA-only env vars. Close finished v1 workers with `close_agent`; V2 workers end normally, so `interrupt_agent` any still running. Apply the ultrawork Task resources rule at task end, not after each criterion. Embed read-back receipts in the evidence and complete the cleanup todos. Missing receipt → record BLOCKED, not PASS.
169
169
  8. RECORD one result immediately from the artifact you just wrote — never from memory or a later turn — stamping the capture tree `$(git rev-parse --short "HEAD^{tree}")` into the evidence:
170
170
  - PASS: `omo-agent-toolkit ulw-loop record-evidence --goal-id <id> --criterion-id <id> --status pass --evidence "<observable> @tree:<short-tree> | <cleanup receipt>" --json`
171
171
  - FAIL: `omo-agent-toolkit ulw-loop record-evidence --goal-id <id> --criterion-id <id> --status fail --evidence "<observable> @tree:<short-tree> | <cleanup receipt>" --notes "<diagnosis>" --json`
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/git-bash/dist/cli.js\" hook post-compact",
9
9
  "timeout": 5,
10
- "statusMessage": "(OmO 5.1.29) Resetting Git Bash MCP Reminder",
10
+ "statusMessage": "(OmO 5.1.32) Resetting Git Bash MCP Reminder",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\git-bash\\dist\\cli.js\" hook post-compact"
12
12
  }
13
13
  ],
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/lsp/dist/cli.js\" hook post-compact",
9
9
  "timeout": 5,
10
- "statusMessage": "(OmO 5.1.29) Resetting LSP Diagnostics Cache",
10
+ "statusMessage": "(OmO 5.1.32) Resetting LSP Diagnostics Cache",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\lsp\\dist\\cli.js\" hook post-compact"
12
12
  }
13
13
  ],
@@ -7,7 +7,7 @@
7
7
  "type": "command",
8
8
  "command": "node \"${PLUGIN_ROOT}/components/rules/dist/cli.js\" hook post-compact",
9
9
  "timeout": 10,
10
- "statusMessage": "(OmO 5.1.29) Resetting Project Rule Cache",
10
+ "statusMessage": "(OmO 5.1.32) Resetting Project Rule Cache",
11
11
  "commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\rules\\dist\\cli.js\" hook post-compact"
12
12
  }
13
13
  ],