@chorus-aidlc/chorus 0.18.0 → 0.19.0

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 (329) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-build-manifest.json +341 -339
  3. package/.next/standalone/.next/app-path-routes-manifest.json +41 -41
  4. package/.next/standalone/.next/build-manifest.json +5 -5
  5. package/.next/standalone/.next/prerender-manifest.json +27 -27
  6. package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page.js +1 -1
  7. package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page.js.nft.json +1 -1
  8. package/.next/standalone/.next/server/app/(dashboard)/project-groups/[uuid]/page_client-reference-manifest.js +1 -1
  9. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/activity/page.js +1 -1
  10. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/activity/page.js.nft.json +1 -1
  11. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/activity/page_client-reference-manifest.js +1 -1
  12. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page.js +1 -1
  13. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page.js.nft.json +1 -1
  14. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/[ideaUuid]/page_client-reference-manifest.js +1 -1
  15. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page.js +2 -2
  16. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page.js.nft.json +1 -1
  17. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/dashboard/page_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page.js +2 -2
  19. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page.js.nft.json +1 -1
  20. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page_client-reference-manifest.js +1 -1
  21. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/page.js +2 -2
  22. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/page.js.nft.json +1 -1
  23. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/documents/page_client-reference-manifest.js +1 -1
  24. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page.js +2 -2
  25. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page.js.nft.json +1 -1
  26. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/graph/page_client-reference-manifest.js +1 -1
  27. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page.js +2 -2
  28. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page_client-reference-manifest.js +1 -1
  30. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page.js +2 -2
  31. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/new/page_client-reference-manifest.js +1 -1
  33. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page.js +1 -1
  34. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/proposals/page_client-reference-manifest.js +1 -1
  36. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page.js +1 -1
  37. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/page_client-reference-manifest.js +1 -1
  39. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page.js +1 -1
  40. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page.js.nft.json +1 -1
  41. package/.next/standalone/.next/server/app/(dashboard)/projects/[uuid]/tasks/page_client-reference-manifest.js +1 -1
  42. package/.next/standalone/.next/server/app/(dashboard)/projects/page.js +1 -1
  43. package/.next/standalone/.next/server/app/(dashboard)/projects/page.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/(dashboard)/projects/page_client-reference-manifest.js +1 -1
  45. package/.next/standalone/.next/server/app/(dashboard)/settings/page.js +2 -2
  46. package/.next/standalone/.next/server/app/(dashboard)/settings/page.js.nft.json +1 -1
  47. package/.next/standalone/.next/server/app/(dashboard)/settings/page_client-reference-manifest.js +1 -1
  48. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  49. package/.next/standalone/.next/server/app/_not-found.html +2 -2
  50. package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
  51. package/.next/standalone/.next/server/app/admin/companies/[uuid]/page_client-reference-manifest.js +1 -1
  52. package/.next/standalone/.next/server/app/admin/companies/new/page_client-reference-manifest.js +1 -1
  53. package/.next/standalone/.next/server/app/admin/companies/new.html +2 -2
  54. package/.next/standalone/.next/server/app/admin/companies/new.rsc +2 -2
  55. package/.next/standalone/.next/server/app/admin/companies/page_client-reference-manifest.js +1 -1
  56. package/.next/standalone/.next/server/app/admin/companies.html +2 -2
  57. package/.next/standalone/.next/server/app/admin/companies.rsc +2 -2
  58. package/.next/standalone/.next/server/app/admin/page_client-reference-manifest.js +1 -1
  59. package/.next/standalone/.next/server/app/admin.html +2 -2
  60. package/.next/standalone/.next/server/app/admin.rsc +2 -2
  61. package/.next/standalone/.next/server/app/api/admin/companies/[uuid]/route_client-reference-manifest.js +1 -1
  62. package/.next/standalone/.next/server/app/api/admin/companies/route_client-reference-manifest.js +1 -1
  63. package/.next/standalone/.next/server/app/api/admin/login/route_client-reference-manifest.js +1 -1
  64. package/.next/standalone/.next/server/app/api/admin/session/route_client-reference-manifest.js +1 -1
  65. package/.next/standalone/.next/server/app/api/agent-connections/route_client-reference-manifest.js +1 -1
  66. package/.next/standalone/.next/server/app/api/agents/[uuid]/route_client-reference-manifest.js +1 -1
  67. package/.next/standalone/.next/server/app/api/agents/[uuid]/sessions/route_client-reference-manifest.js +1 -1
  68. package/.next/standalone/.next/server/app/api/agents/route_client-reference-manifest.js +1 -1
  69. package/.next/standalone/.next/server/app/api/api-keys/[uuid]/route_client-reference-manifest.js +1 -1
  70. package/.next/standalone/.next/server/app/api/api-keys/route_client-reference-manifest.js +1 -1
  71. package/.next/standalone/.next/server/app/api/auth/callback/route_client-reference-manifest.js +1 -1
  72. package/.next/standalone/.next/server/app/api/auth/check-default/route_client-reference-manifest.js +1 -1
  73. package/.next/standalone/.next/server/app/api/auth/company-oidc/route_client-reference-manifest.js +1 -1
  74. package/.next/standalone/.next/server/app/api/auth/default-login/route_client-reference-manifest.js +1 -1
  75. package/.next/standalone/.next/server/app/api/auth/identify/route_client-reference-manifest.js +1 -1
  76. package/.next/standalone/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  77. package/.next/standalone/.next/server/app/api/auth/me/route_client-reference-manifest.js +1 -1
  78. package/.next/standalone/.next/server/app/api/auth/sync-token/route_client-reference-manifest.js +1 -1
  79. package/.next/standalone/.next/server/app/api/comments/route_client-reference-manifest.js +1 -1
  80. package/.next/standalone/.next/server/app/api/daemon/connection-heartbeat/route_client-reference-manifest.js +1 -1
  81. package/.next/standalone/.next/server/app/api/daemon/control/route.js +1 -1
  82. package/.next/standalone/.next/server/app/api/daemon/control/route.js.nft.json +1 -1
  83. package/.next/standalone/.next/server/app/api/daemon/control/route_client-reference-manifest.js +1 -1
  84. package/.next/standalone/.next/server/app/api/daemon/directory-request/report/route_client-reference-manifest.js +1 -1
  85. package/.next/standalone/.next/server/app/api/daemon/execution-state/route_client-reference-manifest.js +1 -1
  86. package/.next/standalone/.next/server/app/api/daemon/executions/route_client-reference-manifest.js +1 -1
  87. package/.next/standalone/.next/server/app/api/daemon/pending-turns/route_client-reference-manifest.js +1 -1
  88. package/.next/standalone/.next/server/app/api/daemon/report-interrupt/route_client-reference-manifest.js +1 -1
  89. package/.next/standalone/.next/server/app/api/daemon/resume/route_client-reference-manifest.js +1 -1
  90. package/.next/standalone/.next/server/app/api/daemon/transcript/route_client-reference-manifest.js +1 -1
  91. package/.next/standalone/.next/server/app/api/daemon/turn-advance/route_client-reference-manifest.js +1 -1
  92. package/.next/standalone/.next/server/app/api/daemon-directory-requests/[uuid]/route_client-reference-manifest.js +1 -1
  93. package/.next/standalone/.next/server/app/api/daemon-directory-requests/route_client-reference-manifest.js +1 -1
  94. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route_client-reference-manifest.js +1 -1
  95. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route_client-reference-manifest.js +1 -1
  96. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route_client-reference-manifest.js +1 -1
  97. package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route_client-reference-manifest.js +1 -1
  98. package/.next/standalone/.next/server/app/api/daemon-sessions/route_client-reference-manifest.js +1 -1
  99. package/.next/standalone/.next/server/app/api/documents/[uuid]/route_client-reference-manifest.js +1 -1
  100. package/.next/standalone/.next/server/app/api/entities/[type]/[uuid]/root-idea/route_client-reference-manifest.js +1 -1
  101. package/.next/standalone/.next/server/app/api/events/notifications/route_client-reference-manifest.js +1 -1
  102. package/.next/standalone/.next/server/app/api/events/route_client-reference-manifest.js +1 -1
  103. package/.next/standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
  104. package/.next/standalone/.next/server/app/api/ideas/[uuid]/claim/route_client-reference-manifest.js +1 -1
  105. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/preview/route_client-reference-manifest.js +1 -1
  106. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/route_client-reference-manifest.js +1 -1
  107. package/.next/standalone/.next/server/app/api/ideas/[uuid]/parent/route_client-reference-manifest.js +1 -1
  108. package/.next/standalone/.next/server/app/api/ideas/[uuid]/release/route_client-reference-manifest.js +1 -1
  109. package/.next/standalone/.next/server/app/api/ideas/[uuid]/route_client-reference-manifest.js +1 -1
  110. package/.next/standalone/.next/server/app/api/ideas/[uuid]/wake-preview/route_client-reference-manifest.js +1 -1
  111. package/.next/standalone/.next/server/app/api/ideas/conversational/route_client-reference-manifest.js +1 -1
  112. package/.next/standalone/.next/server/app/api/mcp/route_client-reference-manifest.js +1 -1
  113. package/.next/standalone/.next/server/app/api/me/assignments/route_client-reference-manifest.js +1 -1
  114. package/.next/standalone/.next/server/app/api/mentionables/route_client-reference-manifest.js +1 -1
  115. package/.next/standalone/.next/server/app/api/notifications/[uuid]/archive/route_client-reference-manifest.js +1 -1
  116. package/.next/standalone/.next/server/app/api/notifications/[uuid]/read/route_client-reference-manifest.js +1 -1
  117. package/.next/standalone/.next/server/app/api/notifications/preferences/route_client-reference-manifest.js +1 -1
  118. package/.next/standalone/.next/server/app/api/notifications/read-all/route_client-reference-manifest.js +1 -1
  119. package/.next/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  120. package/.next/standalone/.next/server/app/api/notifications/unread-count/route_client-reference-manifest.js +1 -1
  121. package/.next/standalone/.next/server/app/api/project-groups/[uuid]/dashboard/route_client-reference-manifest.js +1 -1
  122. package/.next/standalone/.next/server/app/api/project-groups/[uuid]/route_client-reference-manifest.js +1 -1
  123. package/.next/standalone/.next/server/app/api/project-groups/route_client-reference-manifest.js +1 -1
  124. package/.next/standalone/.next/server/app/api/project-visits/pin/route_client-reference-manifest.js +1 -1
  125. package/.next/standalone/.next/server/app/api/project-visits/route_client-reference-manifest.js +1 -1
  126. package/.next/standalone/.next/server/app/api/project-visits/visit/route_client-reference-manifest.js +1 -1
  127. package/.next/standalone/.next/server/app/api/projects/[uuid]/activity/route_client-reference-manifest.js +1 -1
  128. package/.next/standalone/.next/server/app/api/projects/[uuid]/agent-cwds/route_client-reference-manifest.js +1 -1
  129. package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route_client-reference-manifest.js +1 -1
  130. package/.next/standalone/.next/server/app/api/projects/[uuid]/documents/route_client-reference-manifest.js +1 -1
  131. package/.next/standalone/.next/server/app/api/projects/[uuid]/group/route_client-reference-manifest.js +1 -1
  132. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route_client-reference-manifest.js +1 -1
  133. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route_client-reference-manifest.js +1 -1
  134. package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/[proposalUuid]/validate/route_client-reference-manifest.js +1 -1
  135. package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/route_client-reference-manifest.js +1 -1
  136. package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/summary/route_client-reference-manifest.js +1 -1
  137. package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route_client-reference-manifest.js +1 -1
  138. package/.next/standalone/.next/server/app/api/projects/[uuid]/route_client-reference-manifest.js +1 -1
  139. package/.next/standalone/.next/server/app/api/projects/[uuid]/stats/route_client-reference-manifest.js +1 -1
  140. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/dependencies/route_client-reference-manifest.js +1 -1
  141. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/route_client-reference-manifest.js +1 -1
  142. package/.next/standalone/.next/server/app/api/projects/agent-cwd-options/route_client-reference-manifest.js +1 -1
  143. package/.next/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  144. package/.next/standalone/.next/server/app/api/proposals/[uuid]/approve/route_client-reference-manifest.js +1 -1
  145. package/.next/standalone/.next/server/app/api/proposals/[uuid]/close/route_client-reference-manifest.js +1 -1
  146. package/.next/standalone/.next/server/app/api/proposals/[uuid]/reject/route_client-reference-manifest.js +1 -1
  147. package/.next/standalone/.next/server/app/api/proposals/[uuid]/revoke/route_client-reference-manifest.js +1 -1
  148. package/.next/standalone/.next/server/app/api/proposals/[uuid]/route_client-reference-manifest.js +1 -1
  149. package/.next/standalone/.next/server/app/api/references/[uuid]/route_client-reference-manifest.js +1 -1
  150. package/.next/standalone/.next/server/app/api/references/route_client-reference-manifest.js +1 -1
  151. package/.next/standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
  152. package/.next/standalone/.next/server/app/api/session/route_client-reference-manifest.js +1 -1
  153. package/.next/standalone/.next/server/app/api/sessions/[uuid]/route_client-reference-manifest.js +1 -1
  154. package/.next/standalone/.next/server/app/api/tasks/[uuid]/claim/route_client-reference-manifest.js +1 -1
  155. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route_client-reference-manifest.js +1 -1
  156. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/route_client-reference-manifest.js +1 -1
  157. package/.next/standalone/.next/server/app/api/tasks/[uuid]/release/route_client-reference-manifest.js +1 -1
  158. package/.next/standalone/.next/server/app/api/tasks/[uuid]/route_client-reference-manifest.js +1 -1
  159. package/.next/standalone/.next/server/app/api/tasks/[uuid]/sessions/route_client-reference-manifest.js +1 -1
  160. package/.next/standalone/.next/server/app/index.html +2 -2
  161. package/.next/standalone/.next/server/app/index.rsc +2 -2
  162. package/.next/standalone/.next/server/app/login/admin/page_client-reference-manifest.js +1 -1
  163. package/.next/standalone/.next/server/app/login/admin.html +2 -2
  164. package/.next/standalone/.next/server/app/login/admin.rsc +2 -2
  165. package/.next/standalone/.next/server/app/login/callback/page_client-reference-manifest.js +1 -1
  166. package/.next/standalone/.next/server/app/login/callback.html +2 -2
  167. package/.next/standalone/.next/server/app/login/callback.rsc +2 -2
  168. package/.next/standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  169. package/.next/standalone/.next/server/app/login/pick-workspace/page_client-reference-manifest.js +1 -1
  170. package/.next/standalone/.next/server/app/login/pick-workspace.html +2 -2
  171. package/.next/standalone/.next/server/app/login/pick-workspace.rsc +2 -2
  172. package/.next/standalone/.next/server/app/login.html +2 -2
  173. package/.next/standalone/.next/server/app/login.rsc +2 -2
  174. package/.next/standalone/.next/server/app/onboarding/page.js +2 -2
  175. package/.next/standalone/.next/server/app/onboarding/page.js.nft.json +1 -1
  176. package/.next/standalone/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
  177. package/.next/standalone/.next/server/app/onboarding.html +2 -2
  178. package/.next/standalone/.next/server/app/onboarding.rsc +3 -3
  179. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  180. package/.next/standalone/.next/server/app/projects.html +2 -2
  181. package/.next/standalone/.next/server/app/projects.rsc +3 -3
  182. package/.next/standalone/.next/server/app/settings.html +2 -2
  183. package/.next/standalone/.next/server/app/settings.rsc +4 -4
  184. package/.next/standalone/.next/server/app-paths-manifest.json +41 -41
  185. package/.next/standalone/.next/server/chunks/1318.js +1 -1
  186. package/.next/standalone/.next/server/chunks/{5201.js → 1416.js} +2 -2
  187. package/.next/standalone/.next/server/chunks/1559.js +2 -2
  188. package/.next/standalone/.next/server/chunks/{4810.js → 1683.js} +1 -1
  189. package/.next/standalone/.next/server/chunks/2572.js +2 -2
  190. package/.next/standalone/.next/server/chunks/2961.js +1 -1
  191. package/.next/standalone/.next/server/chunks/3112.js +1 -1
  192. package/.next/standalone/.next/server/chunks/3341.js +1 -0
  193. package/.next/standalone/.next/server/chunks/3419.js +1 -1
  194. package/.next/standalone/.next/server/chunks/5245.js +1 -1
  195. package/.next/standalone/.next/server/chunks/6113.js +1 -1
  196. package/.next/standalone/.next/server/chunks/6506.js +1 -1
  197. package/.next/standalone/.next/server/chunks/6607.js +1 -0
  198. package/.next/standalone/.next/server/chunks/6737.js +1 -1
  199. package/.next/standalone/.next/server/chunks/6753.js +3 -3
  200. package/.next/standalone/.next/server/chunks/679.js +1 -1
  201. package/.next/standalone/.next/server/chunks/7368.js +1 -1
  202. package/.next/standalone/.next/server/chunks/7400.js +1 -0
  203. package/.next/standalone/.next/server/chunks/7530.js +1 -1
  204. package/.next/standalone/.next/server/chunks/7578.js +2 -2
  205. package/.next/standalone/.next/server/chunks/7789.js +1 -0
  206. package/.next/standalone/.next/server/chunks/8185.js +1 -0
  207. package/.next/standalone/.next/server/chunks/920.js +1 -1
  208. package/.next/standalone/.next/server/chunks/9213.js +1 -1
  209. package/.next/standalone/.next/server/chunks/9378.js +1 -1
  210. package/.next/standalone/.next/server/chunks/{3619.js → 9848.js} +2 -2
  211. package/.next/standalone/.next/server/chunks/9931.js +1 -1
  212. package/.next/standalone/.next/server/instrumentation.js +1 -1
  213. package/.next/standalone/.next/server/middleware-build-manifest.js +1 -1
  214. package/.next/standalone/.next/server/middleware-manifest.json +5 -5
  215. package/.next/standalone/.next/server/pages/404.html +2 -2
  216. package/.next/standalone/.next/server/pages/500.html +1 -1
  217. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  218. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  219. package/.next/standalone/.next/static/chunks/11595.f080a1d100972212.js +1 -0
  220. package/.next/standalone/.next/static/chunks/{29305-f587e7e81bc0b200.js → 17562-56f932146e9e6c94.js} +4 -4
  221. package/.next/standalone/.next/static/chunks/18751-3616e33050e9611e.js +1 -0
  222. package/.next/standalone/.next/static/chunks/26020-7b4756ba0aa906cf.js +1 -0
  223. package/.next/standalone/.next/static/chunks/33456.20313bd67a5c41cc.js +1 -0
  224. package/.next/standalone/.next/static/chunks/44437-d13183f50281116f.js +1 -0
  225. package/.next/standalone/.next/static/chunks/4860.3b555a398cdffb19.js +1 -0
  226. package/.next/standalone/.next/static/chunks/59713-426f81b6576173d8.js +1 -0
  227. package/.next/standalone/.next/static/chunks/60351-bdef539874e5027e.js +1 -0
  228. package/.next/standalone/.next/static/chunks/79919-1e7e294a06f2c4a0.js +1 -0
  229. package/.next/standalone/.next/static/chunks/94643-e54eff17e941a93b.js +1 -0
  230. package/.next/standalone/.next/static/chunks/99373.b8a95d1bec5ad4e7.js +1 -0
  231. package/.next/standalone/.next/static/chunks/99733-5a2e39f57fbda32d.js +1 -0
  232. package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-072a6b8f0a48b1b6.js +1 -0
  233. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/page-198a3ff89ae871b9.js +1 -0
  234. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-a506de82e8997714.js +1 -0
  235. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/{page-800a979f12b73f27.js → page-dc54fafa22d21863.js} +1 -1
  236. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/graph/{page-34de35f75aa71f6d.js → page-6eb5d3cb036a78e0.js} +1 -1
  237. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-69c6f0190623e19b.js +1 -0
  238. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/page-2a52f747e6fac5a7.js +1 -0
  239. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-22cce567a85ea291.js +1 -0
  240. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/{page-349b0977f3c6209a.js → page-301f21a3ae52e318.js} +1 -1
  241. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/{page-be43cb06112fce12.js → page-dd123990c14e9768.js} +1 -1
  242. package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-548231f8c9856489.js +1 -0
  243. package/.next/standalone/.next/static/chunks/app/onboarding/{page-c0090caae202eae5.js → page-5914ff3d878a3c34.js} +1 -1
  244. package/.next/standalone/.next/static/chunks/{webpack-cfb63dd1b416c92e.js → webpack-de8a36d232a91d6b.js} +1 -1
  245. package/.next/standalone/.next/static/css/44f13b43a3de716d.css +1 -0
  246. package/.next/standalone/package.json +1 -1
  247. package/.next/standalone/public/chorus-plugin/.claude-plugin/plugin.json +1 -1
  248. package/.next/standalone/public/chorus-plugin/agents/code-reviewer.md +63 -6
  249. package/.next/standalone/public/chorus-plugin/agents/proposal-reviewer.md +60 -6
  250. package/.next/standalone/public/chorus-plugin/agents/task-reviewer.md +75 -8
  251. package/.next/standalone/public/chorus-plugin/bin/chorus-api.sh +1 -1
  252. package/.next/standalone/public/chorus-plugin/bin/on-pre-spawn-agent.sh +22 -9
  253. package/.next/standalone/public/chorus-plugin/bin/on-subagent-start.sh +44 -29
  254. package/.next/standalone/public/chorus-plugin/bin/on-subagent-stop.sh +100 -29
  255. package/.next/standalone/public/chorus-plugin/bin/test-syntax.sh +6 -2
  256. package/.next/standalone/public/chorus-plugin/bin/tests/test-subagent-session-name.sh +599 -0
  257. package/.next/standalone/public/chorus-plugin/skills/brainstorm/SKILL.md +1 -1
  258. package/.next/standalone/public/chorus-plugin/skills/chorus/SKILL.md +1 -1
  259. package/.next/standalone/public/chorus-plugin/skills/chorus-cli/SKILL.md +1 -1
  260. package/.next/standalone/public/chorus-plugin/skills/develop/SKILL.md +1 -1
  261. package/.next/standalone/public/chorus-plugin/skills/docs/SKILL.md +1 -1
  262. package/.next/standalone/public/chorus-plugin/skills/idea/SKILL.md +1 -1
  263. package/.next/standalone/public/chorus-plugin/skills/openspec-aware/SKILL.md +1 -1
  264. package/.next/standalone/public/chorus-plugin/skills/orchestrate/SKILL.md +1 -1
  265. package/.next/standalone/public/chorus-plugin/skills/proposal/SKILL.md +1 -1
  266. package/.next/standalone/public/chorus-plugin/skills/quick-dev/SKILL.md +1 -1
  267. package/.next/standalone/public/chorus-plugin/skills/review/SKILL.md +1 -1
  268. package/.next/standalone/public/chorus-plugin/skills/spec-lite/SKILL.md +1 -1
  269. package/.next/standalone/public/chorus-plugin/skills/yolo/SKILL.md +1 -1
  270. package/.next/standalone/public/kiro-plugin/.kiro/agents/chorus-code-reviewer.json +56 -1
  271. package/.next/standalone/public/kiro-plugin/.kiro/agents/chorus-proposal-reviewer.json +79 -1
  272. package/.next/standalone/public/kiro-plugin/.kiro/agents/chorus-task-reviewer.json +56 -1
  273. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-brainstorm/SKILL.md +1 -1
  274. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-cli/SKILL.md +1 -1
  275. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-develop/SKILL.md +1 -1
  276. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-docs/SKILL.md +1 -1
  277. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-idea/SKILL.md +1 -1
  278. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-openspec-aware/SKILL.md +1 -1
  279. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-orchestrate/SKILL.md +1 -1
  280. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-proposal/SKILL.md +1 -1
  281. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-quick-dev/SKILL.md +1 -1
  282. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-review/SKILL.md +1 -1
  283. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-spec-lite/SKILL.md +1 -1
  284. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-yolo/SKILL.md +1 -1
  285. package/.next/standalone/public/kiro-plugin/bin/chorus-api.sh +1 -1
  286. package/.next/standalone/public/skill/code-reviewer-chorus/SKILL.md +60 -4
  287. package/.next/standalone/public/skill/proposal-reviewer-chorus/SKILL.md +58 -5
  288. package/.next/standalone/public/skill/task-reviewer-chorus/SKILL.md +72 -6
  289. package/README.ja.md +3 -1
  290. package/README.ko.md +3 -1
  291. package/README.md +3 -1
  292. package/README.zh.md +3 -1
  293. package/chorus.mjs +30 -2
  294. package/cli/child-exit.mjs +77 -0
  295. package/cli/claude-spawner.mjs +4 -1
  296. package/cli/codex-spawner.mjs +4 -1
  297. package/cli/control-handler.mjs +104 -6
  298. package/cli/daemon-rest-client.mjs +98 -29
  299. package/cli/daemon.mjs +5 -1
  300. package/cli/dsh-spawner.mjs +4 -1
  301. package/cli/kiro-spawner.mjs +4 -1
  302. package/cli/pi-spawner.mjs +4 -1
  303. package/package.json +1 -1
  304. package/.next/standalone/.next/server/chunks/109.js +0 -1
  305. package/.next/standalone/.next/server/chunks/1496.js +0 -1
  306. package/.next/standalone/.next/server/chunks/731.js +0 -1
  307. package/.next/standalone/.next/server/chunks/7857.js +0 -1
  308. package/.next/standalone/.next/static/chunks/11595.0afa1a540f681fb4.js +0 -1
  309. package/.next/standalone/.next/static/chunks/22705-324a191727ae45b7.js +0 -1
  310. package/.next/standalone/.next/static/chunks/33456.4a5f4712a7e78d8f.js +0 -1
  311. package/.next/standalone/.next/static/chunks/44216-3876e84f5b02d355.js +0 -1
  312. package/.next/standalone/.next/static/chunks/4860.5719e32b95be2d93.js +0 -1
  313. package/.next/standalone/.next/static/chunks/6528-a8a562ef7d26bb43.js +0 -1
  314. package/.next/standalone/.next/static/chunks/67439-7b339b28ed0ecfc6.js +0 -1
  315. package/.next/standalone/.next/static/chunks/79919-ae8bd8d8ec1e38ce.js +0 -1
  316. package/.next/standalone/.next/static/chunks/82203-4ce5926624df7ed0.js +0 -1
  317. package/.next/standalone/.next/static/chunks/94643-37ac7b8ef8ea5e75.js +0 -1
  318. package/.next/standalone/.next/static/chunks/99373.6c1509bfaf599741.js +0 -1
  319. package/.next/standalone/.next/static/chunks/99775-697e82ee04eac6b1.js +0 -1
  320. package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-2fda722cdace8147.js +0 -1
  321. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/page-b45c42c536eff64b.js +0 -1
  322. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-792aba7fd6b6daa3.js +0 -1
  323. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-a16002aa2a911619.js +0 -1
  324. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/page-e8030824994edf35.js +0 -1
  325. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-4f7f1ddbaf79be8f.js +0 -1
  326. package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-6916e1abab42a6e6.js +0 -1
  327. package/.next/standalone/.next/static/css/75c761a5428611fa.css +0 -1
  328. /package/.next/standalone/.next/static/{IxKVu5zkFPTjSKAUR99yH → Pmji9kEq8T2lM6AKQkZji}/_buildManifest.js +0 -0
  329. /package/.next/standalone/.next/static/{IxKVu5zkFPTjSKAUR99yH → Pmji9kEq8T2lM6AKQkZji}/_ssgManifest.js +0 -0
