oh-my-opencode 4.4.0 → 4.5.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 (218) hide show
  1. package/.agents/command/get-unpublished-changes.md +148 -0
  2. package/.agents/command/omomomo.md +37 -0
  3. package/.agents/command/publish.md +376 -0
  4. package/.agents/command/remove-deadcode.md +221 -0
  5. package/.agents/command/security-research.md +16 -0
  6. package/.agents/skills/get-unpublished-changes/SKILL.md +24 -0
  7. package/.agents/skills/github-triage/SKILL.md +587 -0
  8. package/.agents/skills/github-triage/scripts/gh_fetch.py +398 -0
  9. package/.agents/skills/hyperplan/SKILL.md +450 -0
  10. package/.agents/skills/omomomo/SKILL.md +36 -0
  11. package/.agents/skills/pre-publish-review/SKILL.md +407 -0
  12. package/.agents/skills/publish/SKILL.md +428 -0
  13. package/.agents/skills/remove-deadcode/SKILL.md +216 -0
  14. package/.agents/skills/security-research/SKILL.md +204 -0
  15. package/.agents/skills/work-with-pr/SKILL.md +360 -0
  16. package/.agents/skills/work-with-pr-workspace/evals/evals.json +76 -0
  17. package/.agents/skills/work-with-pr-workspace/iteration-1/benchmark.json +138 -0
  18. package/.agents/skills/work-with-pr-workspace/iteration-1/benchmark.md +42 -0
  19. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/eval_metadata.json +57 -0
  20. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/grading.json +15 -0
  21. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/code-changes.md +454 -0
  22. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/execution-plan.md +136 -0
  23. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/pr-description.md +47 -0
  24. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/verification-strategy.md +163 -0
  25. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/timing.json +1 -0
  26. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/grading.json +15 -0
  27. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/outputs/code-changes.md +615 -0
  28. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/outputs/execution-plan.md +99 -0
  29. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/outputs/pr-description.md +50 -0
  30. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/outputs/verification-strategy.md +111 -0
  31. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/timing.json +1 -0
  32. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/eval_metadata.json +37 -0
  33. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/grading.json +11 -0
  34. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/outputs/code-changes.md +205 -0
  35. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/outputs/execution-plan.md +78 -0
  36. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/outputs/pr-description.md +42 -0
  37. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/outputs/verification-strategy.md +87 -0
  38. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/timing.json +1 -0
  39. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/grading.json +11 -0
  40. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/outputs/code-changes.md +334 -0
  41. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/outputs/execution-plan.md +86 -0
  42. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/outputs/pr-description.md +23 -0
  43. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/outputs/verification-strategy.md +119 -0
  44. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/timing.json +1 -0
  45. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/eval_metadata.json +32 -0
  46. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/grading.json +10 -0
  47. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/code-changes.md +221 -0
  48. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/execution-plan.md +104 -0
  49. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/pr-description.md +41 -0
  50. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/verification-strategy.md +84 -0
  51. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/timing.json +1 -0
  52. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/grading.json +10 -0
  53. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/code-changes.md +342 -0
  54. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/execution-plan.md +131 -0
  55. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/pr-description.md +39 -0
  56. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/verification-strategy.md +128 -0
  57. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/timing.json +1 -0
  58. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/eval_metadata.json +32 -0
  59. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/grading.json +10 -0
  60. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/outputs/code-changes.md +143 -0
  61. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/outputs/execution-plan.md +82 -0
  62. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/outputs/pr-description.md +51 -0
  63. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/outputs/verification-strategy.md +69 -0
  64. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/timing.json +1 -0
  65. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/grading.json +10 -0
  66. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/outputs/code-changes.md +252 -0
  67. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/outputs/execution-plan.md +83 -0
  68. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/outputs/pr-description.md +33 -0
  69. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/outputs/verification-strategy.md +101 -0
  70. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/timing.json +1 -0
  71. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/eval_metadata.json +32 -0
  72. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/grading.json +10 -0
  73. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/code-changes.md +387 -0
  74. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/execution-plan.md +112 -0
  75. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/pr-description.md +51 -0
  76. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/verification-strategy.md +75 -0
  77. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/timing.json +1 -0
  78. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/grading.json +10 -0
  79. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/outputs/code-changes.md +529 -0
  80. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/outputs/execution-plan.md +127 -0
  81. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/outputs/pr-description.md +42 -0
  82. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/outputs/verification-strategy.md +120 -0
  83. package/.agents/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/timing.json +1 -0
  84. package/.agents/skills/work-with-pr-workspace/iteration-1/review.html +1326 -0
  85. package/.opencode/command/get-unpublished-changes.md +148 -0
  86. package/.opencode/command/omomomo.md +37 -0
  87. package/.opencode/command/publish.md +376 -0
  88. package/.opencode/command/remove-deadcode.md +221 -0
  89. package/.opencode/command/security-research.md +16 -0
  90. package/.opencode/skills/github-triage/SKILL.md +587 -0
  91. package/.opencode/skills/github-triage/scripts/gh_fetch.py +398 -0
  92. package/.opencode/skills/hyperplan/SKILL.md +450 -0
  93. package/.opencode/skills/pre-publish-review/SKILL.md +407 -0
  94. package/.opencode/skills/work-with-pr/SKILL.md +360 -0
  95. package/.opencode/skills/work-with-pr-workspace/evals/evals.json +76 -0
  96. package/.opencode/skills/work-with-pr-workspace/iteration-1/benchmark.json +138 -0
  97. package/.opencode/skills/work-with-pr-workspace/iteration-1/benchmark.md +42 -0
  98. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/eval_metadata.json +57 -0
  99. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/grading.json +15 -0
  100. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/code-changes.md +454 -0
  101. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/execution-plan.md +136 -0
  102. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/pr-description.md +47 -0
  103. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/outputs/verification-strategy.md +163 -0
  104. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/with_skill/timing.json +1 -0
  105. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/grading.json +15 -0
  106. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/outputs/code-changes.md +615 -0
  107. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/outputs/execution-plan.md +99 -0
  108. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/outputs/pr-description.md +50 -0
  109. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/outputs/verification-strategy.md +111 -0
  110. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-1/without_skill/timing.json +1 -0
  111. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/eval_metadata.json +37 -0
  112. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/grading.json +11 -0
  113. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/outputs/code-changes.md +205 -0
  114. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/outputs/execution-plan.md +78 -0
  115. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/outputs/pr-description.md +42 -0
  116. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/outputs/verification-strategy.md +87 -0
  117. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/with_skill/timing.json +1 -0
  118. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/grading.json +11 -0
  119. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/outputs/code-changes.md +334 -0
  120. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/outputs/execution-plan.md +86 -0
  121. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/outputs/pr-description.md +23 -0
  122. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/outputs/verification-strategy.md +119 -0
  123. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-2/without_skill/timing.json +1 -0
  124. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/eval_metadata.json +32 -0
  125. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/grading.json +10 -0
  126. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/code-changes.md +221 -0
  127. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/execution-plan.md +104 -0
  128. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/pr-description.md +41 -0
  129. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/outputs/verification-strategy.md +84 -0
  130. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/with_skill/timing.json +1 -0
  131. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/grading.json +10 -0
  132. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/code-changes.md +342 -0
  133. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/execution-plan.md +131 -0
  134. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/pr-description.md +39 -0
  135. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/outputs/verification-strategy.md +128 -0
  136. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-3/without_skill/timing.json +1 -0
  137. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/eval_metadata.json +32 -0
  138. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/grading.json +10 -0
  139. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/outputs/code-changes.md +143 -0
  140. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/outputs/execution-plan.md +82 -0
  141. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/outputs/pr-description.md +51 -0
  142. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/outputs/verification-strategy.md +69 -0
  143. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/with_skill/timing.json +1 -0
  144. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/grading.json +10 -0
  145. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/outputs/code-changes.md +252 -0
  146. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/outputs/execution-plan.md +83 -0
  147. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/outputs/pr-description.md +33 -0
  148. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/outputs/verification-strategy.md +101 -0
  149. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-4/without_skill/timing.json +1 -0
  150. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/eval_metadata.json +32 -0
  151. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/grading.json +10 -0
  152. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/code-changes.md +387 -0
  153. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/execution-plan.md +112 -0
  154. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/pr-description.md +51 -0
  155. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/outputs/verification-strategy.md +75 -0
  156. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/with_skill/timing.json +1 -0
  157. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/grading.json +10 -0
  158. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/outputs/code-changes.md +529 -0
  159. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/outputs/execution-plan.md +127 -0
  160. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/outputs/pr-description.md +42 -0
  161. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/outputs/verification-strategy.md +120 -0
  162. package/.opencode/skills/work-with-pr-workspace/iteration-1/eval-5/without_skill/timing.json +1 -0
  163. package/.opencode/skills/work-with-pr-workspace/iteration-1/review.html +1326 -0
  164. package/README.ja.md +1 -1
  165. package/README.ko.md +1 -1
  166. package/README.md +1 -1
  167. package/README.ru.md +1 -1
  168. package/README.zh-cn.md +1 -1
  169. package/dist/agents/atlas/agent.d.ts +6 -6
  170. package/dist/agents/prometheus/gemini.d.ts +0 -11
  171. package/dist/agents/prometheus/gpt.d.ts +0 -10
  172. package/dist/agents/prometheus/system-prompt.d.ts +2 -20
  173. package/dist/agents/types.d.ts +1 -16
  174. package/dist/cli/index.js +178 -129
  175. package/dist/config/schema/agent-names.d.ts +3 -3
  176. package/dist/config/schema/agent-overrides.d.ts +208 -208
  177. package/dist/config/schema/categories.d.ts +28 -28
  178. package/dist/config/schema/fallback-models.d.ts +20 -20
  179. package/dist/config/schema/oh-my-opencode-config.d.ts +208 -208
  180. package/dist/features/background-agent/parent-wake-notifier.d.ts +8 -1
  181. package/dist/help/schema/acp.d.ts +95 -0
  182. package/dist/help/schema/doctor.d.ts +147 -0
  183. package/dist/help/schema/sandbox.d.ts +74 -0
  184. package/dist/help/schema/status.d.ts +139 -0
  185. package/dist/hooks/keyword-detector/analyze/default.d.ts +1 -1
  186. package/dist/hooks/keyword-detector/hyperplan/default.d.ts +1 -1
  187. package/dist/hooks/keyword-detector/search/default.d.ts +1 -1
  188. package/dist/hooks/keyword-detector/team/default.d.ts +2 -7
  189. package/dist/hooks/keyword-detector/ultrawork/default.d.ts +1 -9
  190. package/dist/hooks/keyword-detector/ultrawork/gemini.d.ts +1 -16
  191. package/dist/hooks/keyword-detector/ultrawork/gpt.d.ts +1 -10
  192. package/dist/hooks/keyword-detector/ultrawork/planner.d.ts +1 -5
  193. package/dist/hooks/ralph-loop/no-progress-turn-detector.d.ts +7 -0
  194. package/dist/hooks/ralph-loop/pending-verification-handler.d.ts +1 -0
  195. package/dist/hooks/ralph-loop/types.d.ts +1 -0
  196. package/dist/hooks/runtime-fallback/error-classifier.d.ts +1 -0
  197. package/dist/index.js +52205 -50528
  198. package/dist/shared/prompt-async-gate/pending-tool-turn.d.ts +1 -0
  199. package/dist/shared/prompt-async-gate/types.d.ts +4 -3
  200. package/package.json +19 -13
  201. package/dist/agents/atlas/default-prompt-sections.d.ts +0 -6
  202. package/dist/agents/atlas/default.d.ts +0 -2
  203. package/dist/agents/atlas/gemini-prompt-sections.d.ts +0 -6
  204. package/dist/agents/atlas/gemini.d.ts +0 -2
  205. package/dist/agents/atlas/gpt-prompt-sections.d.ts +0 -6
  206. package/dist/agents/atlas/gpt.d.ts +0 -2
  207. package/dist/agents/atlas/kimi-prompt-sections.d.ts +0 -6
  208. package/dist/agents/atlas/kimi.d.ts +0 -2
  209. package/dist/agents/atlas/opus-4-7-prompt-sections.d.ts +0 -6
  210. package/dist/agents/atlas/opus-4-7.d.ts +0 -2
  211. package/dist/agents/atlas/shared-prompt.d.ts +0 -9
  212. package/dist/agents/prometheus/behavioral-summary.d.ts +0 -6
  213. package/dist/agents/prometheus/high-accuracy-mode.d.ts +0 -6
  214. package/dist/agents/prometheus/identity-constraints.d.ts +0 -7
  215. package/dist/agents/prometheus/interview-mode.d.ts +0 -7
  216. package/dist/agents/prometheus/plan-generation.d.ts +0 -7
  217. package/dist/agents/prometheus/plan-template.d.ts +0 -7
  218. package/dist/agents/prometheus/spec-driven-mode.d.ts +0 -7
