oh-my-opencode 4.15.1 → 4.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (234) hide show
  1. package/.agents/skills/codex-qa/SKILL.md +9 -7
  2. package/.agents/skills/codex-qa/references/logging-debug.md +6 -4
  3. package/.agents/skills/opencode-qa/SKILL.md +9 -9
  4. package/.agents/skills/opencode-qa/references/tui-tmux.md +10 -8
  5. package/dist/cli/codex-ulw-loop.d.ts +8 -0
  6. package/dist/cli/doctor/checks/tui-plugin-config.d.ts +4 -4
  7. package/dist/cli/get-local-version/types.d.ts +1 -1
  8. package/dist/cli/index.js +792 -744
  9. package/dist/cli/install-senpi/index.d.ts +1 -0
  10. package/dist/cli/run/poll-for-completion.d.ts +4 -0
  11. package/dist/cli/run/session-resolver.d.ts +1 -0
  12. package/dist/cli/senpi-platform-flag.d.ts +4 -0
  13. package/dist/cli/types.d.ts +2 -1
  14. package/dist/cli-node/index.js +792 -744
  15. package/dist/features/background-agent/manager.d.ts +16 -0
  16. package/dist/features/builtin-commands/templates/start-work.d.ts +1 -1
  17. package/dist/features/monitor/process.d.ts +17 -1
  18. package/dist/hooks/anthropic-context-window-limit-recovery/aggressive-truncation-strategy.d.ts +1 -0
  19. package/dist/index.js +2206 -1971
  20. package/dist/skills/debugging/references/methodology/06-fix.md +6 -0
  21. package/dist/skills/frontend/ATTRIBUTION.md +10 -1
  22. package/dist/skills/frontend/SKILL.md +12 -7
  23. package/dist/skills/frontend/references/design/README.md +8 -4
  24. package/dist/skills/frontend/references/design/_INDEX.md +2 -2
  25. package/dist/skills/frontend/references/design/design-system-architecture.md +24 -2
  26. package/dist/skills/frontend/references/design/lazyweb.md +77 -0
  27. package/dist/skills/frontend/references/design/stitch-design-example.md +121 -0
  28. package/dist/skills/frontend/references/designpowers/README.md +2 -2
  29. package/dist/skills/frontend/references/designpowers/lane-b-execution.md +1 -1
  30. package/dist/skills/programming/SKILL.md +10 -1
  31. package/dist/skills/programming/references/logging.md +91 -0
  32. package/dist/skills/start-work/SKILL.md +2 -2
  33. package/dist/skills/ulw-plan/SKILL.md +5 -5
  34. package/dist/skills/ulw-plan/references/full-workflow.md +7 -7
  35. package/dist/skills/ulw-plan/references/intent-unclear.md +3 -3
  36. package/dist/skills/ulw-research/ATTRIBUTION.md +2 -2
  37. package/dist/skills/ulw-research/SKILL.md +28 -7
  38. package/dist/skills/visual-qa/SKILL.md +13 -17
  39. package/dist/tools/skill/description-formatter.d.ts +1 -0
  40. package/dist/tools/skill/description-formatter.test-support.d.ts +9 -0
  41. package/dist/tools/skill/zauc-mocks-skill-tools/test-support.d.ts +25 -0
  42. package/dist/tui.js +121 -419
  43. package/docs/reference/web-terminal-visual-qa.md +39 -45
  44. package/package.json +48 -25
  45. package/packages/git-bash-mcp/dist/cli.js +2 -2
  46. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
  47. package/packages/omo-codex/plugin/components/bootstrap/AGENTS.md +55 -0
  48. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +19 -16
  49. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  50. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  51. package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +51 -0
  52. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +936 -248
  53. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +233 -135
  54. package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
  55. package/packages/omo-codex/plugin/components/codegraph/src/cache-gc.ts +29 -0
  56. package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +13 -0
  57. package/packages/omo-codex/plugin/components/codegraph/src/hook-sweep.ts +25 -0
  58. package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +3 -1
  59. package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +30 -1
  60. package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +16 -2
  61. package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +80 -0
  62. package/packages/omo-codex/plugin/components/codegraph/test/cache-gc.test.ts +34 -0
  63. package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +107 -0
  64. package/packages/omo-codex/plugin/components/codegraph/test/hook-registration.test.ts +26 -0
  65. package/packages/omo-codex/plugin/components/codegraph/test/hook-sweep.test.ts +29 -0
  66. package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +8 -21
  67. package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +108 -0
  68. package/packages/omo-codex/plugin/components/codegraph/test/serve-built-wrapper.test.ts +76 -0
  69. package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +17 -111
  70. package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +1 -1
  71. package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +45 -67
  72. package/packages/omo-codex/plugin/components/codegraph/test/sweep-cli.test.ts +56 -0
  73. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  74. package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
  75. package/packages/omo-codex/plugin/components/git-bash/AGENTS.md +31 -0
  76. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  77. package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
  78. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/AGENTS.md +45 -0
  79. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  80. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
  81. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  82. package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
  83. package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus.md +37 -102
  84. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  85. package/packages/omo-codex/plugin/components/rules/package.json +1 -1
  86. package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +2 -2
  87. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
  88. package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
  89. package/packages/omo-codex/plugin/components/teammode/AGENTS.md +46 -0
  90. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  91. package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
  92. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +6 -0
  93. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +6 -0
  94. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  95. package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
  96. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +5 -2
  97. package/packages/omo-codex/plugin/components/ultrawork/CHANGELOG.md +2 -0
  98. package/packages/omo-codex/plugin/components/ultrawork/README.md +3 -3
  99. package/packages/omo-codex/plugin/components/ultrawork/directive.md +18 -10
  100. package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +51 -2
  101. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  102. package/packages/omo-codex/plugin/components/ultrawork/package.json +2 -1
  103. package/packages/omo-codex/plugin/components/ultrawork/scripts/sync-directive.mjs +14 -1
  104. package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +388 -0
  105. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +16 -2
  106. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +4 -4
  107. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +2 -2
  108. package/packages/omo-codex/plugin/components/ultrawork/src/codex-hook.ts +5 -3
  109. package/packages/omo-codex/plugin/components/ultrawork/src/skill-pointer.ts +56 -0
  110. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +26 -5
  111. package/packages/omo-codex/plugin/components/ultrawork/test/directive-source.test.ts +12 -0
  112. package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +1 -0
  113. package/packages/omo-codex/plugin/components/ultrawork/test/skill-pointer.test.ts +82 -0
  114. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +5 -0
  115. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +18 -10
  116. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +15 -2
  117. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.js +2 -1
  118. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +145 -32
  119. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.d.ts +1 -0
  120. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.js +5 -1
  121. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.d.ts +6 -0
  122. package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +55 -9
  123. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-snapshot.d.ts +15 -0
  124. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-snapshot.js +33 -0
  125. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-types.d.ts +10 -3
  126. package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.js +15 -11
  127. package/packages/omo-codex/plugin/components/ulw-loop/dist/ultrawork-directive.d.ts +2 -1
  128. package/packages/omo-codex/plugin/components/ulw-loop/dist/ultrawork-directive.js +5 -3
  129. package/packages/omo-codex/plugin/components/ulw-loop/dist/ultrawork-skill-pointer.d.ts +7 -0
  130. package/packages/omo-codex/plugin/components/ulw-loop/dist/ultrawork-skill-pointer.js +46 -0
  131. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +2 -2
  132. package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
  133. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +1 -1
  134. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +7 -7
  135. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +17 -2
  136. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-steering.ts +2 -1
  137. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +5 -1
  138. package/packages/omo-codex/plugin/components/ulw-loop/src/plan-io.ts +59 -11
  139. package/packages/omo-codex/plugin/components/ulw-loop/src/steering-snapshot.ts +38 -0
  140. package/packages/omo-codex/plugin/components/ulw-loop/src/steering-types.ts +11 -3
  141. package/packages/omo-codex/plugin/components/ulw-loop/src/steering.ts +15 -7
  142. package/packages/omo-codex/plugin/components/ulw-loop/src/ultrawork-directive.ts +9 -3
  143. package/packages/omo-codex/plugin/components/ulw-loop/src/ultrawork-skill-pointer.ts +55 -0
  144. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +16 -0
  145. package/packages/omo-codex/plugin/components/ulw-loop/test/plan-io.test.ts +260 -2
  146. package/packages/omo-codex/plugin/components/ulw-loop/test/steering-snapshot.test.ts +124 -0
  147. package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +101 -2
  148. package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +49 -0
  149. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  150. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  151. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  152. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  153. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  154. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  155. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  156. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  157. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  158. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  159. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  160. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  161. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  162. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  163. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  164. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +1 -1
  165. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +1 -1
  166. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  167. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  168. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  169. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  170. package/packages/omo-codex/plugin/package-lock.json +13 -13
  171. package/packages/omo-codex/plugin/package.json +1 -1
  172. package/packages/omo-codex/plugin/scripts/build-components.mjs +63 -17
  173. package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +10 -6
  174. package/packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs +10 -3
  175. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +1 -0
  176. package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +18 -0
  177. package/packages/omo-codex/plugin/skills/debugging/references/methodology/06-fix.md +6 -0
  178. package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +10 -1
  179. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +12 -7
  180. package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +8 -4
  181. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +2 -2
  182. package/packages/omo-codex/plugin/skills/frontend/references/design/design-system-architecture.md +24 -2
  183. package/packages/omo-codex/plugin/skills/frontend/references/design/lazyweb.md +77 -0
  184. package/packages/omo-codex/plugin/skills/frontend/references/design/stitch-design-example.md +121 -0
  185. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +2 -2
  186. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +1 -1
  187. package/packages/omo-codex/plugin/skills/programming/SKILL.md +10 -1
  188. package/packages/omo-codex/plugin/skills/programming/references/logging.md +91 -0
  189. package/packages/omo-codex/plugin/skills/start-work/SKILL.md +2 -2
  190. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +388 -0
  191. package/packages/omo-codex/plugin/skills/ultrawork/agents/openai.yaml +2 -0
  192. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +1 -1
  193. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +7 -7
  194. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +16 -2
  195. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +4 -4
  196. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +2 -2
  197. package/packages/omo-codex/plugin/skills/ulw-research/ATTRIBUTION.md +2 -2
  198. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +28 -7
  199. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +13 -17
  200. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +4 -4
  201. package/packages/omo-codex/plugin/test/bootstrap-hooks.test.mjs +1 -1
  202. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +22 -9
  203. package/packages/omo-codex/plugin/test/install-time-build-runtime.test.mjs +1 -1
  204. package/packages/omo-codex/plugin/test/sync-hook-status-messages.test.mjs +6 -6
  205. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +2 -0
  206. package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +56 -0
  207. package/packages/omo-codex/plugin/test/ulw-plan-skill-contract.test.mjs +52 -0
  208. package/packages/omo-codex/plugin/test/ulw-research-epistemic-contract.test.mjs +98 -0
  209. package/packages/omo-codex/plugin/test/ulw-research-skill-contract.test.mjs +6 -6
  210. package/packages/omo-codex/scripts/install-dist/install-local.mjs +310 -3979
  211. package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +2 -2
  212. package/packages/shared-skills/skills/debugging/references/methodology/06-fix.md +6 -0
  213. package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +10 -1
  214. package/packages/shared-skills/skills/frontend/SKILL.md +12 -7
  215. package/packages/shared-skills/skills/frontend/references/design/README.md +8 -4
  216. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +2 -2
  217. package/packages/shared-skills/skills/frontend/references/design/design-system-architecture.md +24 -2
  218. package/packages/shared-skills/skills/frontend/references/design/lazyweb.md +77 -0
  219. package/packages/shared-skills/skills/frontend/references/design/stitch-design-example.md +121 -0
  220. package/packages/shared-skills/skills/frontend/references/designpowers/README.md +2 -2
  221. package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +1 -1
  222. package/packages/shared-skills/skills/programming/SKILL.md +10 -1
  223. package/packages/shared-skills/skills/programming/references/logging.md +91 -0
  224. package/packages/shared-skills/skills/start-work/SKILL.md +2 -2
  225. package/packages/shared-skills/skills/ulw-plan/SKILL.md +5 -5
  226. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +7 -7
  227. package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +3 -3
  228. package/packages/shared-skills/skills/ulw-research/ATTRIBUTION.md +2 -2
  229. package/packages/shared-skills/skills/ulw-research/SKILL.md +28 -7
  230. package/packages/shared-skills/skills/visual-qa/SKILL.md +13 -17
  231. package/script/qa/strip-ansi.mjs +10 -0
  232. package/script/qa/web-terminal-visual-qa.mjs +112 -195
  233. package/script/qa/xterm-live-terminal.mjs +180 -0
  234. package/script/qa/web-terminal-renderer.mjs +0 -218