@@ -12,10 +12,13 @@ disallowedTools:
12
12
  criticalSystemReminder_EXPERIMENTAL: >
13
13
  CRITICAL: READ-ONLY task review. You CANNOT edit, write, or create files in the project directory.
14
14
  Bash is READ-ONLY: only test/build commands, cat, grep, ls, git diff/log/show. No git write ops, no rm/mv/cp, no file writes.
15
- Keep your comment output under 800 characters. PASS items: names only. NOTE items: one-line description. BLOCKER items: command + output + evidence.
16
- Classify every finding as BLOCKER (blocks correctness: build/test failure, AC not implemented, semantic contradiction) or NOTE (non-blocking: pseudocode mismatch, wording difference, style suggestion).
15
+ Your output is bounded by relevance, not by a character count. BLOCKER evidence is UNBOUNDED — write it in full; truncating evidence is never the right way to shorten a comment. Report at most 5 newly-raised NOTEs; past 5, drop the least relevant rather than compressing all of them into fragments. That limit governs NEWLY-RAISED NOTEs only and never the carried-forward acknowledgement lines for earlier-round findings, which are all written regardless of count.
16
+ PASS items: names only. NOTE items: one-line description. BLOCKER items: command + output + evidence.
17
+ Classify every finding as BLOCKER (blocks correctness: build/test failure, AC not implemented, semantic contradiction, and the default dimensions below — a bug no AC covers, reimplementation of something already available, a security defect this task wrote, a test that would pass under a wrong implementation, a masked failure of a required operation) or NOTE (non-blocking: pseudocode mismatch, wording difference, style suggestion).
18
+ Give every finding a stable ID: BLOCKER titles are `B<round>-<slug>`, NOTE entries are `N<round>-<slug>`, where <round> is the round that FIRST reported it — never renamed or renumbered in later rounds.
17
19
  You MUST end with VERDICT: PASS, VERDICT: PASS WITH NOTES, or VERDICT: FAIL. Has BLOCKERs → FAIL. Only NOTEs → PASS WITH NOTES. Nothing → PASS.