@@ -0,0 +1,334 @@
1
+ # Code Changes: Fix Atlas Hook Crash on Missing worktree_path
2
+
3
+ ## Change 1: Harden `readBoulderState()` validation
4
+
5
+ **File:** `src/features/boulder-state/storage.ts`
6
+
7
+ ### Before (lines 16-36):
8
+ ```typescript
9
+ export function readBoulderState(directory: string): BoulderState | null {
10
+ const filePath = getBoulderFilePath(directory)
11
+
12
+ if (!existsSync(filePath)) {
13
+ return null
14
+ }
15
+
16
+ try {
17
+ const content = readFileSync(filePath, "utf-8")
18
+ const parsed = JSON.parse(content)
19
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
20
+ return null
21
+ }
22
+ if (!Array.isArray(parsed.session_ids)) {
23
+ parsed.session_ids = []
24
+ }
25
+ return parsed as BoulderState
26
+ } catch {
27
+ return null
28
+ }
29
+ }
30
+ ```
31
+
32
+ ### After:
33
+ ```typescript
34
+ export function readBoulderState(directory: string): BoulderState | null {
35
+ const filePath = getBoulderFilePath(directory)
36
+
37
+ if (!existsSync(filePath)) {
38
+ return null
39
+ }
40
+
41
+ try {
42
+ const content = readFileSync(filePath, "utf-8")
43
+ const parsed = JSON.parse(content)
44
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
45
+ return null
46
+ }
47
+ if (typeof parsed.active_plan !== "string" || typeof parsed.plan_name !== "string") {
48
+ return null
49
+ }
50
+ if (!Array.isArray(parsed.session_ids)) {
51
+ parsed.session_ids = []
52
+ }
53
+ if (parsed.worktree_path !== undefined && typeof parsed.worktree_path !== "string") {
54
+ delete parsed.worktree_path
55
+ }
56
+ return parsed as BoulderState
57
+ } catch {
58
+ return null
59
+ }
60
+ }
61
+ ```
62
+
63
+ **Rationale:** Validates that required fields (`active_plan`, `plan_name`) are strings. Strips `worktree_path` if it's present but not a string (e.g., `null`, number). This prevents downstream crashes from `existsSync(undefined)` and ensures type safety at the boundary.
64
+
65
+ ---
66
+
67
+ ## Change 2: Add try/catch in setTimeout retry callback
68
+
69
+ **File:** `src/hooks/atlas/idle-event.ts`
70
+
71
+ ### Before (lines 62-88):
72
+ ```typescript
73
+ sessionState.pendingRetryTimer = setTimeout(async () => {
74
+ sessionState.pendingRetryTimer = undefined
75
+
76
+ if (sessionState.promptFailureCount >= 2) return
77
+ if (sessionState.waitingForFinalWaveApproval) return
78
+
79
+ const currentBoulder = readBoulderState(ctx.directory)
80
+ if (!currentBoulder) return
81
+ if (!currentBoulder.session_ids?.includes(sessionID)) return
82
+
83
+ const currentProgress = getPlanProgress(currentBoulder.active_plan)
84
+ if (currentProgress.isComplete) return
85
+ if (options?.isContinuationStopped?.(sessionID)) return
86
+ if (options?.shouldSkipContinuation?.(sessionID)) return
87
+ if (hasRunningBackgroundTasks(sessionID, options)) return
88
+
89
+ await injectContinuation({
90
+ ctx,
91
+ sessionID,
92
+ sessionState,
93
+ options,
94
+ planName: currentBoulder.plan_name,
95
+ progress: currentProgress,
96
+ agent: currentBoulder.agent,
97
+ worktreePath: currentBoulder.worktree_path,
98
+ })
99
+ }, RETRY_DELAY_MS)
100
+ ```
101
+
102
+ ### After:
103
+ ```typescript
104
+ sessionState.pendingRetryTimer = setTimeout(async () => {
105
+ sessionState.pendingRetryTimer = undefined
106
+
107
+ try {
108
+ if (sessionState.promptFailureCount >= 2) return
109
+ if (sessionState.waitingForFinalWaveApproval) return
110
+
111
+ const currentBoulder = readBoulderState(ctx.directory)
112
+ if (!currentBoulder) return
113
+ if (!currentBoulder.session_ids?.includes(sessionID)) return
114
+
115
+ const currentProgress = getPlanProgress(currentBoulder.active_plan)
116
+ if (currentProgress.isComplete) return
117
+ if (options?.isContinuationStopped?.(sessionID)) return
118
+ if (options?.shouldSkipContinuation?.(sessionID)) return
119
+ if (hasRunningBackgroundTasks(sessionID, options)) return
120
+
121
+ await injectContinuation({
122
+ ctx,
123
+ sessionID,
124
+ sessionState,
125
+ options,
126
+ planName: currentBoulder.plan_name,
127
+ progress: currentProgress,
128
+ agent: currentBoulder.agent,
129
+ worktreePath: currentBoulder.worktree_path,
130
+ })
131
+ } catch (error) {
132
+ log(`[${HOOK_NAME}] Retry continuation failed`, { sessionID, error: String(error) })
133
+ }
134
+ }, RETRY_DELAY_MS)
135
+ ```
136
+
137
+ **Rationale:** The async callback in setTimeout creates a floating promise. Without try/catch, any error becomes an unhandled rejection that can crash the process. This is the critical safety net even after the `readBoulderState` fix.
138
+
139
+ ---
140
+
141
+ ## Change 3: Defensive guard in `getPlanProgress`
142
+
143
+ **File:** `src/features/boulder-state/storage.ts`
144
+
145
+ ### Before (lines 115-118):
146
+ ```typescript
147
+ export function getPlanProgress(planPath: string): PlanProgress {
148
+ if (!existsSync(planPath)) {
149
+ return { total: 0, completed: 0, isComplete: true }
150
+ }
151
+ ```
152
+
153
+ ### After:
154
+ ```typescript
155
+ export function getPlanProgress(planPath: string): PlanProgress {
156
+ if (typeof planPath !== "string" || !existsSync(planPath)) {
157
+ return { total: 0, completed: 0, isComplete: true }
158
+ }
159
+ ```
160
+
161
+ **Rationale:** Defense-in-depth. Even though `readBoulderState` now validates `active_plan`, the `getPlanProgress` function is a public API that could be called from other paths with invalid input. A `typeof` check before `existsSync` prevents the TypeError from `existsSync(undefined)`.
162
+
163
+ ---
164
+
165
+ ## Change 4: New tests
166
+
167
+ ### File: `src/features/boulder-state/storage.test.ts` (additions)
168
+
169
+ ```typescript
170
+ test("should return null when active_plan is missing", () => {
171
+ // given - boulder.json without active_plan
172
+ const boulderFile = join(SISYPHUS_DIR, "boulder.json")
173
+ writeFileSync(boulderFile, JSON.stringify({
174
+ started_at: "2026-01-01T00:00:00Z",
175
+ session_ids: ["ses-1"],
176
+ plan_name: "plan",
177
+ }))
178
+
179
+ // when
180
+ const result = readBoulderState(TEST_DIR)
181
+
182
+ // then
183
+ expect(result).toBeNull()
184
+ })
185
+
186
+ test("should return null when plan_name is missing", () => {
187
+ // given - boulder.json without plan_name
188
+ const boulderFile = join(SISYPHUS_DIR, "boulder.json")
189
+ writeFileSync(boulderFile, JSON.stringify({
190
+ active_plan: "/path/to/plan.md",
191
+ started_at: "2026-01-01T00:00:00Z",
192
+ session_ids: ["ses-1"],
193
+ }))
194
+
195
+ // when
196
+ const result = readBoulderState(TEST_DIR)
197
+
198
+ // then
199
+ expect(result).toBeNull()
200
+ })
201
+
202
+ test("should strip non-string worktree_path from boulder state", () => {
203
+ // given - boulder.json with worktree_path set to null
204
+ const boulderFile = join(SISYPHUS_DIR, "boulder.json")
205
+ writeFileSync(boulderFile, JSON.stringify({
206
+ active_plan: "/path/to/plan.md",
207
+ started_at: "2026-01-01T00:00:00Z",
208
+ session_ids: ["ses-1"],
209
+ plan_name: "plan",
210
+ worktree_path: null,
211
+ }))
212
+
213
+ // when
214
+ const result = readBoulderState(TEST_DIR)
215
+
216
+ // then
217
+ expect(result).not.toBeNull()
218
+ expect(result!.worktree_path).toBeUndefined()
219
+ })
220
+
221
+ test("should preserve valid worktree_path string", () => {
222
+ // given - boulder.json with valid worktree_path
223
+ const boulderFile = join(SISYPHUS_DIR, "boulder.json")
224
+ writeFileSync(boulderFile, JSON.stringify({
225
+ active_plan: "/path/to/plan.md",
226
+ started_at: "2026-01-01T00:00:00Z",
227
+ session_ids: ["ses-1"],
228
+ plan_name: "plan",
229
+ worktree_path: "/valid/worktree/path",
230
+ }))
231
+
232
+ // when
233
+ const result = readBoulderState(TEST_DIR)
234
+
235
+ // then
236
+ expect(result).not.toBeNull()
237
+ expect(result!.worktree_path).toBe("/valid/worktree/path")
238
+ })
239
+ ```
240
+
241
+ ### File: `src/features/boulder-state/storage.test.ts` (getPlanProgress additions)
242
+
243
+ ```typescript
244
+ test("should handle undefined planPath without crashing", () => {
245
+ // given - undefined as planPath (from malformed boulder state)
246
+
247
+ // when
248
+ const progress = getPlanProgress(undefined as unknown as string)
249
+
250
+ // then
251
+ expect(progress.total).toBe(0)
252
+ expect(progress.isComplete).toBe(true)
253
+ })
254
+ ```
255
+
256
+ ### File: `src/hooks/atlas/index.test.ts` (additions to session.idle section)
257
+
258
+ ```typescript
259
+ test("should handle boulder state without worktree_path gracefully", async () => {
260
+ // given - boulder state with incomplete plan, no worktree_path
261
+ const planPath = join(TEST_DIR, "test-plan.md")
262
+ writeFileSync(planPath, "# Plan\n- [ ] Task 1\n- [x] Task 2")
263
+
264
+ const state: BoulderState = {
265
+ active_plan: planPath,
266
+ started_at: "2026-01-02T10:00:00Z",
267
+ session_ids: [MAIN_SESSION_ID],
268
+ plan_name: "test-plan",
269
+ // worktree_path intentionally omitted
270
+ }
271
+ writeBoulderState(TEST_DIR, state)
272
+
273
+ const mockInput = createMockPluginInput()
274
+ const hook = createAtlasHook(mockInput)
275
+
276
+ // when
277
+ await hook.handler({
278
+ event: {
279
+ type: "session.idle",
280
+ properties: { sessionID: MAIN_SESSION_ID },
281
+ },
282
+ })
283
+
284
+ // then - should call prompt without crashing, continuation should not contain worktree context
285
+ expect(mockInput._promptMock).toHaveBeenCalled()
286
+ const callArgs = mockInput._promptMock.mock.calls[0][0]
287
+ expect(callArgs.body.parts[0].text).toContain("incomplete tasks")
288
+ expect(callArgs.body.parts[0].text).not.toContain("[Worktree:")
289
+ })
290
+
291
+ test("should include worktree context when worktree_path is present in boulder state", async () => {
292
+ // given - boulder state with worktree_path
293
+ const planPath = join(TEST_DIR, "test-plan.md")
294
+ writeFileSync(planPath, "# Plan\n- [ ] Task 1")
295
+
296
+ const state: BoulderState = {
297
+ active_plan: planPath,
298
+ started_at: "2026-01-02T10:00:00Z",
299
+ session_ids: [MAIN_SESSION_ID],
300
+ plan_name: "test-plan",
301
+ worktree_path: "/some/worktree/path",
302
+ }
303
+ writeBoulderState(TEST_DIR, state)
304
+
305
+ const mockInput = createMockPluginInput()
306
+ const hook = createAtlasHook(mockInput)
307
+
308
+ // when
309
+ await hook.handler({
310
+ event: {
311
+ type: "session.idle",
312
+ properties: { sessionID: MAIN_SESSION_ID },
313
+ },
314
+ })
315
+
316
+ // then - should include worktree context in continuation prompt
317
+ expect(mockInput._promptMock).toHaveBeenCalled()
318
+ const callArgs = mockInput._promptMock.mock.calls[0][0]
319
+ expect(callArgs.body.parts[0].text).toContain("[Worktree: /some/worktree/path]")
320
+ })
321
+ ```
322
+
323
+ ---
324
+
325
+ ## Summary of Changes
326
+
327
+ | File | Change | Lines Modified |
328
+ |------|--------|---------------|
329
+ | `src/features/boulder-state/storage.ts` | Validate required fields + sanitize worktree_path + guard getPlanProgress | ~8 lines added |
330
+ | `src/hooks/atlas/idle-event.ts` | try/catch around setTimeout async callback | ~4 lines added |
331
+ | `src/features/boulder-state/storage.test.ts` | 5 new tests for validation | ~60 lines added |
332
+ | `src/hooks/atlas/index.test.ts` | 2 new tests for worktree_path handling | ~50 lines added |
333
+
334
+ Total: ~4 production lines changed, ~8 defensive lines added, ~110 test lines added.
@@ -0,0 +1,86 @@
1
+ # Execution Plan: Fix Atlas Hook Crash on Missing worktree_path
2
+
3
+ ## Bug Analysis
4
+
5
+ ### Root Cause
6
+
7
+ `readBoulderState()` in `src/features/boulder-state/storage.ts` performs minimal validation when parsing `boulder.json`:
8
+
9
+ ```typescript
10
+ const parsed = JSON.parse(content)
11
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null
12
+ if (!Array.isArray(parsed.session_ids)) parsed.session_ids = []
13
+ return parsed as BoulderState // <-- unsafe cast, no field validation
14
+ ```
15
+
16
+ It validates `session_ids` but NOT `active_plan`, `plan_name`, or `worktree_path`. This means a malformed `boulder.json` (e.g., `{}` or missing key fields) passes through and downstream code crashes.
17
+
18
+ ### Crash Path
19
+
20
+ 1. `boulder.json` is written without required fields (manual edit, corruption, partial write)
21
+ 2. `readBoulderState()` returns it as `BoulderState` with `active_plan: undefined`
22
+ 3. Multiple call sites pass `boulderState.active_plan` to `getPlanProgress(planPath: string)`:
23
+ - `src/hooks/atlas/idle-event.ts:72` (inside `setTimeout` callback - unhandled rejection!)
24
+ - `src/hooks/atlas/resolve-active-boulder-session.ts:21`
25
+ - `src/hooks/atlas/tool-execute-after.ts:74`
26
+ 4. `getPlanProgress()` calls `existsSync(undefined)` which throws: `TypeError: The "path" argument must be of type string`
27
+
28
+ ### worktree_path-Specific Issues
29
+
30
+ When `worktree_path` field is missing from `boulder.json`:
31
+ - The `idle-event.ts` `scheduleRetry` setTimeout callback (lines 62-88) has NO try/catch. An unhandled promise rejection from the async callback crashes the process.
32
+ - `readBoulderState()` returns `worktree_path: undefined` which itself is handled in `boulder-continuation-injector.ts` (line 42 uses truthiness check), but the surrounding code in the setTimeout lacks error protection.
33
+
34
+ ### Secondary Issue: Unhandled Promise in setTimeout
35
+
36
+ In `idle-event.ts` lines 62-88:
37
+ ```typescript
38
+ sessionState.pendingRetryTimer = setTimeout(async () => {
39
+ // ... no try/catch wrapper
40
+ const currentBoulder = readBoulderState(ctx.directory)
41
+ const currentProgress = getPlanProgress(currentBoulder.active_plan) // CRASH if active_plan undefined
42
+ // ...
43
+ }, RETRY_DELAY_MS)
44
+ ```
45
+
46
+ The async callback creates a floating promise. Any thrown error becomes an unhandled rejection.
47
+
48
+ ---
49
+
50
+ ## Step-by-Step Plan
51
+
52
+ ### Step 1: Harden `readBoulderState()` validation
53
+ **File:** `src/features/boulder-state/storage.ts`
54
+
55
+ - After the `session_ids` fix, add validation for `active_plan` and `plan_name` (required fields)
56
+ - Validate `worktree_path` is either `undefined` or a string (not `null`, not a number)
57
+ - Return `null` for boulder states with missing required fields
58
+
59
+ ### Step 2: Add try/catch in setTimeout callback
60
+ **File:** `src/hooks/atlas/idle-event.ts`
61
+
62
+ - Wrap the `setTimeout` async callback body in try/catch
63
+ - Log errors with the atlas hook logger
64
+
65
+ ### Step 3: Add defensive guard in `getPlanProgress`
66
+ **File:** `src/features/boulder-state/storage.ts`
67
+
68
+ - Add early return for non-string `planPath` argument
69
+
70
+ ### Step 4: Add tests
71
+ **Files:**
72
+ - `src/features/boulder-state/storage.test.ts` - test missing/malformed fields
73
+ - `src/hooks/atlas/index.test.ts` - test atlas hook with boulder missing worktree_path
74
+
75
+ ### Step 5: Run CI checks
76
+ ```bash
77
+ bun run typecheck
78
+ bun test src/features/boulder-state/storage.test.ts
79
+ bun test src/hooks/atlas/index.test.ts
80
+ bun test # full suite
81
+ ```
82
+
83
+ ### Step 6: Create PR
84
+ - Branch: `fix/atlas-hook-missing-worktree-path`
85
+ - Target: `dev`
86
+ - Run CI and verify passes
@@ -0,0 +1,23 @@
1
+ ## Summary
2
+
3
+ - Fix crash in atlas hook when `boulder.json` is missing `worktree_path` (or other required fields) by hardening `readBoulderState()` validation
4
+ - Wrap the unprotected `setTimeout` retry callback in `idle-event.ts` with try/catch to prevent unhandled promise rejections
5
+ - Add defensive type guard in `getPlanProgress()` to prevent `existsSync(undefined)` TypeError
6
+
7
+ ## Context
8
+
9
+ When `boulder.json` is malformed or manually edited to omit fields, `readBoulderState()` returns an object cast as `BoulderState` without validating required fields. Downstream callers like `getPlanProgress(boulderState.active_plan)` then pass `undefined` to `existsSync()`, which throws a TypeError. This crash is especially dangerous in the `setTimeout` retry callback in `idle-event.ts`, where the error becomes an unhandled promise rejection.
10
+
11
+ ## Changes
12
+
13
+ ### `src/features/boulder-state/storage.ts`
14
+ - `readBoulderState()`: Validate `active_plan` and `plan_name` are strings (return `null` if not)
15
+ - `readBoulderState()`: Strip `worktree_path` if present but not a string type
16
+ - `getPlanProgress()`: Add `typeof planPath !== "string"` guard before `existsSync`
17
+
18
+ ### `src/hooks/atlas/idle-event.ts`
19
+ - Wrap `scheduleRetry` setTimeout async callback body in try/catch
20
+
21
+ ### Tests
22
+ - `src/features/boulder-state/storage.test.ts`: 5 new tests for missing/malformed fields
23
+ - `src/hooks/atlas/index.test.ts`: 2 new tests for worktree_path presence/absence in continuation prompt
@@ -0,0 +1,119 @@
1
+ # Verification Strategy
2
+
3
+ ## 1. Unit Tests (Direct Verification)
4
+
5
+ ### boulder-state storage tests
6
+ ```bash
7
+ bun test src/features/boulder-state/storage.test.ts
8
+ ```
9
+
10
+ Verify:
11
+ - `readBoulderState()` returns `null` when `active_plan` missing
12
+ - `readBoulderState()` returns `null` when `plan_name` missing
13
+ - `readBoulderState()` strips non-string `worktree_path` (e.g., `null`)
14
+ - `readBoulderState()` preserves valid string `worktree_path`
15
+ - `getPlanProgress(undefined)` returns safe default without crashing
16
+ - Existing tests still pass (session_ids defaults, empty object, etc.)
17
+
18
+ ### atlas hook tests
19
+ ```bash
20
+ bun test src/hooks/atlas/index.test.ts
21
+ ```
22
+
23
+ Verify:
24
+ - session.idle handler works with boulder state missing `worktree_path` (no crash, prompt injected)
25
+ - session.idle handler includes `[Worktree: ...]` context when `worktree_path` IS present
26
+ - All 30+ existing tests still pass
27
+
28
+ ### atlas idle-event lineage tests
29
+ ```bash
30
+ bun test src/hooks/atlas/idle-event-lineage.test.ts
31
+ ```
32
+
33
+ Verify existing lineage tests unaffected.
34
+
35
+ ### start-work hook tests
36
+ ```bash
37
+ bun test src/hooks/start-work/index.test.ts
38
+ ```
39
+
40
+ Verify worktree-related start-work tests still pass (these create boulder states with/without `worktree_path`).
41
+
42
+ ## 2. Type Safety
43
+
44
+ ```bash
45
+ bun run typecheck
46
+ ```
47
+
48
+ Verify zero new TypeScript errors. The changes are purely additive runtime guards that align with existing types (`worktree_path?: string`).
49
+
50
+ ## 3. LSP Diagnostics on Changed Files
51
+
52
+ ```
53
+ lsp_diagnostics on:
54
+ - src/features/boulder-state/storage.ts
55
+ - src/hooks/atlas/idle-event.ts
56
+ ```
57
+
58
+ Verify zero errors/warnings.
59
+
60
+ ## 4. Full Test Suite
61
+
62
+ ```bash
63
+ bun test
64
+ ```
65
+
66
+ Verify no regressions across the entire codebase.
67
+
68
+ ## 5. Build
69
+
70
+ ```bash
71
+ bun run build
72
+ ```
73
+
74
+ Verify build succeeds.
75
+
76
+ ## 6. Manual Smoke Test (Reproduction)
77
+
78
+ To manually verify the fix:
79
+
80
+ ```bash
81
+ # Create a malformed boulder.json (missing worktree_path)
82
+ mkdir -p .sisyphus
83
+ echo '{"active_plan": ".sisyphus/plans/test.md", "plan_name": "test", "session_ids": ["ses-1"]}' > .sisyphus/boulder.json
84
+
85
+ # Create a plan file
86
+ mkdir -p .sisyphus/plans
87
+ echo '# Plan\n- [ ] Task 1' > .sisyphus/plans/test.md
88
+
89
+ # Start opencode - atlas hook should NOT crash when session.idle fires
90
+ # Verify /tmp/oh-my-opencode.log shows normal continuation behavior
91
+ ```
92
+
93
+ Also test the extreme case:
94
+ ```bash
95
+ # boulder.json with no required fields
96
+ echo '{}' > .sisyphus/boulder.json
97
+
98
+ # After fix: readBoulderState returns null, atlas hook gracefully skips
99
+ ```
100
+
101
+ ## 7. CI Pipeline
102
+
103
+ After pushing the branch, verify:
104
+ - `ci.yml` workflow passes: tests (split: mock-heavy isolated + batch), typecheck, build
105
+ - No new lint warnings
106
+
107
+ ## 8. Edge Cases Covered
108
+
109
+ | Scenario | Expected Behavior |
110
+ |----------|-------------------|
111
+ | `boulder.json` = `{}` | `readBoulderState` returns `null` |
112
+ | `boulder.json` missing `active_plan` | `readBoulderState` returns `null` |
113
+ | `boulder.json` missing `plan_name` | `readBoulderState` returns `null` |
114
+ | `boulder.json` has `worktree_path: null` | Field stripped, returned as `undefined` |
115
+ | `boulder.json` has `worktree_path: 42` | Field stripped, returned as `undefined` |
116
+ | `boulder.json` has no `worktree_path` | Works normally, no crash |
117
+ | `boulder.json` has valid `worktree_path` | Preserved, included in continuation prompt |
118
+ | setTimeout retry with corrupted boulder.json | Error caught and logged, no process crash |
119
+ | `getPlanProgress(undefined)` | Returns `{ total: 0, completed: 0, isComplete: true }` |
@@ -0,0 +1 @@
1
+ {"total_tokens": null, "duration_ms": 325000, "total_duration_seconds": 325}
@@ -0,0 +1,32 @@
1
+ {
2
+ "eval_id": 3,
3
+ "eval_name": "refactor-split-constants",
4
+ "prompt": "Refactor src/tools/delegate-task/constants.ts to split DEFAULT_CATEGORIES and CATEGORY_MODEL_REQUIREMENTS into separate files. Keep backward compatibility with the barrel export. Make a PR.",
5
+ "assertions": [
6
+ {
7
+ "id": "worktree-isolation",
8
+ "text": "Plan uses git worktree in a sibling directory",
9
+ "type": "manual"
10
+ },
11
+ {
12
+ "id": "multiple-atomic-commits",
13
+ "text": "Uses 2+ commits for the multi-file refactor",
14
+ "type": "manual"
15
+ },
16
+ {
17
+ "id": "barrel-export",
18
+ "text": "Maintains backward compatibility via barrel re-export in constants.ts or index.ts",
19
+ "type": "manual"
20
+ },
21
+ {
22
+ "id": "three-gates",
23
+ "text": "Verification loop includes all 3 gates",
24
+ "type": "manual"
25
+ },
26
+ {
27
+ "id": "real-constants-file",
28
+ "text": "References actual src/tools/delegate-task/constants.ts file and its exports",
29
+ "type": "manual"
30
+ }
31
+ ]
32
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "run_id": "eval-3-with_skill",
3
+ "expectations": [
4
+ {"text": "Plan uses git worktree in a sibling directory", "passed": true, "evidence": "../omo-wt/refactor-delegate-task-constants"},
5
+ {"text": "Uses 2+ commits for the multi-file refactor", "passed": true, "evidence": "Commit 1: category defaults+appends, Commit 2: plan agent prompt+names"},
6
+ {"text": "Maintains backward compatibility via barrel re-export", "passed": true, "evidence": "constants.ts converted to re-export from 4 new files, full import map verified"},
7
+ {"text": "Verification loop includes all 3 gates", "passed": true, "evidence": "Gate A (CI), Gate B (review-work), Gate C (Cubic)"},
8
+ {"text": "References actual src/tools/delegate-task/constants.ts", "passed": true, "evidence": "654 lines analyzed, 4 responsibilities identified, full external+internal import map"}
9
+ ]
10
+ }