@@ -0,0 +1,91 @@
1
+ # Logging — Cross-Language Methodology
2
+
3
+ Every log line has exactly two legitimate readers: the operator reconstructing an incident and the developer reproducing a bug. A line that serves neither is cost — storage, noise, and attention stolen from the lines that matter. Everything below derives from that.
4
+
5
+ This reference is deliberately stack-agnostic. It never tells you which logging library to use — the ecosystem table in SKILL.md owns stack defaults, and the project's existing practice overrides everything (Rule 0).
6
+
7
+ ---
8
+
9
+ ## Rule 0 — Discover the project's practice before emitting anything
10
+
11
+ **BEFORE adding a single log line, find out how this project logs.** Grep for the logger initialization, a wrapper module, prior art in sibling files, and the project's agent docs (AGENTS.md / CLAUDE.md).
12
+
13
+ | What you find | Required behavior |
14
+ |---|---|
15
+ | A designated logger or wrapper | Use it exactly — its levels, its field conventions, its error-passing shape. Copy the call shape of the nearest well-written call site, not your habit. |
16
+ | A logging lib you like better | Irrelevant. NEVER introduce a second logging framework into a project that already has one. |
17
+ | Raw `console.*` / `print` culture | Follow it for user-facing CLI output. For diagnostics, propose structured logging in your reply — do not unilaterally convert the project. |
18
+ | **No logging at all** (library, small CLI, script) | **Respect the absence.** A library that suddenly logs is a behavior change its consumers never asked for; a 40-line script does not need a logging framework. If logging would genuinely help, say so in your reply — add it only when the user asks or the task itself is about observability. |
19
+
20
+ Bypassing the project's designated logger with a bare `console.log` / `print` "just for this one line" is the logging equivalent of `as any`: it escapes every contract the project set up — stage routing, formatting, redaction, shipping.
21
+
22
+ Serialization contracts (reserved field names, argument order, the key an Error must be passed under) are project knowledge. Discover the contract from the logger config and existing call sites; if the project's agent docs do not record it, record what you found there as part of your change.
23
+
24
+ ## Greenfield — when you own the setup
25
+
26
+ A new service earns exactly this much logging infrastructure, and no more:
27
+
28
+ 1. **One init module.** Callers import a ready logger; only the init module knows the stage. No call site ever checks `NODE_ENV`-style vars to decide how to log.
29
+ 2. **Stage split by environment.** Dev = human-readable (pretty, colorized). Prod = structured, machine-parseable (JSON to stdout). Same logger API on both — the stage changes the sink and format, never the call sites.
30
+ 3. **Level threshold per stage.** Dev = `debug`, prod = `info`, overridable with a `LOG_LEVEL`-style env var.
31
+ 4. **The stack's standard structured logger** (the ecosystem table in SKILL.md names the default) — never a hand-rolled one.
32
+ 5. **Error-serialization proof.** Before trusting error logging, pass a real Error/exception through the PROD formatter once and assert the output preserves type, message, and stack. Every structured-logging stack has a reserved-key contract, and violating it typically produces an empty `{}` where the stack trace should have been — discovered during the incident. This is a one-line test; write it at setup time and the whole bug class is dead permanently.
33
+
34
+ ## Choosing the level — consumer, not severity
35
+
36
+ **A level is a routing decision, not a severity vibe. Choose it by naming who consumes the line and what they do about it. If you cannot name the consumer, do not emit the line.**
37
+
38
+ | Level | Consumer and action | The line earns this level when |
39
+ |---|---|---|
40
+ | `error` | Alerting wakes a human NOW | **The service failed** at a user-visible operation and cannot recover on its own. |
41
+ | `warn` | Reviewed in batch — dashboards, weekly triage | The request SUCCEEDED but took an abnormal path: retry needed, fallback engaged, degraded mode, suspicious data. |
42
+ | `info` | Read during an incident to reconstruct the timeline | A state transition without which the request's story does not reconstruct: session/job/connection created, completed, destroyed. |
43
+ | `debug` | The developer reproducing locally | Detailed tracing. **Does not exist in prod.** |
44
+
45
+ Two corollaries that get violated constantly:
46
+
47
+ - **`error` means the SERVICE failed, not the request.** A 4xx is the client's mistake handled correctly — that is `warn` at most, `info` for routine misses. Reserve `error` for 5xx-class outcomes: the service could not do its job. Log 4xx as `error` and the alert channel drowns in noise from every crawler probing `/wp-admin`; a drowned alert channel is equivalent to no alerting.
48
+ - **A failure logged at `info` is invisible.** If the message says "failed", the level is `warn` or `error` — never `info`.
49
+
50
+ ## Placement — log decisions, not work
51
+
52
+ Log where the system decides something, not where it does something:
53
+
54
+ - **Boundaries** — request in / response out, calls to external systems (and their failures).
55
+ - **State transitions** — create / complete / destroy of sessions, jobs, connections.
56
+ - **Decision points** — retry chosen, fallback engaged, cache bypassed, degraded mode entered.
57
+ - **The one place an error is finally handled.**
58
+
59
+ Never log inside pure functions, utilities, or private helpers — callers with context log outcomes; internals stay silent. Two mechanical rules:
60
+
61
+ - **One event, one line.** Log-and-rethrow at every layer turns one incident into five look-alike incidents. Log where the error is handled; layers that only propagate stay silent.
62
+ - **Mechanical logging belongs to middleware.** Request/response logging is wired once at the framework layer, never hand-assembled per handler. High-volume zero-signal paths (health probes, metrics scrapes) are excluded there as data — an exclusion set — not as scattered `if` statements.
63
+
64
+ **No speculative logs.** "Might need it later" is not a consumer. A log line earns its place through evidence: a debugging session that burned rounds because this state was invisible (see the debugging bridge below), an incident postmortem, an alert that needs the field.
65
+
66
+ ## The line contract
67
+
68
+ - **The message is a stable, grep-able constant; data goes in fields.** `logger.warn({orderId, attempt}, "payment retry")` — never `` `retrying payment for ${orderId}` ``. An interpolated message cannot be counted, aggregated, or alerted on.
69
+ - **Correlation or it did not happen.** Request-scoped lines carry the trace/request id; entity-scoped lines carry the entity id. A line you cannot join to its request is noise during the only moments logs matter.
70
+ - **Name events semantically** (`session.destroy`, `payment.fallback`), never positionally ("Step 3"). Step numbers couple the log stream to today's call structure; the first refactor makes them lie.
71
+ - **No secrets.** Tokens, credentials, session cookies, and PII never enter a log line; URLs are sanitized (strip or redact query params like `token`, `key`) before logging. A leaked log is a leaked credential.
72
+ - **The logging path may not break the program.** If a log call can itself fail (serializing exotic state, a wrapper that touches I/O), that failure is caught, downgraded to a `warn` through a channel that cannot fail, and the operation continues. An empty catch around logging is still an empty catch.
73
+
74
+ ## Anti-patterns
75
+
76
+ | Anti-pattern | Why it fails |
77
+ |---|---|
78
+ | `console.*` / `print` bypassing the project's designated logger | Escapes stage routing, redaction, and shipping — invisible in prod |
79
+ | Introducing a logging framework to a project that has none | Uninvited behavior change; Rule 0 violation |
80
+ | 4xx logged as `error` | Alert noise buries real pages |
81
+ | Log-and-rethrow at every layer | One incident looks like five |
82
+ | Variables interpolated into the message string | Un-aggregatable, un-alertable |
83
+ | "Might need it later" logs | No consumer → pure cost |
84
+ | Debug-time prints promoted to permanent `info` | Narration, not state transitions |
85
+ | Trusting Error serialization without the proof | `error: {}` in prod, discovered during the incident |
86
+
87
+ ## Debugging bridge — how logs earn their place
88
+
89
+ When a `debugging`-skill session takes extra rounds *because state was invisible* — no line told you which branch ran, what the value was, whether the fallback engaged — that invisibility is a defect adjacent to the bug. **The fix ships with the log line that would have made diagnosis one round**: placed at a decision point, leveled by consumer, fields not interpolation, through the project's designated logger.
90
+
91
+ The inverse also holds: every temporary `print` / `dbg!` / `console.log` planted *during* diagnosis is a debug artifact and gets scrubbed at cleanup. The triage between the two is the consumer test — a line whose ongoing consumer you can name is part of the fix; a line that only served today's session is an artifact.
@@ -99,10 +99,10 @@ Each sub-task message must include:
99
99
  4. Automated verification commands to run.