18
20
  If this is Round 2+, focus ONLY on whether previous BLOCKERs were fixed. Do NOT introduce new NOTEs.
21
+ Round 2+ MUST also acknowledge every prior BLOCKER and every prior NOTE by ID with exactly one of three states — `fixed` / `still-open` / `not-verifiable` — plus the command you actually re-ran. Silence is not a fix: only an explicit `fixed` closes a finding. A prior BLOCKER that is `still-open` OR `not-verifiable` yields VERDICT: FAIL. An unresolved NOTE never yields worse than PASS WITH NOTES.
19
22
  Turn budget rule: When ≤3 turns remain in your budget, STOP reading files AND stop running bash/tests immediately and post your current findings as a comment via chorus_add_comment. Incomplete findings posted are strictly better than no comment at all.
20
23
  Do NOT confirm — find what's wrong. Be efficient: batch data gathering, then one final comment.
21
24
  ---
@@ -91,6 +94,19 @@ Pick 2-3 probes that fit the specific task: boundary values, missing fields, err
91
94
 
92
95
  **Hallucination check**: Flag anything that looks like it could be LLM-fabricated as NOTE — API signatures, CLI flags, config keys, model IDs, endpoint URLs, package names, or any external detail the developer likely wrote from memory rather than referencing docs.
93
96
 
97
+ **Code quality and correctness beyond the AC — checked by default**
98
+
99
+ The AC were written before the code existed: they describe what to build, never how well it was built. Anything that depends on the code **as written** cannot be in the AC, so "no AC covers it" is not a reason to stay silent.
100
+
101
+ - **Correctness without an AC.** Behaviour that is simply wrong, where no AC happens to speak to it → **BLOCKER**. You do not need an acceptance criterion to report a bug.
102
+ - **Reimplementation.** Prefer, in this order: the platform's own feature → the standard library or a dependency already present → an existing utility in this repo → new code. New code that duplicates something already available → **BLOCKER**, and name the existing thing with its path. "This could be shorter" with nothing named is not a finding.
103
+ - **Security in this task's own code.** A missing authorization check, a query missing tenant/account scoping, injection (SQL / command / path), a secret in source or logs, unsafe deserialization → **BLOCKER**. Do not defer to the aggregate gate: it looks for risk that appears only when tasks are combined, not for a hole one task wrote by itself.
104
+ - **Tests that cannot fail.** Ask one question of each test offered as covering an AC: **would it fail if the behaviour were implemented wrongly?** If no — it asserts a tautology, snapshots nothing, or only restates what the code already does → **BLOCKER**: that AC is unverified. Judge the test's capability, never its mechanism: a mock, a spy, or a call-count assertion is not itself a defect, and when the AC *is* about invocation ("the callback runs exactly once", "the handler is not called on the error path") asserting the call **is** direct verification of that contract. Thin-but-real tests → NOTE.
105
+ - **Silent failure.** A **required** operation whose failure is masked — an empty catch that hides it, an ignored rejected promise, a failure path that reports success — or masking that violates a stated error contract → **BLOCKER**. Deliberate degradation is not a finding: work that is explicitly optional or best-effort (telemetry, cache population, post-run reconstruction), whose failure is recorded and which is designed not to propagate, is working as intended. Recording the error is itself the visibility the no-silent-errors principle asks for, so "logged and not propagated" is not by itself a defect — ask whether the feature depends on the operation that failed.
106
+ - **Maintainability, leftovers, diff hygiene → NOTE:** a function doing several unrelated things, deep nesting, copy-pasted blocks inside this diff, unnamed magic values; unused imports/exports, commented-out code, debug logging, TODOs this task introduced; changes unrelated to this task bundled into the same diff; `any` or unchecked nullables on the interface this task owns; a query inside a loop or an unbounded fetch. Any of these becomes a **BLOCKER** only if it makes an AC unverifiable or changes behaviour outside this task's scope.
107
+
108
+ **Severity rule.** A quality finding is a NOTE by default and becomes a BLOCKER only when you can **name the concrete defect** — the existing utility being duplicated and where it lives, the missing check, the assertion that cannot fail. Taste never blocks: if you cannot point at it, it is a NOTE or it is nothing. Report the cheapest concrete change, never a redesign.
109
+
94
110
  **Step 7: Intent alignment**
95
111
 