100
100
  5. One Manual-QA channel, named with the exact tool and exact invocation (the literal `curl`, `send-keys`, `browser:control-in-app-browser` action, `page.click`, payload, selectors, and the binary observable that decides PASS/FAIL), not "verify it works". A LIGHT checkbox needs one real-surface proof of its deliverable, and auxiliary surfaces (CLI stdout, DB state diff, parsed config dump) are first-class when the surface is CLI- or data-shaped:
101
101
  - HTTP call: `curl -i` against the live endpoint.
102
- - tmux: a `tmux` session driven with `send-keys`, dumped via `capture-pane`.
102
+ - Terminal / TUI: drive a real pty; `tmux send-keys` is fine for a boot/behavior smoke, but color/layout/CJK evidence goes through the xterm.js web terminal below, NEVER `tmux capture-pane`.
103
103
  - Browser use: in Codex, use `browser:control-in-app-browser` first when available and the scenario does not need an authenticated or persistent user browser profile; otherwise drive the real page with Chrome, or agent-browser (https://github.com/vercel-labs/agent-browser) when Chrome is unavailable.
104
104
  - Computer use: OS-level GUI automation against the running desktop app when the surface is not a page.
105
- - TUI visual evidence: when a tmux/TUI claim needs visual QA or PR proof, run `node script/qa/web-terminal-visual-qa.mjs --from-file <capture.txt> --evidence-dir <dir>` and attach `terminal.png` plus `metadata.json`.
105
+ - TUI visual evidence: when a TUI claim needs visual QA or PR proof, run `node script/qa/web-terminal-visual-qa.mjs --command "<cmd>" --input "{Enter}" --evidence-dir <dir>` (real pty rendered through xterm.js in Chrome) and attach `terminal.png` plus `metadata.json`.
106
106
  6. The adversarial classes that apply to this sub-task (from the 9 ultraqa classes) and how each is probed.
107
107
  7. Required artifact path and cleanup receipt.
108
108
 
@@ -9,18 +9,18 @@ metadata:
9
9
 
10
10
  You are **Prometheus**, a planning consultant. You turn a vague or large request into ONE **decision-complete** work plan a downstream worker executes with zero further interview. You read, search, run read-only analysis, and write ONLY plan artifacts under `.omo/`. You are a PLANNER - you never edit product code and never implement.
11
11
 
12
- **Plan mode is sticky.** "do X" / "fix X" / "build X" / "just do it" all mean "plan X". You **never start implementation** - not for small, obvious, or urgent work. Execution is the worker's job and begins only when the user explicitly starts it (e.g. `$start-work`).
12
+ **Plan mode is sticky.** "do X" / "fix X" / "build X" / "just do it" all mean "plan X". You **never start implementation** - not for small, obvious, or urgent work, and not through a subagent: delegated implementation is still implementation. Execution belongs to a separate worker session that only the user starts (e.g. `$start-work`).
13
13
 
14
14
  Outcome-first: explore a lot, ask few sharp questions - or none, when the intent is fuzzy (see routing) - and stop the moment the plan is done.
15
15
 
16
16
  ## INTENT ROUTING - pick ONE intent reference
17
17
 
18
- Before routing, parse review modifiers separately. If the user says "high accuracy", "ultra high accuracy", "고정밀", "deep review", or equivalent, set `review_required: true` in the draft. This does NOT choose CLEAR/UNCLEAR and does NOT suppress interview; it only makes the high-accuracy review gate required after the plan exists.
18
+ **Review modifiers are a gate trigger, not a style cue.** If the user says "high accuracy", "ultra high accuracy", "고정밀", "deep review", or equivalent - in ANY turn, even appended to a follow-up question and even after the plan already exists - set `review_required: true` in the draft: the dual high-accuracy review (native `momus` + the independent Oracle review) is now REQUIRED before handoff, and if the plan already exists you run it this same turn. Answering the current question more carefully does NOT satisfy it. This does NOT choose CLEAR/UNCLEAR and does NOT suppress interview.
19
19
 
20
20
  After grounding, make ONE judgment, record `intent: clear|unclear` plus `review_required`, **ANNOUNCE both to the user in one line**, then load ONE intent reference (you ALSO read `references/full-workflow.md` for the shared mechanics - see below). The test keys on whether the desired **OUTCOME** is clear, NOT on request length. The announcement is the user's first signal of whether they will be interviewed and whether high-accuracy review is already requested - never skip it.
21
21
 
22
- > "Intent: **CLEAR**, review required you specified the endpoint and asked for high accuracy. I will ask only the genuine forks, then run the high-accuracy review after approval."
23
- > "Intent: **UNCLEAR**, review required 'make auth better' is open-ended and you asked for high accuracy. I will choose best-practice defaults, then run the high-accuracy review automatically."
22
+ > "Intent: **CLEAR**, review required - you specified the endpoint and asked for high accuracy. I will ask only the genuine forks, then run the high-accuracy review after approval."
23
+ > "Intent: **UNCLEAR**, review required - 'make auth better' is open-ended and you asked for high accuracy. I will choose best-practice defaults, then run the high-accuracy review automatically."
24
24
 
25
25
  - **OVERRIDE - explicit ask wins:** if the user explicitly asks to be questioned or interviewed ("ask me", "interview me", "why aren't you asking me" - in any language), route **CLEAR**, run the interview, and turn the adopt-default filter OFF: the user has claimed the forks, so every surviving one is ASKED, not defaulted. This beats the OUTCOME test below, even on a fuzzy brief.
26
26
  - **CLEAR** - the user knows the outcome; the only open items are preferences/tradeoffs the repo cannot answer (genuine owner-decisions). Read **`references/intent-clear.md`**: ask the surviving forks with WHY, run the normal approval gate, and offer high-accuracy review only when `review_required` is false.
@@ -67,7 +67,7 @@ Fan out read-only research before deciding. Every delegated prompt names TASK /
67
67
  task(subagent_type="explore", description="Map the implementation surface", prompt="TASK: act as an explorer. DELIVERABLE: ... SCOPE: ... VERIFY: ...")
68
68
  ```
69
69
 
70
- Roles: `explore` (internal patterns/conventions/tests), `librarian` (external docs/contracts), `metis` (gap analysis), `momus` (high-accuracy plan review). Full delegation/wait/fallback discipline is in `references/full-workflow.md`.
70
+ Roles - the ONLY subagents you may spawn (all read-only, plus `oracle` for the high-accuracy review): `explore` (internal patterns/conventions/tests), `librarian` (external docs/contracts), `metis` (gap analysis), `momus` (high-accuracy plan review). Never dispatch with `category=` - categories spawn implementers - and never instruct a child to edit files. Full delegation/wait/fallback discipline is in `references/full-workflow.md`.
71
71
 
72
72
  ## Stop rules
73
73
 
@@ -10,7 +10,7 @@ metadata:
10
10
  The deep mechanics both routing paths share (`intent-clear.md`, `intent-unclear.md`). Read the phase you are in.
11
11
 
12
12
  ## Role
13
- You are Prometheus, a planning consultant. You turn a vague or large request into ONE decision-complete work plan a downstream worker executes with zero further interview. You read, search, run read-only analysis, and write only `.omo/plans/<slug>.md` and `.omo/drafts/*.md`. You never edit product code and never implement. **Plan mode is sticky**: "do X" / "fix X" / "just do it" mean "plan X"; execution belongs to the worker and starts only on the user's explicit start (e.g. `$start-work`), never on your judgment.
13
+ You are Prometheus, a planning consultant. You turn a vague or large request into ONE decision-complete work plan a downstream worker executes with zero further interview. You read, search, run read-only analysis, and write only `.omo/plans/<slug>.md` and `.omo/drafts/*.md`. You never edit product code and never implement - directly or through a subagent. **Plan mode is sticky**: "do X" / "fix X" / "just do it" mean "plan X"; execution belongs to the worker and starts only on the user's explicit start (e.g. `$start-work`), never on your judgment.
14
14
 
15
15
  ## North star
16
16
  A plan is decision-complete when the implementer needs ZERO judgment calls: every decision made, every ambiguity resolved, every pattern referenced with a concrete path. The executor has NO interview context - be exhaustive.
@@ -36,7 +36,7 @@ Make ONE judgment and follow ONE reference. Review modifiers are not routing sig
36
36
  - CLEAR -> `intent-clear.md`: run the **two filters** on every candidate question; ask only surviving forks (owner-decisions), with WHY.
37
37
  - UNCLEAR -> `intent-unclear.md`: research maximally, adopt announced best-practice defaults, do not ask the user extra questions.
38
38
 
39
- If a draft/plan already exists and the user asks for high-accuracy review, high-accuracy planning, or to make the plan more accurate, do not reroute from scratch unless the scope changed. Load the draft, preserve its recorded `intent`, set `review_required: true`, update stale plan content if needed, then run the required review loop against the current plan.
39
+ If a draft/plan already exists and the user says a review modifier - even appended to an otherwise unrelated follow-up question - or asks to make the plan more accurate, do not reroute from scratch unless the scope changed. Load the draft, preserve its recorded `intent`, set `review_required: true`, answer the question if one was asked, update stale plan content if needed, then run the required review loop against the current plan in that same turn. A more rigorous answer is not a substitute for the review.
40
40
 
41
41
  Both paths record `intent`, `review_required`, and decisions to `.omo/drafts/<slug>.md` as they go - long sessions outlive your context, and plan generation reads the draft, not your memory.
42
42
 
@@ -52,7 +52,7 @@ Then read the user's next reply as a decision:
52
52
  - **Scope change** - a reply that alters the approach. Fold it into the draft, update the brief, re-present once.
53
53
  - **Still unclear** - emit ONE short line naming the pending action and the approval you need; **do not re-explore** and do not restate the whole brief.
54
54
 
55
- No Metis, no plan file, no execution until the user approves. The UNCLEAR path auto-runs the high-accuracy review AFTER approval; it never skips this gate. Narrow `$start-work` bootstrap exception: when `$start-work` invoked this skill because there was no selectable plan, the user's "start work" counts as approval to generate the plan and begin execution.
55
+ No Metis, no plan file, no execution until the user approves. The UNCLEAR path auto-runs the high-accuracy review AFTER approval; it never skips this gate. Narrow `$start-work` bootstrap exception: when `$start-work` invoked this skill because there was no selectable plan, the user's "start work" counts as approval to generate the plan; execution then begins per the harness's start-work rule - never run by the planning agent itself.
56
56
 
57
57
  ## Phase 3 - Generate the plan (only after approval)
58
58
  1. RUN `node "<skill-root>/scripts/scaffold-plan.mjs" <slug> [--clear|--unclear]` (replace `<skill-root>` with this skill's own directory) to create the draft + the plan skeleton (human TL;DR on top, every header below). Run it ONCE here; a plain re-run on an existing plan is a safe no-op that preserves your appended todos, so resuming after compaction never crashes or clobbers. If it refuses because a same-named non-artifact file exists, pick a different `<slug>` rather than `--reset` over a human file you did not create. Never hand-build the skeleton.
@@ -82,10 +82,10 @@ Runs in parallel; ALL must APPROVE; surface results and wait for the user's expl
82
82
  ## Phase 4 - Deliver
83
83
  - CLEAR with `review_required: false`: present the plan summary, then ask ONE question and stop - start work now, or run a high-accuracy review first? Never pick for the user; never begin execution yourself - execution belongs to the worker.
84
84
  - CLEAR with `review_required: true`: run the high-accuracy review before delivery, record receipts, then present the plan summary and review result. Do not ask whether to run the review; the user already asked.
85
- - UNCLEAR: run Metis plus the high-accuracy review AUTOMATICALLY before presenting (unless Classify=Trivial), then present a brief that LEADS with the derived approach and the adopted defaults; still wait for the user's explicit okay.
85
+ - UNCLEAR: run the high-accuracy review AUTOMATICALLY before presenting (unless Classify=Trivial), then present a brief that LEADS with the derived approach and the adopted defaults; still wait for the user's explicit okay.
86
86
 
87
87
  ### High-accuracy review (dual review)
88
- The high-accuracy review is DUAL and both passes must return OKAY before handoff: (1) the native `momus` reviewer subagent, and (2) an independent Oracle review via `task(subagent_type="oracle", ...)` on the strongest available reasoning model, in a fully isolated sub-session with normal approval and sandbox policy. Do not add flags that disable approvals or sandboxing. Fix every cited issue and resubmit BOTH fresh until each approves. CLEAR: runs when the user opts in or `review_required: true`. UNCLEAR: runs automatically unless Classify=Trivial.
88
+ The high-accuracy review is DUAL and both passes must return OKAY before handoff: (1) the native `momus` reviewer subagent, and (2) an independent Oracle review via `task(subagent_type="oracle", ...)` on the strongest available reasoning model, in a fully isolated sub-session with normal approval and sandbox policy. Do not add flags that disable approvals or sandboxing. One round = exactly ONE `momus` + ONE independent review, dispatched together against the COMPLETE plan file (todos + TL;DR filled) - never a second `momus` while a round is in flight. After both verdicts return, fix every cited issue and resubmit both fresh until each approves. CLEAR: runs when the user opts in or `review_required: true`. UNCLEAR: runs automatically unless Classify=Trivial.
89
89
 
90
90
  The draft must record the native Momus session/result, the independent review session/result, and the fix/retry summary. Do not say "high-accuracy review completed" unless both receipts exist and both final verdicts are unconditional approval.
91
91
 
@@ -96,9 +96,9 @@ Every delegated prompt starts with `TASK:`, then DELIVERABLE / SCOPE / VERIFY; s
96
96
  task(subagent_type="explore", description="Map the implementation surface", prompt="TASK: act as an explorer. DELIVERABLE: ... SCOPE: ... VERIFY: ...")
97
97
  ```
98
98
 
99
- Roles: `explore`, `librarian`, `metis`, `momus`. Spawn long plan/reviewer agents in the background and poll with short waits through the OpenCode task surface; require the child to send `WORKING: <task> - <phase>` before long passes and `BLOCKED: <reason>` only when progress stops. A timeout only means no new update arrived; treat a running child as alive. Fall back only when the child completed without the deliverable, is ack-only after followup, explicitly `BLOCKED:`, or no longer running; then respawn a smaller delegated job. Close each agent after integrating its result.
99
+ Roles - the ONLY spawnable subagents (all read-only, plus `oracle` for the high-accuracy review): `explore`, `librarian`, `metis`, `momus`. Never dispatch with `category=` and never instruct a child to edit files. Spawn long plan/reviewer agents in the background and poll with short waits through the OpenCode task surface; require the child to send `WORKING: <task> - <phase>` before long passes and `BLOCKED: <reason>` only when progress stops. A timeout only means no new update arrived; treat a running child as alive. Fall back only when the child completed without the deliverable, is ack-only after followup, explicitly `BLOCKED:`, or no longer running; then respawn a smaller delegated job. Close each agent after integrating its result.
100
100
 
101
101
  ## Stop rules
102
- - Plan file exists, template filled, every todo has references + acceptance + QA + commit, dependency matrix consistent: present the summary, ask the start-or-high-accuracy question (CLEAR) or lead with the best-practice brief (UNCLEAR), and stop. Execution belongs to the worker, never to you.
102
+ - Plan file exists, template filled, every todo has references + acceptance + QA + commit, dependency matrix consistent, and any required high-accuracy receipts recorded: present the summary, then (CLEAR without `review_required`) ask the start-or-high-accuracy question, or (CLEAR with `review_required` / UNCLEAR) report the review result - and stop. Execution belongs to the worker, never to you.
103
103
  - Brief presented and `status: awaiting-approval` recorded: wait. Do not re-explore unless the user changes scope.
104
104
  - Two research waves with no new useful facts: stop exploring, present the brief.
@@ -26,13 +26,13 @@ Fold a contrarian self-grill into the Metis spawn: challenge the single highest-
26
26
  </default_selection>
27
27
 
28
28
  <high_accuracy_auto>
29
- Because the human did not steer, adversarial review SUBSTITUTES for the interview you skipped - this is what catches a bad default. After the plan is written, run Metis gap analysis (always) AND the dual high-accuracy review defined in `full-workflow.md` AUTOMATICALLY - no "do you want a review?" question. Fold Metis silently; resubmit fresh until BOTH passes APPROVE; fix every cited issue.
29
+ Because the human did not steer, adversarial review SUBSTITUTES for the interview you skipped - this is what catches a bad default. Metis runs during plan generation as always; after Metis findings are folded and the plan file is complete, run the dual high-accuracy review defined in `full-workflow.md` AUTOMATICALLY - no "do you want a review?" question - and resubmit fresh until BOTH passes APPROVE, fixing every cited issue.
30
30
 
31
31
  TRIVIAL-TIER GUARD: if Classify sized the work Trivial, the auto-Momus loop is SUPPRESSED (Metis still runs once) - a vague-but-tiny request ("clean this up") must not trigger the full adversarial loop. UNCLEAR raises the research-plus-default posture; it does not override the Trivial cost guard for Momus.
32
32
  </high_accuracy_auto>
33
33
 
34
34
  <approval_gate>
35
- Still present a brief and wait for the user's explicit okay - approval is not execution - but the brief LEADS with "here is the best-practice approach I derived and the assumptions I adopted (with reversibility)", not "here are questions for you". The adopted-defaults list is surfaced loudly in the plan's human TL;DR "Decisions I made for you" block, so the user can veto any single default at the gate. LEAD that block with the routing call itself - "I treated this as open-ended and chose defaults; if you had a specific outcome in mind, say so and I will switch to asking" - so a wrong CLEAR-as-UNCLEAR read is a one-line correction at the gate, not a silently-spent adversarial loop. Approval authorizes writing or keeping the plan only, never implementation. The durable draft (Components plus Open-assumptions ledgers plus gate state) is the compaction-safe resume point. ($start-work bootstrap exception: "start work" counts as approval to generate AND begin per the harness bootstrap rule; ordinary ulw-plan keeps the normal gate.)
35
+ Still present a brief and wait for the user's explicit okay - approval is not execution - but the brief LEADS with "here is the best-practice approach I derived and the assumptions I adopted (with reversibility)", not "here are questions for you". The adopted-defaults list is surfaced loudly in the plan's human TL;DR "Decisions I made for you" block, so the user can veto any single default at the gate. LEAD that block with the routing call itself - "I treated this as open-ended and chose defaults; if you had a specific outcome in mind, say so and I will switch to asking" - so a wrong CLEAR-as-UNCLEAR read is a one-line correction at the gate, not a silently-spent adversarial loop. Approval authorizes writing or keeping the plan only, never implementation. The durable draft (Components plus Open-assumptions ledgers plus gate state) is the compaction-safe resume point. ($start-work bootstrap exception: "start work" counts as approval to generate the plan, with execution starting per the harness's start-work rule - never run by the planning agent itself; ordinary ulw-plan keeps the normal gate.)
36
36
  </approval_gate>
37
37
 
38
38
  <worked_example>
@@ -40,5 +40,5 @@ Request: "make auth better".
40
40
  1. Research waves -> current auth at `src/auth/*` (session cookies, no login rate-limit, bcrypt rounds=8, no MFA); best-practice baselines via librarian.
41
41
  2. Topology lock as an ANNOUNCEMENT, not a question: components = session hardening, brute-force protection, password policy, MFA (deferred).
42
42
  3. Adopted-defaults table (assumption | default | rationale | reversible?): bcrypt rounds 8 -> 12 (reversible), add 5/min-per-IP login limit (reversible), rotate session id on privilege change (reversible).
43
- 4. Auto Metis + Momus loop -> fix cited gaps -> brief LEADING with the approach and the defaults, surfaced in the human TL;DR for veto.
43
+ 4. Metis folded -> auto dual review (fix cited gaps until both approve) -> brief LEADING with the approach and the defaults, surfaced in the human TL;DR for veto.
44
44
  </worked_example>
@@ -7,9 +7,9 @@ is adapted into this skill's prompt contract.
7
7
 
8
8
  ---
9
9
 
10
- ## 1. insane-research (fivetaku) — inspiration for the claim-ledger verification gate
10
+ ## 1. insane-research (fivetaku) — inspiration for the claim-graph verification gate
11
11
 
12
- The non-code claim-ledger verification gate (Phase 3b: a data-flow-lock where the
12
+ The non-code claim-graph verification gate (Phase 3b: a data-flow-lock where the
13
13
  synthesis may assert a high-risk non-code claim only after it clears `>= 2 independent
14
14
  source domains + 1 counter-search + a primary source`, otherwise it is abstained to an
15
15
  unresolved/refuted annex) is inspired by the data-flow-lock verification design in
@@ -49,9 +49,22 @@ The research is done when all of these hold:
49
49
  - Every EXPAND lead was investigated or explicitly closed as a duplicate or dead end, and convergence was reached under the Phase 2 rules.
50
50
  - Claims that were contested, undocumented, or performance-shaped were proven or refuted by executed code.
51
51
  - Every claim in the deliverable cites a source or a verification artifact.
52
+ - Every asserted claim is represented in the claim graph, tied to an intent-vs-reality diff when an expected truth exists, and backed by observation manifest entries from independent observation groups or a documented single-source exception; convergence or exception status is explicit.
52
53
  - Final materials follow the Phase 5 format default or the user's explicit format.
53
54
  - The session journal reconstructs what was searched, found, and expanded, wave by wave.
54
55
 
56
+ ## Epistemic instrumentation
57
+
58
+ Saturation is not just more searching; it is a knowledge-production protocol. The session journal must make the path from observation to claim to verdict auditable. The orchestrator owns these artifacts:
59
+
60
+ - `intent-diff.md` — one row per expected truth derived from the user intent, design/spec text, branch history, or authoritative docs. Required fields: `intent_id`, expected truth, observed reality, diff, violated invariant, intent source, supporting observations, status (`true`, `violated`, or `unknown`), and linked claim ids.
61
+ - `claim-graph.md` — the single claim store; one node per claim. Required fields: `claim_id`, statement, claim type, risk tier, scope, intent ids, supporting observations, contradicting observations, independent observation groups, convergence status, counter-search result, primary source backing, dependencies, status (`supported`, `partial`, `refuted`, or `unresolved`), and final synthesis location. High-risk non-code nodes that clear the Phase 3b gate are mirrored into a `verified-claims` digest section at the top of the file — the sole allowlist the synthesis draws non-code claims from.
62
+ - `observation-manifest.md` — one row per observation. Required fields: `observation_id`, source path or URL, evidence layer, observer group, independence basis, observer, `observed_at`, `valid_at` or `claim_valid_at`, artifact path, quote or line anchor, and contamination notes.
63
+ - `verification-economics.md` — one row per proof decision. Required fields: claim, risk, error cost, verification cost/time, chosen verification path, defer/verify decision, outcome, and residual risk.
64
+ - `cause-disappearance.md` — one row per causal finding. Required fields: cause id, expected truth, previous observation, `last_seen`, disconfirming observation, replacement cause if any, current status, and whether the violation is no longer observed.
65
+
66
+ Observation candidates and claim candidates travel back from workers as message text. The orchestrator writes the instrumentation artifacts, links candidates into the intent diff and claim graph, and records where each observation entered the synthesis. A conclusion is not ready for final materials until its expected truth/reality diff is closed or marked unknown, its claim node exists, and its independent-observation convergence status is supported or explicitly excepted.
67
+
55
68
  ## Run the swarm as a cooperating team
56
69
 
57
70
  Saturation research defaults to teammode, not isolated fire-and-forget workers: a lead one worker surfaces almost always reshapes what another should search next. When your harness gives you real cooperating members — Codex: the `teammode` skill (`codex_app` threads); OpenCode: `team_mode` — run this swarm as a team. Fall back to the background-worker swarm below only when team mode is unavailable, or the axes are genuinely independent with no cross-pollination expected.
@@ -78,7 +91,7 @@ Every research spawn message contains, in order:
78
91
  2. The budget lift: "This is an explicit exhaustive-research assignment. Your default retrieval budget and stop-when-answered rules do not apply — run the full protocol below and report every lead."
79
92
  3. Scope — the axis, the sources to hit, and what a complete answer contains.
80
93
  4. The role protocol (Phase 1).
81
- 5. The reply tail. EXPAND markers travel back as message text, never as files. Every worker ends the reply with:
94
+ 5. The reply tail. EXPAND markers, observation candidates, and claim candidates travel back as message text, never as files. Every worker ends the reply with:
82
95
 
83
96
  ```
84
97
  ## EXPAND
@@ -90,7 +103,7 @@ A worker with nothing to expand writes `## EXPAND` followed by `none — <one-li
90
103
 
91
104
  ## Phase 0 — Decompose and open the journal
92
105
 
93
- Before spawning anything, decompose the query:
106
+ Before spawning anything, decompose the query. Start from "what must be true if the user's intent/spec is true?", not "what looks broken?" Seed `intent-diff.md` with those expected truths before treating code, current docs, or web results as the source of truth:
94
107
 
95
108
  ```
96
109
  <analysis>
@@ -110,6 +123,11 @@ This is `$SESSION_DIR`. The orchestrator owns the journal: you write every file
110
123
 
111
124
  - `wave-<N>-<kind>-<axis>.md` — your digest of each worker return: key findings, sources with URLs, and the worker's EXPAND markers verbatim.
112
125
  - `expansion-log.md` — per wave: workers spawned, markers gained, leads opened and closed.
126
+ - `intent-diff.md` — orchestrator-owned expected-truth ledger comparing intent/spec/history to observed reality.
127
+ - `claim-graph.md` — orchestrator-owned claim graph linking every final assertion to observations, counterevidence, dependencies, and verdict.
128
+ - `observation-manifest.md` — orchestrator-owned observation manifest with `observed_at`, temporal validity, artifact paths, and contamination notes.
129
+ - `verification-economics.md` — proof-cost ledger mapping claim risk to verification path, deferral decisions, and residual risk.
130
+ - `cause-disappearance.md` — cause ledger tracking expected truth, previous observation, `last_seen`, disconfirming observation, and whether the violation is no longer observed.
113
131
  - `verify-<slug>.md`, `SYNTHESIS.md`, `REPORT.*` from later phases.
114
132
 
115
133
  Append each digest the moment its worker returns, not in a batch at the end — the journal is your recovery point after context loss and the user's audit trail.
@@ -181,19 +199,21 @@ Reply with: the exact code, the full output, environment (OS, runtime, dependenc
181
199
 
182
200
  Journal each verdict to `verify-<slug>.md`.
183
201
 
184
- ## Phase 3b — Lock non-code claims through a claim ledger
202
+ ## Phase 3b — Lock non-code claims through the claim graph
185
203
 
186
204
  Code settles code-shaped claims (Phase 3). Numeric, market-share, legal, dated, causal, and financial claims cannot be run — so they pass through a data-flow-lock instead (the verification idea adapted from fivetaku/insane-research): the synthesis may assert a high-risk non-code claim **only** if it cleared this gate, and the gate's output is the sole allowlist the synthesis draws from. Skip the gate and there is nothing to synthesize — the lock is self-enforcing.
187
205
 
188
- The claim ledger is orchestrator-owned. Workers only return verified-claim markers as message text, the same channel as EXPAND markers — never a file. As leads resolve, you record one ledger entry per asserted claim and compute its status; workers report claim candidates in their replies, and you decide.
206
+ The claim graph is orchestrator-owned. Workers only return verified-claim markers, observation candidates, and claim candidates as message text, the same channel as EXPAND markers — never a file. As leads resolve, you record one node per asserted claim in `claim-graph.md` and compute its status; workers report claim candidates in their replies, and you decide. The graph is the single claim store: final synthesis may not draw from free-form claims that skipped it.
189
207
 
190
208
  A high-risk claim clears the gate to `verified-claims` only when all hold:
191
209
 
192
210
  - **>= 2 independent source domains** corroborate it (two pages on the same domain count once).
211
+ - **>= 2 independent observation groups** converge on it, unless the graph records why a primary-only source is the correct single-source exception.
193
212
  - **One counter-search** actively looked for a refutation and did not find a stronger one.
194
213
  - **A primary source** (the standard, filing, dataset, or first-party doc) backs it, not only secondary commentary.
214
+ - **Temporal evidence is explicit**: each supporting observation records `observed_at` and either `valid_at` or `claim_valid_at`, so branch-only, historical, release, and current-runtime claims cannot be conflated.
195
215
 
196
- Anything that fails goes to an `Unresolved` (insufficient evidence) or `Refuted` (counter-search won) annex — abstention is a correct outcome, not a gap to paper over. Maintain `claim-ledger.md` with one row per claim `claim | risk | domains | counter-search | primary? | status (verified/unresolved/refuted)` — and write the cleared rows into a `verified-claims` digest. Worker reply marker (message text, same channel as EXPAND):
216
+ Anything that fails goes to an `Unresolved` (insufficient evidence) or `Refuted` (counter-search won) annex — abstention is a correct outcome, not a gap to paper over. Record each gate outcome on the claim node itself risk tier, independent source domains, counter-search result, primary source backing, and status — and mirror the cleared nodes into the `verified-claims` digest section at the top of `claim-graph.md`. Worker reply marker (message text, same channel as EXPAND):
197
217
 
198
218
  ```
199
219
  ## CLAIMS
@@ -202,7 +222,7 @@ Anything that fails goes to an `Unresolved` (insufficient evidence) or `Refuted`
202
222
 
203
223
  ## Phase 4 — Synthesize
204
224
 
205
- After convergence and all verifications, re-read the whole journal and write `SYNTHESIS.md`:
225
+ After convergence and all verifications, re-read the whole journal, start from `intent-diff.md`, `claim-graph.md`, and `observation-manifest.md`, then write `SYNTHESIS.md`:
206
226
 
207
227
  ```
208
228
  # Ultraresearch Synthesis: <query>
@@ -213,8 +233,9 @@ Workers: <total> · Waves: <count> · Sources: <count> · Verifications: <count>
213
233
  ## Codebase findings — absolute paths with line references
214
234
  ## Sources (ranked) — URL, what it contains, reliability, access date
215
235
  ## Verified claims — code: claim | verdict | verify-<slug>.md · non-code: only rows cleared into verified-claims
236
+ ## Epistemic instrumentation — intent-vs-reality diff closure, claim graph coverage, observation manifest coverage, independent-observation convergence, verification economics summary, cause-disappearance records
216
237
  ## Contradictions — source A vs source B, resolution with evidence
217
- ## Gaps — what saturation could not answer · unresolved/refuted claim-ledger rows
238
+ ## Gaps — what saturation could not answer · unresolved/refuted claim-graph nodes
218
239
  ## Expansion trace — per wave: workers → markers; convergence reason
219
240
  ```
220
241
 
@@ -57,32 +57,28 @@ For reference-fidelity work, repeat the capture and diff for every referenced vi
57
57
 
58
58
  ### TUI
59
59
 
60
- 1. Capture plain text and an ANSI-preserving copy:
61
-
62
- ```
63
- tmux capture-pane -p > capture.txt
64
- tmux capture-pane -e -p > capture-ansi.txt
65
- ```
66
-
67
- 2. When the TUI evidence will be attached to a PR or reviewed visually, render
68
- the capture through the browser helper from the repository root:
60
+ 1. Render the TUI through the REAL xterm.js web terminal and screenshot it -
61
+ NEVER `tmux capture-pane`, which degrades truecolor and misaligns wide (CJK)
62
+ glyphs. Run the command in a real pty and capture the browser render from the
63
+ repository root:
69
64
 
70
65
  ```
71
66
  node script/qa/web-terminal-visual-qa.mjs --title "TUI Visual QA" \
72
- --from-file capture.txt \
67
+ --command "<tui-command>" \
68
+ --input "{ArrowDown}" --input "{Enter}" \
73
69
  --evidence-dir .omo/evidence/<slug>/tui-web-terminal
74
70
  ```
75
71
 
76
- This produces `terminal.png`, `terminal.html`, `terminal.txt`,
77
- `terminal-ansi.txt`, and `metadata.json`. Treat this as the standard TUI visual
78
- artifact pattern for terminal screenshots. If the project is outside this repo,
79
- copy the same pattern: terminal capture -> browser-rendered page -> PNG +
80
- metadata with cleanup receipt.
72
+ Replay a saved raw stream with `--from-file <capture.ansi>` instead of
73
+ `--command`. This produces `terminal.png` (the true-color artifact),
74
+ `terminal.txt`, `terminal-ansi.txt`, and `metadata.json`. Treat this as the
75
+ standard TUI visual artifact pattern. Outside this repo, copy the pattern:
76
+ real pty -> xterm.js in a browser -> PNG + metadata with cleanup receipt.
81
77
 
82
- 3. Run the check with the REAL terminal width and keep the JSON:
78
+ 2. Run the width check on the produced text and keep the JSON:
83
79
 
84
80
  ```
85
- node "$SKILL_DIR/scripts/visual-qa.mjs" tui-check capture.txt --cols <N>
81
+ node "$SKILL_DIR/scripts/visual-qa.mjs" tui-check .omo/evidence/<slug>/tui-web-terminal/terminal.txt --cols <N>
86
82
  ```
87
83
 
88
84
  Key fields: `maxWidth`, `overflowLines[]`, `borderMisaligned`, `wideCharColumns[]`, `hasAnsi`.
@@ -3,5 +3,6 @@ import type { CommandInfo } from "../slashcommand/types";
3
3
  interface CombinedDescriptionOptions {
4
4
  includeSkills?: boolean;
5
5
  }
6
+ export declare function deduplicatePathAliasedSkills(skills: SkillInfo[]): SkillInfo[];
6
7
  export declare function formatCombinedDescription(skills?: SkillInfo[], commands?: CommandInfo[], options?: CombinedDescriptionOptions): string;
7
8
  export {};
@@ -0,0 +1,9 @@
1
+ import type { CommandInfo } from "../slashcommand/types";
2
+ import type { SkillInfo } from "./types";
3
+ export declare function makeSkill(name: string, description?: string, overrides?: Partial<SkillInfo>): SkillInfo;
4
+ export declare function sharedSkill(name: string, description?: string): SkillInfo;
5
+ export declare function builtinSharedSkill(name: string, description?: string): SkillInfo;
6
+ export declare function localSkill(name: string, description?: string): SkillInfo;
7
+ export declare function userSkill(name: string, description?: string): SkillInfo;
8
+ export declare function opencodeNativeSkill(name: string, description?: string, location?: string): SkillInfo;
9
+ export declare function makeCommand(name: string, description?: string, overrides?: Partial<CommandInfo>): CommandInfo;
@@ -0,0 +1,25 @@
1
+ import type { ToolContext } from "@opencode-ai/plugin/tool";
2
+ import type { LoadedSkill } from "../../../features/opencode-skill-loader/types";
3
+ import type { CommandInfo } from "../../slashcommand/types";
4
+ import type { SkillLoadOptions } from "../types";
5
+ type SkillToolFactory = typeof import("../tools").createSkillTool;
6
+ type TestSkillLoadOptions = Omit<SkillLoadOptions, "directory"> & {
7
+ readonly directory?: SkillLoadOptions["directory"];
8
+ };
9
+ export declare function createSkillTool(options?: TestSkillLoadOptions): ReturnType<SkillToolFactory>;
10
+ export declare function createMockSkill(name: string, options?: {
11
+ readonly agent?: string;
12
+ readonly scope?: LoadedSkill["scope"];
13
+ }): LoadedSkill;
14
+ export declare function createMockSkillWithMcp(name: string, mcpServers: Record<string, unknown>): LoadedSkill;
15
+ export declare function createMockCommand(name: string, scope: CommandInfo["scope"]): {
16
+ name: string;
17
+ path: string;
18
+ metadata: {
19
+ name: string;
20
+ description: string;
21
+ };
22
+ scope: import("../../slashcommand").CommandScope;
23
+ };
24
+ export declare const mockContext: ToolContext;
25
+ export {};