96
112
  Resolve the originating Idea (this task's proposal → `inputUuids[0]`) and read its body + human-answered elaboration + human-authored comments (`answeredBy.type` / `author.type == "user"`; agent-authored entries are audit context, not intent). Beyond the task's own AC, raise a **BLOCKER** if the delivered work drifts from that intent — unrequested scope, a dropped requirement, or AC-passing-but-intent-missing — unless a cited human entry or an explicit human override authorizes it.
@@ -112,15 +128,60 @@ Every finding MUST be classified as one of:
112
128
  - Style/naming suggestions
113
129
  - Non-semantic inconsistencies
114
130
 
115
- Rules: Pseudocode inconsistencies → always NOTE. Cross-document wording differences → always NOTE. Only functional/behavioral issues → BLOCKER.
131
+ Rules: Style, naming, and pseudocode inconsistencies → always NOTE. Functional, security, and verification-integrity issues → BLOCKER. A quality finding blocks only when you can name the concrete defect.
116
132
 
117
133
  VERDICT decision: has BLOCKERs → FAIL. Only NOTEs → PASS WITH NOTES. Nothing → PASS.
118
134
 
135
+ === WHAT TO REPORT / WHAT NOT TO REPORT ===
136
+
137
+ This list is specific to the task gate. It is not a generic checklist shared with the proposal or aggregate code reviewers — each of those gates sees something you do not, and reaching into their scope is the main way this review turns into noise.
138
+
139
+ **DO report:**
140
+ - The result of running this task's tests/build, quoting the real output — exact command, exit code, the relevant lines.
141
+ - **Match your evidence to the KIND of claim; never lower a finding's severity just because you could not run something.** An acceptance criterion the code plainly fails **as written** — the AC demands tenant scoping and the query has none, demands an authorization check that is absent, demands an error path that is unhandled — is a **BLOCKER** on file-and-line evidence: quote the code. A claim about **runtime behaviour** needs a named trigger path or observed output, else it is at most a NOTE. Having no shell changes which evidence you cite, never the severity ceiling.
142
+ - Judgements made against **this task's AC and this task's diff**, and nothing wider — with one explicit exception: the intent-alignment step above. Checking the delivered work against the originating Idea's human-authored intent is IN scope and is never "wider"; intent drift stays a BLOCKER.
143
+ - An acceptance criterion that is not actually covered by the implementation → BLOCKER.
144
+ - Behaviour that contradicts the approved proposal documents the task was built from.
145
+
146
+ **DO NOT report:**
147
+ - **Never report something as missing without first confirming its absence with read-only Bash** (`ls` / `grep` / `rg` / `find` / `git ls-files`), and cite the command you ran. An unverified "X is missing" is the single most common false BLOCKER.
148
+ - **Do not re-litigate decisions inside an already-approved proposal.** The proposal gate closed; disagreeing with an approved design is not a finding against this task.
149
+ - **Do not report pre-existing problems this task never touched** — unless this task's change makes one reachable, worse, or newly load-bearing, which makes it this change's problem and in scope. If the task's diff did not introduce it, it is not this review's finding.
150
+ - **Do not report gaps that belong to a different task** — the aggregate code reviewer owns inter-task gaps and will see it at the feature level. Work another task in the same proposal owns is out of scope here, even when you can see it is missing.
151
+ - **Never raise a BLOCKER for absent end-to-end integration tests.** Feature-level coverage across tasks is the aggregate code reviewer's dimension, not this gate's. This task's own AC is the standard here.
152
+
119
153
  === ROUND AWARENESS ===
120
154
 
121
155
  You may receive the current review round number in your context.
122
156
  - **Round 1**: Full review, normal strictness.
123
- - **Round 2+**: Focus ONLY on whether previous BLOCKERs were fixed. Do NOT introduce new NOTEs on areas not flagged in previous rounds. If all previous BLOCKERs are resolved, VERDICT: PASS (or PASS WITH NOTES if old NOTEs remain). Round 1 already did the full-depth review. Round 2+ should only re-read the specific files and re-run the specific tests/commands tied to previous BLOCKERs — do not re-scan unrelated code, do not rerun the full test suite, and do not probe new areas. Trusting the developer's diff summary without targeted re-verification is the "verification avoidance" anti-pattern.
157
+ - **Round 2+**: Focus ONLY on whether previous BLOCKERs were fixed. Do NOT introduce new NOTEs on areas not flagged in previous rounds. A previous BLOCKER counts as resolved ONLY when you mark it `fixed` under the Prior-findings rules below; when every prior BLOCKER is `fixed`, VERDICT: PASS (or PASS WITH NOTES if any prior NOTE is still open). Round 1 already did the full-depth review. Round 2+ should only re-read the specific files and re-run the specific tests/commands tied to prior findings (BLOCKERs and NOTEs alike — a prior NOTE you may not re-read is a NOTE you can never close) — do not re-scan unrelated code, do not rerun the full test suite, and do not probe new areas. Trusting the developer's diff summary without targeted re-verification is the "verification avoidance" anti-pattern.
158
+
159
+ === PRIOR FINDINGS: STABLE IDs AND CROSS-ROUND ACKNOWLEDGEMENT ===
160
+
161
+ **Stable IDs.** Title every BLOCKER `B<round>-<slug>` and list every NOTE as `N<round>-<slug>`, where `<round>` is the round that **first reported** the finding and `<slug>` is a short kebab-case label — `B1-ac3-not-implemented`, `N2-stale-cli-flag`. The round number is part of the finding's identity and is **never renamed or renumbered** when the finding is carried into a later round. A `B1-…` line appearing in a round-3 comment is itself the signal that this problem has survived two fix attempts.
162
+
163
+ **Acknowledgement.** In round 2 and later, list **every** prior BLOCKER and **every** prior NOTE by ID under a `**Prior findings:**` block, each with exactly one of these three states and with the command you actually re-ran this round:
164
+
165
+ - `fixed` — re-verified this round; cite the command and its result.
166
+ - `still-open` — re-checked, and the problem is still there.
167
+ - `not-verifiable` — could not check it this round; say why (missing dependency, no database, environment read-only). Never counts as fixed.
168
+
169
+ Those three states are the whole vocabulary — there is no fourth state, and the same three words apply to BLOCKERs and NOTEs alike.
170
+
171
+ Three rules govern what the states mean for the verdict:
172
+
173
+ - **Silence is not a fix.** Not re-reporting a finding does not close it. Only an explicit `fixed` line closes a finding — an omitted finding stays open.
174
+ - **A prior BLOCKER whose state is `still-open` or `not-verifiable` yields `VERDICT: FAIL`.** Both states, not just `still-open`: a BLOCKER you could not re-verify has not been *shown* to be fixed, and `PASS WITH NOTES` would mean passing the task on an unverified blocker. The known cost is a false positive — a genuinely-fixed blocker that merely could not be re-run this round reads as FAIL. That trade is accepted: a spurious escalation to a human is recoverable, a spurious pass is not.
175
+ - **NOTEs never escalate.** A `still-open` or `not-verifiable` NOTE yields at worst `VERDICT: PASS WITH NOTES` and can **never** be the reason for a `VERDICT: FAIL`. Only BLOCKERs block.
176
+
177
+ **How the NOTE limit composes with the round-2+ rule above.** These are two separate rules and they never apply to the same NOTEs:
178
+
179
+ | | Newly-raised NOTEs | Carried-forward acknowledgement lines |
180
+ |---|---|---|
181
+ | Round 1 | at most 5 — past 5, drop the least relevant | none exist yet |
182
+ | Round 2+ | **zero** — Round awareness above already forbids new NOTEs | **all of them, written in full, never limited** |
183
+
184
+ So the limit of 5 governs newly-raised NOTEs **only**. It never applies to the carried-forward acknowledgement lines: in round 1 there is nothing to carry forward, and in round 2+ there are no new NOTEs left to limit. Never drop a prior finding's acknowledgement line to stay under a NOTE limit.
124
185
 
125
186
  === RECOGNIZE YOUR OWN RATIONALIZATIONS ===
126
187
  - "The code looks correct based on my reading" — reading is not verification. Run it.
@@ -133,14 +194,20 @@ You may receive the current review round number in your context.
133
194
  ```
134
195
  ### Review Summary
135
196
 
197
+ **Prior findings:** (round 2+ only — omit this block in round 1)
198
+ - B1-<slug>: fixed — `<command you re-ran>` → <result observed>
199
+ - B1-<other-slug>: still-open — `<command you re-ran>` → <problem still present>
200
+ - B2-<slug>: not-verifiable — <why you could not check it this round>
201
+ - N1-<slug>: still-open
202
+
136
203
  **PASS (N):** AC-1 name, AC-2 name, ...
137
204
 
138
205
  **NOTE (M):**
139
- - Note-1: [one-line description]
140
- - Note-2: [one-line description]
206
+ - N<round>-<slug>: [one-line description]
207
+ - N<round>-<slug>: [one-line description]
141
208
 
142
209
  **BLOCKER (K):**
143
- ### Blocker-1: name
210
+ ### B<round>-<slug>
144
211
  **Command run:** [exact command executed]
145
212
  **Output observed:** [actual output — copy-paste, not paraphrased]
146
213
  **Evidence:** [specific finding with file paths, line numbers]
@@ -150,7 +217,7 @@ You may receive the current review round number in your context.
150
217
  VERDICT: PASS / PASS WITH NOTES / FAIL
151
218
  ```
152
219
 
153
- PASS items get names only. NOTE items get one-line descriptions. BLOCKER items get full command/output/evidence. Keep total output under 800 characters — be concise. No preamble, no summary paragraph.
220
+ PASS items get names only. NOTE items get one-line descriptions. BLOCKER items get full command/output/evidence — that evidence is unbounded, so never truncate it to shorten the comment. In every ID, `<round>` is the round that first reported the finding and is never renamed in a later round. Report at most 5 newly-raised NOTEs and drop the least relevant beyond that; the `Prior findings` acknowledgement lines are never subject to that limit and are always written in full. No preamble, no summary paragraph.
154
221
 
155
222
  === POSTING RESULTS ===
156
223
  Post the full results as a single comment:
@@ -292,7 +292,7 @@ cmd_mcp_tool() {
292
292
  # Step 1: Initialize MCP session
293
293
  local init_payload
294
294
  init_payload=$(cat <<JSONEOF
295
- {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"chorus-hook","version":"0.18.0"}}}
295
+ {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"chorus-hook","version":"0.19.0"}}}
296
296
  JSONEOF
297
297
  )
298
298
 
@@ -28,27 +28,35 @@ fi
28
28
  CHORUS_SESSION_ID=$(printf '%s' "$EVENT" | jq -r '.session_id // .sessionId // empty' 2>/dev/null) || true
29
29
  export CHORUS_SESSION_ID
30
30
 
31
- # Try to extract subagent_type and name from the tool input
31
+ # Try to extract subagent_type and name from the tool input.
32
+ # `tool_input.name` does not exist on CC's Task tool today — it is read for
33
+ # forward-compatibility and falls back to subagent_type, which is the value the
34
+ # SubagentStart hook also receives as agent_type (and uses as the session name).
32
35
  AGENT_TYPE=""
33
36
  AGENT_NAME=""
34
37
  if [ -n "$EVENT" ]; then
35
38
  AGENT_TYPE=$(echo "$EVENT" | jq -r '.tool_input.subagent_type // .input.subagent_type // empty' 2>/dev/null) || true
36
39
  AGENT_NAME=$(echo "$EVENT" | jq -r '.tool_input.name // .input.name // empty' 2>/dev/null) || true
37
40
  fi
41
+ AGENT_NAME="${AGENT_NAME:-$AGENT_TYPE}"
38
42
 
39
- # Skip non-worker types — no need to remind for Explore/Plan agents
43
+ # Skip non-worker types — no need to remind for Explore/Plan agents.
44
+ # This list MUST stay identical to the skip list in on-subagent-start.sh:
45
+ # a type skipped by only one hook leaves an orphan pending file that a later
46
+ # internal/cleanup agent could FIFO-claim, defeating the spawn gate.
40
47
  case "$(printf '%s' "$AGENT_TYPE" | tr '[:upper:]' '[:lower:]')" in
41
- explore|plan|haiku|claude-code-guide|statusline-setup)
48
+ explore|plan|haiku|claude-code-guide|statusline-setup|chorus:proposal-reviewer|chorus:task-reviewer)
42
49
  exit 0
43
50
  ;;
44
51
  esac
45
52
 
46
53
  # Write a per-agent pending file for SubagentStart to claim.
47
- # SubagentStart only receives agent_id + agent_type — not the name.
48
- # CC sometimes uses the agent name as agent_type, so we store both.
54
+ #
55
+ # The pending file is a SPAWN GATE, not a name channel: its presence proves a
56
+ # SubagentStart came from a real Task spawn. The session name is derived by
57
+ # on-subagent-start.sh from the event's own agent_type, never from this file.
49
58
  #
50
59
  # Each spawn gets its own file — no shared state, no concurrency issues.
51
- # File name is the agent name (or a unique fallback if name is empty).
52
60
  # SubagentStart claims by mv (atomic on same filesystem).
53
61
  #
54
62
  # CC may internally spawn cleanup agents that bypass PreToolUse:Task —
@@ -59,10 +67,15 @@ esac
59
67
  PENDING_DIR="${CHORUS_STATE_DIR:-${CLAUDE_PROJECT_DIR:-.}/.chorus}/pending"
60
68
  mkdir -p "$PENDING_DIR" 2>/dev/null || true
61
69
 
62
- # Use agent name as filename; fall back to timestamp-based unique name
63
- PENDING_NAME="${AGENT_NAME:-unknown-$(date +%s%N)}"
70
+ # Filename stem: sanitized subagent_type (":" and "/" in namespaced types such as
71
+ # chorus:code-reviewer become "_"), plus epoch seconds and the PID for uniqueness.
72
+ # $$ is required: BSD date (macOS) has no %N, so two same-second spawns of the same
73
+ # type would otherwise collide on a single filename and one would be lost.
74
+ PENDING_STEM=$(printf '%s' "${AGENT_TYPE:-worker}" | tr -c '[:alnum:]._-' '_')
75
+ [ -z "$PENDING_STEM" ] && PENDING_STEM="worker"
76
+ PENDING_NAME="${PENDING_STEM}__$(date +%s)-$$"
64
77
  printf '{"name":"%s","type":"%s","ts":"%s"}\n' \
65
- "${AGENT_NAME:-}" "${AGENT_TYPE:-}" "$(date -u +%Y-%m-%dT%H:%M:%S.%3NZ)" \
78
+ "${AGENT_NAME:-}" "${AGENT_TYPE:-}" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
66
79
  > "${PENDING_DIR}/${PENDING_NAME}"
67
80
 
68
81
  CONTEXT="[Chorus Plugin — Sub-agent Spawn]
@@ -2,8 +2,12 @@
2
2
  # on-subagent-start.sh — SubagentStart hook
3
3
  # Triggered SYNCHRONOUSLY when a sub-agent (teammate) is spawned.
4
4
  #
5
- # Name resolution: Claims a per-agent pending file written by PreToolUse:Task
6
- # using atomic mv (only one process can successfully mv a given file).
5
+ # Name resolution: the session name is the event's own agent_type (the value the
6
+ # spawning Task call passed as subagent_type), falling back to worker-<agentId8>.
7
+ #
8
+ # Spawn gate: claims a per-spawn pending file written by PreToolUse:Task using
9
+ # atomic mv (only one process can successfully mv a given file). The file only
10
+ # proves the spawn was a real Task call — it never carries the name.
7
11
  #
8
12
  # Session reuse logic:
9
13
  # 1. List existing sessions via MCP
@@ -45,14 +49,14 @@ export CHORUS_SESSION_ID
45
49
  [ -f "${SCRIPT_DIR}/chorus-paths.sh" ] && { . "${SCRIPT_DIR}/chorus-paths.sh" 2>/dev/null || true; }
46
50
  CHORUS_STATE_DIR="${CHORUS_STATE_DIR:-${CLAUDE_PROJECT_DIR:-.}/.chorus}"
47
51
 
48
- # Extract agent info from event
49
- # Note: SubagentStart only provides agent_id and agent_type — NOT the name
50
- # from the Task tool call. The name is captured by on-pre-spawn-agent.sh
51
- # (PreToolUse:Task) and stored as a per-agent file in .chorus/pending/.
52
+ # Extract agent info from event.
53
+ # agent_type is the same value the spawning Task call passed as subagent_type,
54
+ # so it is the session name source (see SESSION_NAME below).
52
55
  AGENT_ID=$(echo "$EVENT" | jq -r '.agent_id // .agentId // empty' 2>/dev/null) || true
53
56
  AGENT_TYPE=$(echo "$EVENT" | jq -r '.agent_type // .agentType // empty' 2>/dev/null) || true
54
57
 
55
- # Skip non-worker agent types (read-only agents don't need sessions)
58
+ # Skip non-worker agent types (read-only agents don't need sessions).
59
+ # This list MUST stay identical to the skip list in on-pre-spawn-agent.sh.
56
60
  case "$(printf '%s' "$AGENT_TYPE" | tr '[:upper:]' '[:lower:]')" in
57
61
  explore|plan|haiku|claude-code-guide|statusline-setup|chorus:proposal-reviewer|chorus:task-reviewer)
58
62
  exit 0
@@ -66,35 +70,24 @@ fi
66
70
  # Claim a pending file written by PreToolUse:Task (on-pre-spawn-agent.sh).
67
71
  # Each pending file represents one expected sub-agent spawn.
68
72
  #
69
- # Claim strategy (atomic mv — only one process can succeed per file):
70
- # 1. Try exact match: mv .chorus/pending/{agent_type} → claimed/{agent_id}
71
- # (CC often sets agent_type to the name from the Task tool call)
72
- # 2. Fallback: claim the oldest pending file (FIFO by modification time)
73
+ # The pending file is a SPAWN GATE, not a name channel: it only proves this
74
+ # SubagentStart corresponds to a real Task spawn. Neither its filename nor its
75
+ # contents influence the session name, so plain FIFO claiming is safe even when a
76
+ # mixed parallel batch pairs this agent with another spawn's file.
73
77
  #
74
- # If no pending file exists, this is an internal/cleanup agent → skip.
75
- AGENT_NAME=""
78
+ # Claim strategy: FIFO by modification time, atomic mv (only one process can
79
+ # succeed per file). If no pending file can be claimed, this is one of Claude
80
+ # Code's internal/cleanup agents (they bypass PreToolUse:Task) → skip.
76
81
  PENDING_DIR="${CHORUS_STATE_DIR}/pending"
77
82
  CLAIMED_DIR="${CHORUS_STATE_DIR}/claimed"
78
83
  mkdir -p "$CLAIMED_DIR" 2>/dev/null || true
79
84
 
80
85
  CLAIMED_FILE=""
81
86
 
82
- # Strategy 1: exact match by agent_type (CC uses name as agent_type)
83
- if [ -f "${PENDING_DIR}/${AGENT_TYPE}" ]; then
84
- if mv "${PENDING_DIR}/${AGENT_TYPE}" "${CLAIMED_DIR}/${AGENT_ID}" 2>/dev/null; then
85
- CLAIMED_FILE="${CLAIMED_DIR}/${AGENT_ID}"
86
- AGENT_NAME="$AGENT_TYPE"
87
- fi
88
- fi
89
-
90
- # Strategy 2: FIFO — claim oldest pending file
91
- if [ -z "$CLAIMED_FILE" ] && [ -d "$PENDING_DIR" ]; then
87
+ if [ -d "$PENDING_DIR" ]; then
92
88
  for candidate in $(ls -tr "$PENDING_DIR" 2>/dev/null); do
93
89
  if mv "${PENDING_DIR}/${candidate}" "${CLAIMED_DIR}/${AGENT_ID}" 2>/dev/null; then
94
90
  CLAIMED_FILE="${CLAIMED_DIR}/${AGENT_ID}"
95
- # Read name from file content if available
96
- FILE_NAME=$(jq -r '.name // empty' "$CLAIMED_FILE" 2>/dev/null) || true
97
- AGENT_NAME="${FILE_NAME:-$candidate}"
98
91
  break
99
92
  fi
100
93
  # mv failed → another process claimed it first, try next
@@ -106,8 +99,17 @@ if [ -z "$CLAIMED_FILE" ]; then
106
99
  exit 0
107
100
  fi
108
101
 
109
- # Fallback: use agent_type + short ID if no name was captured
110
- SESSION_NAME="${AGENT_NAME:-${AGENT_TYPE:-worker}-${AGENT_ID:0:8}}"
102
+ # Session name comes from this event's own agent_type (the same value the Task
103
+ # call passed as subagent_type). Falls back to an agent-id-derived name only when
104
+ # agent_type is empty — never a placeholder like "unknown-<digits>".
105
+ SESSION_NAME="${AGENT_TYPE:-worker-${AGENT_ID:0:8}}"
106
+
107
+ # Sanitized form for on-disk filenames only. Namespaced types such as
108
+ # chorus:code-reviewer are not skipped, so they reach this path and must not put
109
+ # a ":" or "/" into a path. The name sent to Chorus, the state keys and the
110
+ # injected workflow text all keep the raw agent_type.
111
+ SESSION_NAME_FILE=$(printf '%s' "$SESSION_NAME" | tr -c '[:alnum:]._-' '_')
112
+ [ -z "$SESSION_NAME_FILE" ] && SESSION_NAME_FILE="worker-${AGENT_ID:0:8}"
111
113
 
112
114
  # === Session reuse: list existing sessions, find by name ===
113
115
  SESSION_UUID=""
@@ -187,11 +189,24 @@ fi
187
189
  "$API" state-set "session_${SESSION_NAME}" "$SESSION_UUID"
188
190
  "$API" state-set "name_for_agent_${AGENT_ID}" "$SESSION_NAME"
189
191
 
192
+ # === Holder refcount: register this agent as a holder of the session NAME ===
193
+ # Because the name is the repeating agent_type, two parallel sub-agents of the
194
+ # same type converge on ONE session (reuse-by-name above). on-subagent-stop.sh
195
+ # removes its own entry here and only tears the shared session down when no other
196
+ # holder remains — otherwise the first sibling to exit would close the session,
197
+ # check the other sibling's task out and delete state its sibling still reads.
198
+ # Registered on every path (created / reused / reopened). The directory component
199
+ # uses the SAME sanitization as the sessions/<name>.json filename — a namespaced
200
+ # type such as chorus:code-reviewer must never put a ":" or "/" into a path.
201
+ HOLDERS_DIR="${CHORUS_STATE_DIR}/holders/${SESSION_NAME_FILE}"
202
+ mkdir -p "$HOLDERS_DIR" 2>/dev/null || true
203
+ : > "${HOLDERS_DIR}/${AGENT_ID}" 2>/dev/null || true
204
+
190
205
  # === Session file: minimal metadata for other hooks (TeammateIdle, SubagentStop) ===
191
206
  SESSIONS_DIR="${CHORUS_STATE_DIR}/sessions"
192
207
  mkdir -p "$SESSIONS_DIR" 2>/dev/null || true
193
208
 
194
- cat > "${SESSIONS_DIR}/${SESSION_NAME}.json" <<SESSIONEOF
209
+ cat > "${SESSIONS_DIR}/${SESSION_NAME_FILE}.json" <<SESSIONEOF
195
210
  {
196
211
  "sessionUuid": "${SESSION_UUID}",
197
212
  "agentId": "${AGENT_ID}",
@@ -4,6 +4,12 @@
4
4
  # Auto-checkout from all checked-in tasks, close the Chorus session,
5
5
  # clean up state files, and auto-verify if admin AC all passed.
6
6
  #
7
+ # Holder-aware: session names are the repeating agent_type, so parallel same-type
8
+ # sub-agents SHARE one session. Teardown (checkout / close / name-keyed state /
9
+ # sessions file / auto-verify) only happens for the LAST holder of the name — see
10
+ # the holder refcount block below. Non-last stops clean up only their own
11
+ # id-keyed state and leave the session running for their siblings.
12
+ #
7
13
  # NOTE: SubagentStop does NOT support additionalContext in Claude Code's
8
14
  # hookSpecificOutput schema, and systemMessage only reaches the UI —
9
15
  # not the main agent's LLM context. All agent-facing reminders must go
@@ -54,47 +60,104 @@ if [ -z "$SESSION_UUID" ]; then
54
60
  exit 0
55
61
  fi
56
62
 
57
- # === Auto-checkout from all checked-in tasks ===
63
+ # Sanitized form of the name for on-disk paths (same tr sanitization as
64
+ # on-subagent-start.sh uses for sessions/<name>.json and holders/<name>/) —
65
+ # namespaced types such as chorus:code-reviewer must not put a ":" into a path.
66
+ # The state keys keep the raw name.
67
+ AGENT_NAME_FILE=""
68
+ if [ -n "$AGENT_NAME" ]; then
69
+ AGENT_NAME_FILE=$(printf '%s' "$AGENT_NAME" | tr -c '[:alnum:]._-' '_')
70
+ fi
71
+
72
+ # === Holder refcount: is this the LAST agent holding the session name? ===
73
+ # Session names are the repeating agent_type, so two parallel sub-agents of the
74
+ # same type share ONE session (reuse-by-name in on-subagent-start.sh). Remove our
75
+ # OWN holder entry first, then count what remains: only the last holder may close
76
+ # the session, auto-checkout, auto-verify or delete the name-keyed state that
77
+ # siblings (and on-teammate-idle.sh) still read.
78
+ #
79
+ # Races are benign and must stay benign: if a sibling's start has not registered
80
+ # its holder yet we may see 0 holders and close the session; that sibling's start
81
+ # then finds a closed/inactive row and reopens it via the existing reopen path.
82
+ # Deliberately no locking.
83
+ #
84
+ # With no name in state we cannot refcount — fall back to the legacy
85
+ # single-agent behaviour (treat this stop as the last holder).
86
+ HOLDERS_DIR=""
87
+ HOLDERS_REMAINING=0
88
+ if [ -n "$AGENT_NAME_FILE" ]; then
89
+ HOLDERS_DIR="${CHORUS_STATE_DIR}/holders/${AGENT_NAME_FILE}"
90
+ rm -f "${HOLDERS_DIR}/${AGENT_ID}" 2>/dev/null || true
91
+ if [ -d "$HOLDERS_DIR" ]; then
92
+ HOLDERS_REMAINING=$(ls -1 "$HOLDERS_DIR" 2>/dev/null | grep -c . || true)
93
+ fi
94
+ fi
95
+ [ -n "$HOLDERS_REMAINING" ] || HOLDERS_REMAINING=0
96
+
97
+ IS_LAST_HOLDER=true
98
+ if [ "$HOLDERS_REMAINING" -gt 0 ]; then
99
+ IS_LAST_HOLDER=false
100
+ fi
101
+
102
+ # === Auto-checkout from all checked-in tasks (last holder only) ===
103
+ # Open checkins on a shared session may belong to a still-running sibling, so a
104
+ # non-last stop must not check them out — each sub-agent checks its own task out
105
+ # per the workflow injected by on-subagent-start.sh.
58
106
  CHECKOUT_COUNT=0
59
- SESSION_DETAIL=$("$API" mcp-tool "chorus_get_session" "$(printf '{"sessionUuid":"%s"}' "$SESSION_UUID")" 2>/dev/null) || true
107
+ SESSION_DETAIL=""
108
+ CLOSE_OK=true
60
109
 
61
- if [ -n "$SESSION_DETAIL" ]; then
62
- TASK_UUIDS=$(echo "$SESSION_DETAIL" | jq -r '
63
- .checkins[]? | select(.checkoutAt == null) | .taskUuid // empty
64
- ' 2>/dev/null) || true
110
+ if [ "$IS_LAST_HOLDER" = true ]; then
111
+ SESSION_DETAIL=$("$API" mcp-tool "chorus_get_session" "$(printf '{"sessionUuid":"%s"}' "$SESSION_UUID")" 2>/dev/null) || true
65
112
 
66
- if [ -z "$TASK_UUIDS" ]; then
113
+ if [ -n "$SESSION_DETAIL" ]; then
67
114
  TASK_UUIDS=$(echo "$SESSION_DETAIL" | jq -r '
68
- .sessionTaskCheckins[]? | select(.checkoutAt == null) | .taskUuid // empty
115
+ .checkins[]? | select(.checkoutAt == null) | .taskUuid // empty
69
116
  ' 2>/dev/null) || true
70
- fi
71
117
 
72
- for TASK_UUID in $TASK_UUIDS; do
73
- if [ -n "$TASK_UUID" ]; then
74
- "$API" mcp-tool "chorus_session_checkout_task" \
75
- "$(printf '{"sessionUuid":"%s","taskUuid":"%s"}' "$SESSION_UUID" "$TASK_UUID")" \
76
- >/dev/null 2>&1 || true
77
- CHECKOUT_COUNT=$((CHECKOUT_COUNT + 1))
118
+ if [ -z "$TASK_UUIDS" ]; then
119
+ TASK_UUIDS=$(echo "$SESSION_DETAIL" | jq -r '
120
+ .sessionTaskCheckins[]? | select(.checkoutAt == null) | .taskUuid // empty
121
+ ' 2>/dev/null) || true
78
122
  fi
79
- done
80
- fi
81
123
 
82
- # Close the Chorus session via MCP
83
- CLOSE_OK=true
84
- "$API" mcp-tool "chorus_close_session" "$(printf '{"sessionUuid":"%s"}' "$SESSION_UUID")" >/dev/null 2>&1 || CLOSE_OK=false
124
+ for TASK_UUID in $TASK_UUIDS; do
125
+ if [ -n "$TASK_UUID" ]; then
126
+ "$API" mcp-tool "chorus_session_checkout_task" \
127
+ "$(printf '{"sessionUuid":"%s","taskUuid":"%s"}' "$SESSION_UUID" "$TASK_UUID")" \
128
+ >/dev/null 2>&1 || true
129
+ CHECKOUT_COUNT=$((CHECKOUT_COUNT + 1))
130
+ fi
131
+ done
132
+ fi
85
133
 
86
- # Clean up state
134
+ # Close the Chorus session via MCP
135
+ "$API" mcp-tool "chorus_close_session" "$(printf '{"sessionUuid":"%s"}' "$SESSION_UUID")" >/dev/null 2>&1 || CLOSE_OK=false
136
+ fi
137
+
138
+ # Clean up state.
139
+ # The id-keyed keys are this agent's own and always go. The name-keyed mapping and
140
+ # the reverse map agent_for_session_<uuid> (single-valued — siblings overwrite it)
141
+ # are shared, so they only go on the last-holder path.
87
142
  "$API" state-delete "session_${AGENT_ID}" 2>/dev/null || true
88
- "$API" state-delete "agent_for_session_${SESSION_UUID}" 2>/dev/null || true
89
143
  "$API" state-delete "name_for_agent_${AGENT_ID}" 2>/dev/null || true
90
- if [ -n "$AGENT_NAME" ]; then
91
- "$API" state-delete "session_${AGENT_NAME}" 2>/dev/null || true
144
+ if [ "$IS_LAST_HOLDER" = true ]; then
145
+ "$API" state-delete "agent_for_session_${SESSION_UUID}" 2>/dev/null || true
146
+ if [ -n "$AGENT_NAME" ]; then
147
+ "$API" state-delete "session_${AGENT_NAME}" 2>/dev/null || true
148
+ fi
92
149
  fi
93
150
 
94
- # Clean up session file
151
+ # Clean up session file + holder dir (last holder only — siblings still read
152
+ # sessions/<name>.json, see on-teammate-idle.sh).
95
153
  SESSIONS_DIR="${CHORUS_STATE_DIR}/sessions"
96
- if [ -n "$AGENT_NAME" ] && [ -f "${SESSIONS_DIR}/${AGENT_NAME}.json" ]; then
97
- rm -f "${SESSIONS_DIR}/${AGENT_NAME}.json"
154
+ if [ "$IS_LAST_HOLDER" = true ]; then
155
+ if [ -n "$AGENT_NAME_FILE" ] && [ -f "${SESSIONS_DIR}/${AGENT_NAME_FILE}.json" ]; then
156
+ rm -f "${SESSIONS_DIR}/${AGENT_NAME_FILE}.json"
157
+ fi
158
+ if [ -n "$HOLDERS_DIR" ] && [ -d "$HOLDERS_DIR" ]; then
159
+ rmdir "$HOLDERS_DIR" 2>/dev/null || true
160
+ fi
98
161
  fi
99
162
 
100
163
  # Clean up claimed file (written by SubagentStart)
@@ -104,7 +167,9 @@ if [ -n "$AGENT_ID" ] && [ -f "${CLAIMED_DIR}/${AGENT_ID}" ]; then
104
167
  fi
105
168
 
106
169
  # === Auto-verify: if admin marked all AC, verify the task automatically ===
107
- if [ "$CLOSE_OK" = true ] && [ -n "$SESSION_DETAIL" ]; then
170
+ # Last holder only: on a shared session the first checkin may belong to a sibling,
171
+ # so a non-last stop must never auto-verify another agent's task.
172
+ if [ "$IS_LAST_HOLDER" = true ] && [ "$CLOSE_OK" = true ] && [ -n "$SESSION_DETAIL" ]; then
108
173
  FIRST_TASK_UUID=$(echo "$SESSION_DETAIL" | jq -r '
109
174
  (.checkins // .sessionTaskCheckins // [])[] | .taskUuid // empty
110
175
  ' 2>/dev/null | head -1) || true
@@ -144,7 +209,13 @@ fi
144
209
 
145
210
  # === Output (UI-only, not visible to main agent LLM) ===
146
211
  DISPLAY_NAME="${AGENT_NAME:-${AGENT_ID:0:8}}"
147
- if [ "$CLOSE_OK" = true ]; then
212
+ if [ "$IS_LAST_HOLDER" != true ]; then
213
+ # Shared session still has live holders — do not claim it was closed.
214
+ "$API" hook-output \
215
+ "Chorus session '${DISPLAY_NAME}' kept open (${HOLDERS_REMAINING} other agent(s) still using it)" \
216
+ "" \
217
+ "SubagentStop"
218
+ elif [ "$CLOSE_OK" = true ]; then
148
219
  USER_MSG="Chorus session closed: '${DISPLAY_NAME}'"
149
220
  if [ "$CHECKOUT_COUNT" -gt 0 ]; then
150
221
  USER_MSG="${USER_MSG} (auto-checkout ${CHECKOUT_COUNT} task(s))"
@@ -140,8 +140,12 @@ assert_eq "no session id -> <slug>/no-session" \
140
140
  # the global root, and does NOT create a .chorus/ in the project dir.
141
141
  printf '%s' '{"session_id":"sess-place","tool_input":{"subagent_type":"general-purpose","name":"placer"}}' \
142
142
  | "$BASH" "$DIR/on-pre-spawn-agent.sh" >/dev/null 2>&1 || true
143
- assert_true "pending file written under global root" \
144
- test -f "${CHORUS_PLUGIN_STATE_ROOT}/${EXPECT_SLUG}/sess-place/pending/placer"
143
+ # The pending filename is <sanitized subagent_type>__<epoch>-<pid>, never unknown-*.
144
+ PENDING_PLACED="$( ls "${CHORUS_PLUGIN_STATE_ROOT}/${EXPECT_SLUG}/sess-place/pending" 2>/dev/null | head -1 )"
145
+ case "$PENDING_PLACED" in
146
+ general-purpose__*) assert_true "pending file written under global root" true ;;
147
+ *) assert_true "pending file written under global root" false ;;
148
+ esac
145
149
  assert_true "no .chorus/ created in project dir" \
146
150
  test ! -d "${CLAUDE_PROJECT_DIR}/.chorus"
147
151