@chorus-aidlc/chorus 0.17.2 → 0.18.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 (446) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-build-manifest.json +357 -355
  3. package/.next/standalone/.next/app-path-routes-manifest.json +44 -44
  4. package/.next/standalone/.next/build-manifest.json +5 -5
  5. package/.next/standalone/.next/prerender-manifest.json +18 -18
  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 +2 -2
  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.js.nft.json +1 -1
  66. package/.next/standalone/.next/server/app/api/agent-connections/route_client-reference-manifest.js +1 -1
  67. package/.next/standalone/.next/server/app/api/agents/[uuid]/route_client-reference-manifest.js +1 -1
  68. package/.next/standalone/.next/server/app/api/agents/[uuid]/sessions/route.js +1 -1
  69. package/.next/standalone/.next/server/app/api/agents/[uuid]/sessions/route.js.nft.json +1 -1
  70. package/.next/standalone/.next/server/app/api/agents/[uuid]/sessions/route_client-reference-manifest.js +1 -1
  71. package/.next/standalone/.next/server/app/api/agents/route_client-reference-manifest.js +1 -1
  72. package/.next/standalone/.next/server/app/api/api-keys/[uuid]/route_client-reference-manifest.js +1 -1
  73. package/.next/standalone/.next/server/app/api/api-keys/route_client-reference-manifest.js +1 -1
  74. package/.next/standalone/.next/server/app/api/auth/callback/route_client-reference-manifest.js +1 -1
  75. package/.next/standalone/.next/server/app/api/auth/check-default/route_client-reference-manifest.js +1 -1
  76. package/.next/standalone/.next/server/app/api/auth/company-oidc/route_client-reference-manifest.js +1 -1
  77. package/.next/standalone/.next/server/app/api/auth/default-login/route_client-reference-manifest.js +1 -1
  78. package/.next/standalone/.next/server/app/api/auth/identify/route_client-reference-manifest.js +1 -1
  79. package/.next/standalone/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  80. package/.next/standalone/.next/server/app/api/auth/me/route_client-reference-manifest.js +1 -1
  81. package/.next/standalone/.next/server/app/api/auth/sync-token/route_client-reference-manifest.js +1 -1
  82. package/.next/standalone/.next/server/app/api/comments/route.js +1 -1
  83. package/.next/standalone/.next/server/app/api/comments/route.js.nft.json +1 -1
  84. package/.next/standalone/.next/server/app/api/comments/route_client-reference-manifest.js +1 -1
  85. package/.next/standalone/.next/server/app/api/daemon/connection-heartbeat/route.js.nft.json +1 -1
  86. package/.next/standalone/.next/server/app/api/daemon/connection-heartbeat/route_client-reference-manifest.js +1 -1
  87. package/.next/standalone/.next/server/app/api/daemon/control/route_client-reference-manifest.js +1 -1
  88. package/.next/standalone/.next/server/app/api/daemon/directory-request/report/route.js.nft.json +1 -1
  89. package/.next/standalone/.next/server/app/api/daemon/directory-request/report/route_client-reference-manifest.js +1 -1
  90. package/.next/standalone/.next/server/app/api/daemon/execution-state/route.js.nft.json +1 -1
  91. package/.next/standalone/.next/server/app/api/daemon/execution-state/route_client-reference-manifest.js +1 -1
  92. package/.next/standalone/.next/server/app/api/daemon/executions/route.js.nft.json +1 -1
  93. package/.next/standalone/.next/server/app/api/daemon/executions/route_client-reference-manifest.js +1 -1
  94. package/.next/standalone/.next/server/app/api/daemon/pending-turns/route.js +1 -1
  95. package/.next/standalone/.next/server/app/api/daemon/pending-turns/route.js.nft.json +1 -1
  96. package/.next/standalone/.next/server/app/api/daemon/pending-turns/route_client-reference-manifest.js +1 -1
  97. package/.next/standalone/.next/server/app/api/daemon/report-interrupt/route.js.nft.json +1 -1
  98. package/.next/standalone/.next/server/app/api/daemon/report-interrupt/route_client-reference-manifest.js +1 -1
  99. package/.next/standalone/.next/server/app/api/daemon/resume/route.js +1 -1
  100. package/.next/standalone/.next/server/app/api/daemon/resume/route.js.nft.json +1 -1
  101. package/.next/standalone/.next/server/app/api/daemon/resume/route_client-reference-manifest.js +1 -1
  102. package/.next/standalone/.next/server/app/api/daemon/transcript/route.js +1 -1
  103. package/.next/standalone/.next/server/app/api/daemon/transcript/route.js.nft.json +1 -1
  104. package/.next/standalone/.next/server/app/api/daemon/transcript/route_client-reference-manifest.js +1 -1
  105. package/.next/standalone/.next/server/app/api/daemon/turn-advance/route.js +1 -1
  106. package/.next/standalone/.next/server/app/api/daemon/turn-advance/route.js.nft.json +1 -1
  107. package/.next/standalone/.next/server/app/api/daemon/turn-advance/route_client-reference-manifest.js +1 -1
  108. package/.next/standalone/.next/server/app/api/daemon-directory-requests/[uuid]/route.js.nft.json +1 -1
  109. package/.next/standalone/.next/server/app/api/daemon-directory-requests/[uuid]/route_client-reference-manifest.js +1 -1
  110. package/.next/standalone/.next/server/app/api/daemon-directory-requests/route.js.nft.json +1 -1
  111. package/.next/standalone/.next/server/app/api/daemon-directory-requests/route_client-reference-manifest.js +1 -1
  112. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route.js +1 -1
  113. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route.js.nft.json +1 -1
  114. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/instruction/route_client-reference-manifest.js +1 -1
  115. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route.js +1 -1
  116. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route.js.nft.json +1 -1
  117. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/repoint/route_client-reference-manifest.js +1 -1
  118. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route.js +1 -1
  119. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route.js.nft.json +1 -1
  120. package/.next/standalone/.next/server/app/api/daemon-sessions/[sessionUuid]/route_client-reference-manifest.js +1 -1
  121. package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route.js +1 -1
  122. package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route.js.nft.json +1 -1
  123. package/.next/standalone/.next/server/app/api/daemon-sessions/ad-hoc/route_client-reference-manifest.js +1 -1
  124. package/.next/standalone/.next/server/app/api/daemon-sessions/route.js +1 -1
  125. package/.next/standalone/.next/server/app/api/daemon-sessions/route.js.nft.json +1 -1
  126. package/.next/standalone/.next/server/app/api/daemon-sessions/route_client-reference-manifest.js +1 -1
  127. package/.next/standalone/.next/server/app/api/documents/[uuid]/route_client-reference-manifest.js +1 -1
  128. package/.next/standalone/.next/server/app/api/entities/[type]/[uuid]/root-idea/route.js +1 -1
  129. package/.next/standalone/.next/server/app/api/entities/[type]/[uuid]/root-idea/route.js.nft.json +1 -1
  130. package/.next/standalone/.next/server/app/api/entities/[type]/[uuid]/root-idea/route_client-reference-manifest.js +1 -1
  131. package/.next/standalone/.next/server/app/api/events/notifications/route.js +1 -1
  132. package/.next/standalone/.next/server/app/api/events/notifications/route.js.nft.json +1 -1
  133. package/.next/standalone/.next/server/app/api/events/notifications/route_client-reference-manifest.js +1 -1
  134. package/.next/standalone/.next/server/app/api/events/route.js +1 -1
  135. package/.next/standalone/.next/server/app/api/events/route.js.nft.json +1 -1
  136. package/.next/standalone/.next/server/app/api/events/route_client-reference-manifest.js +1 -1
  137. package/.next/standalone/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
  138. package/.next/standalone/.next/server/app/api/ideas/[uuid]/claim/route.js +1 -1
  139. package/.next/standalone/.next/server/app/api/ideas/[uuid]/claim/route.js.nft.json +1 -1
  140. package/.next/standalone/.next/server/app/api/ideas/[uuid]/claim/route_client-reference-manifest.js +1 -1
  141. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/preview/route.js +1 -1
  142. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/preview/route.js.nft.json +1 -1
  143. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/preview/route_client-reference-manifest.js +1 -1
  144. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/route.js +1 -1
  145. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/route.js.nft.json +1 -1
  146. package/.next/standalone/.next/server/app/api/ideas/[uuid]/move/route_client-reference-manifest.js +1 -1
  147. package/.next/standalone/.next/server/app/api/ideas/[uuid]/parent/route.js +1 -1
  148. package/.next/standalone/.next/server/app/api/ideas/[uuid]/parent/route.js.nft.json +1 -1
  149. package/.next/standalone/.next/server/app/api/ideas/[uuid]/parent/route_client-reference-manifest.js +1 -1
  150. package/.next/standalone/.next/server/app/api/ideas/[uuid]/release/route.js +1 -1
  151. package/.next/standalone/.next/server/app/api/ideas/[uuid]/release/route.js.nft.json +1 -1
  152. package/.next/standalone/.next/server/app/api/ideas/[uuid]/release/route_client-reference-manifest.js +1 -1
  153. package/.next/standalone/.next/server/app/api/ideas/[uuid]/route.js +1 -1
  154. package/.next/standalone/.next/server/app/api/ideas/[uuid]/route.js.nft.json +1 -1
  155. package/.next/standalone/.next/server/app/api/ideas/[uuid]/route_client-reference-manifest.js +1 -1
  156. package/.next/standalone/.next/server/app/api/ideas/[uuid]/wake-preview/route.js.nft.json +1 -1
  157. package/.next/standalone/.next/server/app/api/ideas/[uuid]/wake-preview/route_client-reference-manifest.js +1 -1
  158. package/.next/standalone/.next/server/app/api/ideas/conversational/route.js +1 -1
  159. package/.next/standalone/.next/server/app/api/ideas/conversational/route.js.nft.json +1 -1
  160. package/.next/standalone/.next/server/app/api/ideas/conversational/route_client-reference-manifest.js +1 -1
  161. package/.next/standalone/.next/server/app/api/mcp/route.js +1 -1
  162. package/.next/standalone/.next/server/app/api/mcp/route.js.nft.json +1 -1
  163. package/.next/standalone/.next/server/app/api/mcp/route_client-reference-manifest.js +1 -1
  164. package/.next/standalone/.next/server/app/api/me/assignments/route.js +1 -1
  165. package/.next/standalone/.next/server/app/api/me/assignments/route.js.nft.json +1 -1
  166. package/.next/standalone/.next/server/app/api/me/assignments/route_client-reference-manifest.js +1 -1
  167. package/.next/standalone/.next/server/app/api/mentionables/route.js +1 -1
  168. package/.next/standalone/.next/server/app/api/mentionables/route.js.nft.json +1 -1
  169. package/.next/standalone/.next/server/app/api/mentionables/route_client-reference-manifest.js +1 -1
  170. package/.next/standalone/.next/server/app/api/notifications/[uuid]/archive/route.js +1 -1
  171. package/.next/standalone/.next/server/app/api/notifications/[uuid]/archive/route.js.nft.json +1 -1
  172. package/.next/standalone/.next/server/app/api/notifications/[uuid]/archive/route_client-reference-manifest.js +1 -1
  173. package/.next/standalone/.next/server/app/api/notifications/[uuid]/read/route.js +1 -1
  174. package/.next/standalone/.next/server/app/api/notifications/[uuid]/read/route.js.nft.json +1 -1
  175. package/.next/standalone/.next/server/app/api/notifications/[uuid]/read/route_client-reference-manifest.js +1 -1
  176. package/.next/standalone/.next/server/app/api/notifications/preferences/route.js +1 -1
  177. package/.next/standalone/.next/server/app/api/notifications/preferences/route.js.nft.json +1 -1
  178. package/.next/standalone/.next/server/app/api/notifications/preferences/route_client-reference-manifest.js +1 -1
  179. package/.next/standalone/.next/server/app/api/notifications/read-all/route.js +1 -1
  180. package/.next/standalone/.next/server/app/api/notifications/read-all/route.js.nft.json +1 -1
  181. package/.next/standalone/.next/server/app/api/notifications/read-all/route_client-reference-manifest.js +1 -1
  182. package/.next/standalone/.next/server/app/api/notifications/route.js +1 -1
  183. package/.next/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  184. package/.next/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  185. package/.next/standalone/.next/server/app/api/notifications/unread-count/route.js +1 -1
  186. package/.next/standalone/.next/server/app/api/notifications/unread-count/route.js.nft.json +1 -1
  187. package/.next/standalone/.next/server/app/api/notifications/unread-count/route_client-reference-manifest.js +1 -1
  188. package/.next/standalone/.next/server/app/api/project-groups/[uuid]/dashboard/route_client-reference-manifest.js +1 -1
  189. package/.next/standalone/.next/server/app/api/project-groups/[uuid]/route_client-reference-manifest.js +1 -1
  190. package/.next/standalone/.next/server/app/api/project-groups/route_client-reference-manifest.js +1 -1
  191. package/.next/standalone/.next/server/app/api/project-visits/pin/route_client-reference-manifest.js +1 -1
  192. package/.next/standalone/.next/server/app/api/project-visits/route_client-reference-manifest.js +1 -1
  193. package/.next/standalone/.next/server/app/api/project-visits/visit/route_client-reference-manifest.js +1 -1
  194. package/.next/standalone/.next/server/app/api/projects/[uuid]/activity/route_client-reference-manifest.js +1 -1
  195. package/.next/standalone/.next/server/app/api/projects/[uuid]/agent-cwds/route.js.nft.json +1 -1
  196. package/.next/standalone/.next/server/app/api/projects/[uuid]/agent-cwds/route_client-reference-manifest.js +1 -1
  197. package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route.js +1 -1
  198. package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route.js.nft.json +1 -1
  199. package/.next/standalone/.next/server/app/api/projects/[uuid]/available/route_client-reference-manifest.js +1 -1
  200. package/.next/standalone/.next/server/app/api/projects/[uuid]/documents/route_client-reference-manifest.js +1 -1
  201. package/.next/standalone/.next/server/app/api/projects/[uuid]/group/route_client-reference-manifest.js +1 -1
  202. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route.js +1 -1
  203. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route.js.nft.json +1 -1
  204. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/route_client-reference-manifest.js +1 -1
  205. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route.js +1 -1
  206. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route.js.nft.json +1 -1
  207. package/.next/standalone/.next/server/app/api/projects/[uuid]/ideas/tracker/route_client-reference-manifest.js +1 -1
  208. package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/[proposalUuid]/validate/route_client-reference-manifest.js +1 -1
  209. package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/route_client-reference-manifest.js +1 -1
  210. package/.next/standalone/.next/server/app/api/projects/[uuid]/proposals/summary/route_client-reference-manifest.js +1 -1
  211. package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route.js +1 -1
  212. package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route.js.nft.json +1 -1
  213. package/.next/standalone/.next/server/app/api/projects/[uuid]/resource-graph/route_client-reference-manifest.js +1 -1
  214. package/.next/standalone/.next/server/app/api/projects/[uuid]/route_client-reference-manifest.js +1 -1
  215. package/.next/standalone/.next/server/app/api/projects/[uuid]/stats/route_client-reference-manifest.js +1 -1
  216. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/dependencies/route.js +1 -1
  217. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/dependencies/route.js.nft.json +1 -1
  218. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/dependencies/route_client-reference-manifest.js +1 -1
  219. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/route.js +1 -1
  220. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/route.js.nft.json +1 -1
  221. package/.next/standalone/.next/server/app/api/projects/[uuid]/tasks/route_client-reference-manifest.js +1 -1
  222. package/.next/standalone/.next/server/app/api/projects/agent-cwd-options/route.js.nft.json +1 -1
  223. package/.next/standalone/.next/server/app/api/projects/agent-cwd-options/route_client-reference-manifest.js +1 -1
  224. package/.next/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  225. package/.next/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  226. package/.next/standalone/.next/server/app/api/proposals/[uuid]/approve/route_client-reference-manifest.js +1 -1
  227. package/.next/standalone/.next/server/app/api/proposals/[uuid]/close/route_client-reference-manifest.js +1 -1
  228. package/.next/standalone/.next/server/app/api/proposals/[uuid]/reject/route_client-reference-manifest.js +1 -1
  229. package/.next/standalone/.next/server/app/api/proposals/[uuid]/revoke/route_client-reference-manifest.js +1 -1
  230. package/.next/standalone/.next/server/app/api/proposals/[uuid]/route_client-reference-manifest.js +1 -1
  231. package/.next/standalone/.next/server/app/api/references/[uuid]/route_client-reference-manifest.js +1 -1
  232. package/.next/standalone/.next/server/app/api/references/route_client-reference-manifest.js +1 -1
  233. package/.next/standalone/.next/server/app/api/search/route_client-reference-manifest.js +1 -1
  234. package/.next/standalone/.next/server/app/api/session/route_client-reference-manifest.js +1 -1
  235. package/.next/standalone/.next/server/app/api/sessions/[uuid]/route.js +1 -1
  236. package/.next/standalone/.next/server/app/api/sessions/[uuid]/route.js.nft.json +1 -1
  237. package/.next/standalone/.next/server/app/api/sessions/[uuid]/route_client-reference-manifest.js +1 -1
  238. package/.next/standalone/.next/server/app/api/tasks/[uuid]/claim/route.js +1 -1
  239. package/.next/standalone/.next/server/app/api/tasks/[uuid]/claim/route.js.nft.json +1 -1
  240. package/.next/standalone/.next/server/app/api/tasks/[uuid]/claim/route_client-reference-manifest.js +1 -1
  241. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route.js +1 -1
  242. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route.js.nft.json +1 -1
  243. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/[dependsOnUuid]/route_client-reference-manifest.js +1 -1
  244. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/route.js +1 -1
  245. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/route.js.nft.json +1 -1
  246. package/.next/standalone/.next/server/app/api/tasks/[uuid]/dependencies/route_client-reference-manifest.js +1 -1
  247. package/.next/standalone/.next/server/app/api/tasks/[uuid]/release/route.js +1 -1
  248. package/.next/standalone/.next/server/app/api/tasks/[uuid]/release/route.js.nft.json +1 -1
  249. package/.next/standalone/.next/server/app/api/tasks/[uuid]/release/route_client-reference-manifest.js +1 -1
  250. package/.next/standalone/.next/server/app/api/tasks/[uuid]/route.js +1 -1
  251. package/.next/standalone/.next/server/app/api/tasks/[uuid]/route.js.nft.json +1 -1
  252. package/.next/standalone/.next/server/app/api/tasks/[uuid]/route_client-reference-manifest.js +1 -1
  253. package/.next/standalone/.next/server/app/api/tasks/[uuid]/sessions/route.js +1 -1
  254. package/.next/standalone/.next/server/app/api/tasks/[uuid]/sessions/route.js.nft.json +1 -1
  255. package/.next/standalone/.next/server/app/api/tasks/[uuid]/sessions/route_client-reference-manifest.js +1 -1
  256. package/.next/standalone/.next/server/app/index.html +2 -2
  257. package/.next/standalone/.next/server/app/index.rsc +2 -2
  258. package/.next/standalone/.next/server/app/login/admin/page_client-reference-manifest.js +1 -1
  259. package/.next/standalone/.next/server/app/login/admin.html +2 -2
  260. package/.next/standalone/.next/server/app/login/admin.rsc +2 -2
  261. package/.next/standalone/.next/server/app/login/callback/page_client-reference-manifest.js +1 -1
  262. package/.next/standalone/.next/server/app/login/callback.html +2 -2
  263. package/.next/standalone/.next/server/app/login/callback.rsc +2 -2
  264. package/.next/standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  265. package/.next/standalone/.next/server/app/login/pick-workspace/page_client-reference-manifest.js +1 -1
  266. package/.next/standalone/.next/server/app/login/pick-workspace.html +2 -2
  267. package/.next/standalone/.next/server/app/login/pick-workspace.rsc +2 -2
  268. package/.next/standalone/.next/server/app/login.html +2 -2
  269. package/.next/standalone/.next/server/app/login.rsc +2 -2
  270. package/.next/standalone/.next/server/app/onboarding/page.js +2 -2
  271. package/.next/standalone/.next/server/app/onboarding/page.js.nft.json +1 -1
  272. package/.next/standalone/.next/server/app/onboarding/page_client-reference-manifest.js +1 -1
  273. package/.next/standalone/.next/server/app/onboarding.html +2 -2
  274. package/.next/standalone/.next/server/app/onboarding.rsc +3 -3
  275. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  276. package/.next/standalone/.next/server/app/projects.html +2 -2
  277. package/.next/standalone/.next/server/app/projects.rsc +3 -3
  278. package/.next/standalone/.next/server/app/settings.html +2 -2
  279. package/.next/standalone/.next/server/app/settings.rsc +4 -4
  280. package/.next/standalone/.next/server/app-paths-manifest.json +44 -44
  281. package/.next/standalone/.next/server/chunks/109.js +1 -0
  282. package/.next/standalone/.next/server/chunks/1318.js +1 -1
  283. package/.next/standalone/.next/server/chunks/1496.js +1 -0
  284. package/.next/standalone/.next/server/chunks/1559.js +2 -2
  285. package/.next/standalone/.next/server/chunks/2572.js +1 -1
  286. package/.next/standalone/.next/server/chunks/2961.js +1 -1
  287. package/.next/standalone/.next/server/chunks/3112.js +1 -1
  288. package/.next/standalone/.next/server/chunks/{2536.js → 3619.js} +3 -3
  289. package/.next/standalone/.next/server/chunks/{6080.js → 4810.js} +1 -1
  290. package/.next/standalone/.next/server/chunks/4827.js +1 -1
  291. package/.next/standalone/.next/server/chunks/5245.js +1 -1
  292. package/.next/standalone/.next/server/chunks/6113.js +1 -1
  293. package/.next/standalone/.next/server/chunks/6506.js +2 -2
  294. package/.next/standalone/.next/server/chunks/6515.js +2 -2
  295. package/.next/standalone/.next/server/chunks/6737.js +1 -0
  296. package/.next/standalone/.next/server/chunks/6753.js +3 -3
  297. package/.next/standalone/.next/server/chunks/679.js +1 -1
  298. package/.next/standalone/.next/server/chunks/731.js +1 -0
  299. package/.next/standalone/.next/server/chunks/7368.js +1 -1
  300. package/.next/standalone/.next/server/chunks/7530.js +1 -1
  301. package/.next/standalone/.next/server/chunks/7857.js +1 -0
  302. package/.next/standalone/.next/server/chunks/920.js +1 -1
  303. package/.next/standalone/.next/server/chunks/9213.js +1 -1
  304. package/.next/standalone/.next/server/chunks/9378.js +1 -1
  305. package/.next/standalone/.next/server/chunks/9931.js +1 -1
  306. package/.next/standalone/.next/server/middleware-build-manifest.js +1 -1
  307. package/.next/standalone/.next/server/middleware-manifest.json +5 -5
  308. package/.next/standalone/.next/server/pages/404.html +2 -2
  309. package/.next/standalone/.next/server/pages/500.html +1 -1
  310. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  311. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  312. package/.next/standalone/.next/static/chunks/11595.0afa1a540f681fb4.js +1 -0
  313. package/.next/standalone/.next/static/chunks/22705-324a191727ae45b7.js +1 -0
  314. package/.next/standalone/.next/static/chunks/{31308-32614efb88305738.js → 31308-bb4a97b3f39c22dd.js} +1 -1
  315. package/.next/standalone/.next/static/chunks/33456.4a5f4712a7e78d8f.js +1 -0
  316. package/.next/standalone/.next/static/chunks/44216-3876e84f5b02d355.js +1 -0
  317. package/.next/standalone/.next/static/chunks/4860.5719e32b95be2d93.js +1 -0
  318. package/.next/standalone/.next/static/chunks/6528-a8a562ef7d26bb43.js +1 -0
  319. package/.next/standalone/.next/static/chunks/67439-7b339b28ed0ecfc6.js +1 -0
  320. package/.next/standalone/.next/static/chunks/79919-ae8bd8d8ec1e38ce.js +1 -0
  321. package/.next/standalone/.next/static/chunks/82203-4ce5926624df7ed0.js +1 -0
  322. package/.next/standalone/.next/static/chunks/94643-37ac7b8ef8ea5e75.js +1 -0
  323. package/.next/standalone/.next/static/chunks/99373.6c1509bfaf599741.js +1 -0
  324. package/.next/standalone/.next/static/chunks/99775-697e82ee04eac6b1.js +1 -0
  325. package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-2fda722cdace8147.js +1 -0
  326. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/dashboard/{page-eecb38fa4b8eb4e8.js → page-b45c42c536eff64b.js} +1 -1
  327. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-792aba7fd6b6daa3.js +1 -0
  328. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/{page-cd7ec77596304a07.js → page-800a979f12b73f27.js} +1 -1
  329. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/graph/{page-97a9e6f949002004.js → page-34de35f75aa71f6d.js} +1 -1
  330. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-a16002aa2a911619.js +1 -0
  331. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/new/{page-cec15f4b835d34fc.js → page-e8030824994edf35.js} +1 -1
  332. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-4f7f1ddbaf79be8f.js +1 -0
  333. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/[taskUuid]/{page-4ee117e690fda56f.js → page-349b0977f3c6209a.js} +1 -1
  334. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/tasks/{page-7fbc46dfb7b22bd3.js → page-be43cb06112fce12.js} +1 -1
  335. package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-6916e1abab42a6e6.js +1 -0
  336. package/.next/standalone/.next/static/chunks/app/onboarding/{page-4fce966dc96d4ff1.js → page-c0090caae202eae5.js} +1 -1
  337. package/.next/standalone/.next/static/chunks/{webpack-1bfc783412a06fc5.js → webpack-cfb63dd1b416c92e.js} +1 -1
  338. package/.next/standalone/.next/static/css/75c761a5428611fa.css +1 -0
  339. package/.next/standalone/package.json +1 -1
  340. package/.next/standalone/public/chorus-plugin/.claude-plugin/plugin.json +2 -2
  341. package/.next/standalone/public/chorus-plugin/agents/code-reviewer.md +1 -0
  342. package/.next/standalone/public/chorus-plugin/agents/proposal-reviewer.md +12 -3
  343. package/.next/standalone/public/chorus-plugin/agents/task-reviewer.md +4 -0
  344. package/.next/standalone/public/chorus-plugin/bin/chorus-api.sh +1 -1
  345. package/.next/standalone/public/chorus-plugin/bin/on-post-submit-for-verify.sh +3 -3
  346. package/.next/standalone/public/chorus-plugin/bin/on-post-submit-proposal.sh +3 -3
  347. package/.next/standalone/public/chorus-plugin/bin/on-post-verify-task.sh +2 -2
  348. package/.next/standalone/public/chorus-plugin/bin/on-session-start.sh +39 -64
  349. package/.next/standalone/public/chorus-plugin/bin/resolve-spec-mode.sh +107 -0
  350. package/.next/standalone/public/chorus-plugin/bin/tests/test-resolver-drift.sh +46 -0
  351. package/.next/standalone/public/chorus-plugin/bin/tests/test-skill-harness-fidelity-negative.sh +328 -0
  352. package/.next/standalone/public/chorus-plugin/bin/tests/test-skill-harness-fidelity.sh +372 -0
  353. package/.next/standalone/public/chorus-plugin/bin/tests/test-spec-mode-resolution.sh +83 -0
  354. package/.next/standalone/public/chorus-plugin/skills/brainstorm/SKILL.md +1 -1
  355. package/.next/standalone/public/chorus-plugin/skills/chorus/SKILL.md +11 -6
  356. package/.next/standalone/public/chorus-plugin/skills/chorus-cli/SKILL.md +1 -1
  357. package/.next/standalone/public/chorus-plugin/skills/develop/SKILL.md +14 -9
  358. package/.next/standalone/public/chorus-plugin/skills/docs/SKILL.md +1 -1
  359. package/.next/standalone/public/chorus-plugin/skills/idea/SKILL.md +1 -1
  360. package/.next/standalone/public/chorus-plugin/skills/openspec-aware/SKILL.md +27 -31
  361. package/.next/standalone/public/chorus-plugin/skills/orchestrate/SKILL.md +11 -1
  362. package/.next/standalone/public/chorus-plugin/skills/proposal/SKILL.md +14 -7
  363. package/.next/standalone/public/chorus-plugin/skills/quick-dev/SKILL.md +6 -4
  364. package/.next/standalone/public/chorus-plugin/skills/review/SKILL.md +10 -8
  365. package/.next/standalone/public/chorus-plugin/skills/spec-lite/SKILL.md +147 -0
  366. package/.next/standalone/public/chorus-plugin/skills/yolo/SKILL.md +49 -34
  367. package/.next/standalone/public/kiro-plugin/.kiro/agents/chorus-code-reviewer.json +1 -1
  368. package/.next/standalone/public/kiro-plugin/.kiro/agents/chorus-proposal-reviewer.json +2 -1
  369. package/.next/standalone/public/kiro-plugin/.kiro/agents/chorus-task-reviewer.json +1 -1
  370. package/.next/standalone/public/kiro-plugin/.kiro/agents/chorus.md +1 -1
  371. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-brainstorm/SKILL.md +1 -1
  372. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-cli/SKILL.md +1 -1
  373. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-develop/SKILL.md +9 -7
  374. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-docs/SKILL.md +1 -1
  375. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-idea/SKILL.md +1 -1
  376. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-openspec-aware/SKILL.md +35 -27
  377. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-orchestrate/SKILL.md +9 -1
  378. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-proposal/SKILL.md +14 -7
  379. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-quick-dev/SKILL.md +2 -2
  380. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-review/SKILL.md +8 -8
  381. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-spec-lite/SKILL.md +147 -0
  382. package/.next/standalone/public/kiro-plugin/.kiro/skills/chorus-yolo/SKILL.md +39 -25
  383. package/.next/standalone/public/kiro-plugin/.kiro/steering/chorus.md +11 -6
  384. package/.next/standalone/public/kiro-plugin/bin/chorus-api.sh +1 -1
  385. package/.next/standalone/public/kiro-plugin/bin/on-agent-spawn.sh +41 -0
  386. package/.next/standalone/public/kiro-plugin/bin/on-post-submit-for-verify.sh +3 -3
  387. package/.next/standalone/public/kiro-plugin/bin/on-post-submit-proposal.sh +3 -3
  388. package/.next/standalone/public/kiro-plugin/bin/on-post-verify-task.sh +2 -2
  389. package/.next/standalone/public/kiro-plugin/bin/resolve-spec-mode.sh +107 -0
  390. package/.next/standalone/public/kiro-plugin/manifest.txt +2 -0
  391. package/.next/standalone/public/skill/chorus/SKILL.md +11 -1
  392. package/.next/standalone/public/skill/code-reviewer-chorus/SKILL.md +1 -0
  393. package/.next/standalone/public/skill/develop-chorus/SKILL.md +1 -1
  394. package/.next/standalone/public/skill/orchestrate-chorus/SKILL.md +11 -1
  395. package/.next/standalone/public/skill/proposal-reviewer-chorus/SKILL.md +5 -2
  396. package/.next/standalone/public/skill/quick-dev-chorus/SKILL.md +1 -1
  397. package/.next/standalone/public/skill/review-chorus/SKILL.md +5 -3
  398. package/.next/standalone/public/skill/task-reviewer-chorus/SKILL.md +4 -0
  399. package/.next/standalone/public/skill/yolo-chorus/SKILL.md +23 -7
  400. package/README.ja.md +3 -3
  401. package/README.ko.md +3 -3
  402. package/README.md +3 -3
  403. package/README.zh.md +3 -3
  404. package/cli/agent-cli-config.mjs +323 -0
  405. package/cli/agent-launcher.mjs +45 -17
  406. package/cli/claude-spawner.mjs +22 -13
  407. package/cli/codex-spawner.mjs +23 -15
  408. package/cli/credentials.mjs +7 -0
  409. package/cli/daemon-agent.mjs +1 -1
  410. package/cli/daemon-config.mjs +14 -0
  411. package/cli/daemon.mjs +34 -9
  412. package/cli/dsh-managed-config.mjs +219 -293
  413. package/cli/dsh-spawner.mjs +53 -27
  414. package/cli/init/steps/credential-seed.mjs +1 -1
  415. package/cli/kiro-spawner.mjs +22 -15
  416. package/cli/launch-diagnostics.mjs +67 -0
  417. package/cli/login.mjs +17 -1
  418. package/cli/pi-spawner.mjs +19 -12
  419. package/cli/prompts.mjs +52 -2
  420. package/cli/spawner-select.mjs +6 -11
  421. package/package.json +1 -1
  422. package/.next/standalone/.next/server/chunks/1114.js +0 -1
  423. package/.next/standalone/.next/server/chunks/2953.js +0 -1
  424. package/.next/standalone/.next/server/chunks/5162.js +0 -1
  425. package/.next/standalone/.next/server/chunks/6689.js +0 -1
  426. package/.next/standalone/.next/server/chunks/9667.js +0 -1
  427. package/.next/standalone/.next/static/chunks/11595.b81c0bf7732c3b62.js +0 -1
  428. package/.next/standalone/.next/static/chunks/24808-e3d95efc7ec039c5.js +0 -1
  429. package/.next/standalone/.next/static/chunks/33456.cfc9aa607a62e879.js +0 -1
  430. package/.next/standalone/.next/static/chunks/4860.41351a823cf400e4.js +0 -1
  431. package/.next/standalone/.next/static/chunks/51468-194d894e563580dd.js +0 -1
  432. package/.next/standalone/.next/static/chunks/61570-527701d072d00a24.js +0 -1
  433. package/.next/standalone/.next/static/chunks/65066-6da35d5cb080c7f5.js +0 -1
  434. package/.next/standalone/.next/static/chunks/72875-0987d09cd8406614.js +0 -1
  435. package/.next/standalone/.next/static/chunks/75936-79860953212592fd.js +0 -1
  436. package/.next/standalone/.next/static/chunks/79919-e02963faee5cb563.js +0 -1
  437. package/.next/standalone/.next/static/chunks/94643-e8f5fa25e2340cc8.js +0 -1
  438. package/.next/standalone/.next/static/chunks/99373.633f7c25e64bcdac.js +0 -1
  439. package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-bb5ef11586301c72.js +0 -1
  440. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/documents/[documentUuid]/page-725373108da1b08c.js +0 -1
  441. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/[proposalUuid]/page-7d2f4713697eb0a7.js +0 -1
  442. package/.next/standalone/.next/static/chunks/app/(dashboard)/projects/[uuid]/proposals/page-0225f87552b977d9.js +0 -1
  443. package/.next/standalone/.next/static/chunks/app/(dashboard)/settings/page-8b30678a58e7b2ee.js +0 -1
  444. package/.next/standalone/.next/static/css/1d9cf83f50b6db00.css +0 -1
  445. /package/.next/standalone/.next/static/{WSN4XeA1kUCI6CeEHcaT_ → IxKVu5zkFPTjSKAUR99yH}/_buildManifest.js +0 -0
  446. /package/.next/standalone/.next/static/{WSN4XeA1kUCI6CeEHcaT_ → IxKVu5zkFPTjSKAUR99yH}/_ssgManifest.js +0 -0
@@ -67,45 +67,17 @@ if command -v jq >/dev/null 2>&1; then
67
67
 
68
68
  fi
69
69
 
70
- # Detect OpenSpec mode for this repo, once per session.
71
- # Both conditions are required for OpenSpec mode to be usable:
72
- # (a) an openspec/ directory at the project root (this repo was inited via `openspec init`), AND
73
- # (b) the `openspec` CLI on PATH (so we can `openspec new change`, `validate`, `archive`).
74
- # Overrides (precedence high -> low, first match wins):
75
- # 1. enableOpenSpec userConfig toggle (default true) — UI-level switch.
76
- # 2. CHORUS_OPENSPEC_MODE=off env var — env-level explicit opt-out.
77
- # When the folder is present but the CLI is missing, surface that as a
78
- # specific reason so the user-visible toast can hint at the install step
79
- # instead of silently falling back.
70
+ # Resolve the active spec mode for this repo, once per session. The resolution
71
+ # logic lives in resolve-spec-mode.sh (pure: env + filesystem only) so it can be
72
+ # unit-tested see bin/tests/test-spec-mode-resolution.sh. It sets SPEC_MODE,
73
+ # SPEC_REASON, SPEC_FAIL, OPENSPEC_USABLE_REASON, OPENSPEC_HINT, CHORUS_OPENSPEC_ACTIVE.
80
74
  #
81
- # The inactive states split into two user-facing kinds:
82
- # - OPENSPEC_OPTOUT=1 the user explicitly turned OpenSpec off (plugin
83
- # toggle or env var). Respect it: show a neutral note, no nag.
84
- # - OPENSPEC_OPTOUT=0 OpenSpec is simply not set up (no folder, or folder
85
- # without the CLI). Point the user at `/chorus enable openspec`, which walks
86
- # the actual install/init steps — the banner stays a one-liner.
75
+ # Summary: an explicit CHORUS_SPEC_MODE (lite|openspec|off) wins; when UNSET,
76
+ # OpenSpec stays the default whenever it is usable (openspec/ dir + CLI, not
77
+ # disabled) and lite is the fallback only when OpenSpec is absent or disabled.
78
+ # Legacy CHORUS_OPENSPEC_MODE=off still forces not-openspec ( lite when unset).
87
79
  PROJECT_ROOT="${CLAUDE_PROJECT_DIR:-$PWD}"
88
- OPENSPEC_HINT=""
89
- OPENSPEC_OPTOUT=0
90
- if [ "${CLAUDE_PLUGIN_OPTION_ENABLEOPENSPEC:-true}" != "true" ]; then
91
- CHORUS_OPENSPEC_ACTIVE=0
92
- OPENSPEC_OPTOUT=1
93
- OPENSPEC_REASON="enableOpenSpec userConfig=false (plugin-level opt-out)"
94
- elif [ "${CHORUS_OPENSPEC_MODE:-}" = "off" ]; then
95
- CHORUS_OPENSPEC_ACTIVE=0
96
- OPENSPEC_OPTOUT=1
97
- OPENSPEC_REASON="CHORUS_OPENSPEC_MODE=off (explicit opt-out)"
98
- elif [ ! -d "${PROJECT_ROOT}/openspec" ]; then
99
- CHORUS_OPENSPEC_ACTIVE=0
100
- OPENSPEC_REASON="no openspec/ directory at ${PROJECT_ROOT}/openspec"
101
- elif ! command -v openspec >/dev/null 2>&1; then
102
- CHORUS_OPENSPEC_ACTIVE=0
103
- OPENSPEC_REASON="openspec/ directory present but \`openspec\` CLI not on PATH"
104
- OPENSPEC_HINT="install with: npm i -g @fission-ai/openspec"
105
- else
106
- CHORUS_OPENSPEC_ACTIVE=1
107
- OPENSPEC_REASON="openspec/ directory + openspec CLI both present"
108
- fi
80
+ . "${SCRIPT_DIR}/resolve-spec-mode.sh"
109
81
 
110
82
  # Build context for Claude (additionalContext)
111
83
  CONTEXT="# Chorus Plugin — Active
@@ -116,33 +88,33 @@ Chorus is connected at ${CHORUS_URL}. Session lifecycle hooks are enabled.
116
88
 
117
89
  ${CHECKIN_RESULT}
118
90
 
119
- ## OpenSpec Mode
91
+ ## Spec Mode
120
92
 
121
- CHORUS_OPENSPEC_ACTIVE=${CHORUS_OPENSPEC_ACTIVE} (${OPENSPEC_REASON})"
93
+ CHORUS_SPEC_MODE=${SPEC_MODE} (${SPEC_REASON})"
122
94
 
123
- if [ "$CHORUS_OPENSPEC_ACTIVE" = "1" ]; then
95
+ if [ "$SPEC_MODE" = "lite" ]; then
124
96
  CONTEXT="${CONTEXT}
125
97
 
126
- OpenSpec mode is **active** for this session. When the proposal / develop / yolo skills reach an OpenSpec-aware step, load the openspec-aware skill at \`.claude/skills/openspec-aware/SKILL.md\` and follow §3 (OpenSpec authoring) do NOT re-run the §1 detection block, the answer is already known.
98
+ Routing: lite follow the spec-lite skill (\`skills/spec-lite/SKILL.md\`). Author a Chorus-native change folder \`.chorus/specs/<slug>/\` (\`prd.md\` required; \`tech_design.md\` / \`adr.md\` / \`spec.md\` / \`guide.md\` optional) and mirror each \`<type>.md\` 1:1 into a Chorus Document of that type via \`chorus mcp call … --arg-file content=<file>\`. Do NOT scaffold \`openspec/changes/\` or add an \`OpenSpec change slug:\` line."
99
+ elif [ "$SPEC_MODE" = "off" ]; then
100
+ CONTEXT="${CONTEXT}
127
101
 
128
- Critical rule (openspec-aware §2 Rule 1): document mirror calls (\`chorus_pm_add_document_draft\` / \`chorus_pm_update_document_draft\` / \`chorus_pm_update_document\`) MUST fill \`content\` from the local file — prefer \`chorus mcp call <tool> '<json>' --arg-file content=<file>\`, falling back to \`chorus-api.sh mcp-tool\` with \`json_encode_file\` when \`chorus\` is not on PATH. Do NOT invoke these MCP tools directly with hand-typed \`content\` in OpenSpec mode."
129
- else
102
+ Routing: off free-form, no spec artifact. Do NOT create \`.chorus/specs/\` or \`openspec/changes/\` files; author document drafts inline via direct MCP."
103
+ elif [ -n "$SPEC_FAIL" ]; then
130
104
  CONTEXT="${CONTEXT}
131
105
 
132
- OpenSpec mode is **inactive** for this session. The proposal / develop / yolo skills follow their free-form path; do NOT scaffold \`openspec/changes/\`, do NOT add an \`OpenSpec change slug:\` line to proposal descriptions, and do NOT route document mirror calls through the \`chorus\` CLI or \`chorus-api.sh\`."
133
- if [ "$OPENSPEC_OPTOUT" = "1" ]; then
134
- CONTEXT="${CONTEXT}
106
+ Routing: openspec **cannot be honored** ${SPEC_FAIL}. The proposal / yolo skill MUST halt after resolving the mode; do NOT silently fall back to lite/free-form. Surface this to the user."
107
+ if [ -n "$OPENSPEC_HINT" ]; then
108
+ CONTEXT="${CONTEXT} Install hint: ${OPENSPEC_HINT}."
109
+ fi
110
+ else
111
+ CONTEXT="${CONTEXT}
135
112
 
136
- OpenSpec was **explicitly turned off** (${OPENSPEC_REASON}), so this is a deliberate choice — do NOT nag the user to enable it. If they ask to turn it back on, point them at re-enabling the plugin's \`enableOpenSpec\` toggle / unsetting \`CHORUS_OPENSPEC_MODE\`, then the OpenSpec setup section in the \`/chorus\` skill."
137
- elif [ -n "$OPENSPEC_HINT" ]; then
138
- CONTEXT="${CONTEXT}
113
+ CHORUS_OPENSPEC_ACTIVE=1 (${OPENSPEC_USABLE_REASON})
139
114
 
140
- Note: this repo has an \`openspec/\` directory, so the user likely intends to use OpenSpec mode but the \`openspec\` CLI is not installed. Surface this to the user (e.g. \"This repo is OpenSpec-init'd but the \\\`openspec\\\` CLI isn't installed locally ${OPENSPEC_HINT}\") before authoring documents. To set it up, run \`/chorus enable openspec\` (§6 walks the install + re-launch)."
141
- else
142
- CONTEXT="${CONTEXT}
115
+ Routing: openspec load the openspec-aware skill at \`.claude/skills/openspec-aware/SKILL.md\` and follow §3 (OpenSpec authoring)do NOT re-run the §1 detection block, the answer is already known.
143
116
 
144
- Note: OpenSpec is not set up in this repo (${OPENSPEC_REASON}). Spec-driven authoring is optionalfree-form works fine. If the user wants spec-driven mode (proposal.md / design.md / spec deltas mirrored into Chorus), run \`/chorus enable openspec\` §6 walks the \`npm i -g @fission-ai/openspec\` + \`openspec init\` steps and the re-launch."
145
- fi
117
+ Critical rule (openspec-aware §2 Rule 1): document mirror calls (\`chorus_pm_add_document_draft\` / \`chorus_pm_update_document_draft\` / \`chorus_pm_update_document\`) MUST fill \`content\` from the local file prefer \`chorus mcp call <tool> '<json>' --arg-file content=<file>\`, falling back to \`chorus-api.sh mcp-tool\` with \`json_encode_file\` when \`chorus\` is not on PATH. Do NOT invoke these MCP tools directly with hand-typed \`content\` in OpenSpec mode."
146
118
  fi
147
119
 
148
120
  CONTEXT="${CONTEXT}
@@ -164,18 +136,21 @@ Resuming with existing Chorus session: ${MAIN_SESSION}"
164
136
  "$API" mcp-tool "chorus_session_heartbeat" "$(printf '{"sessionUuid":"%s"}' "$MAIN_SESSION")" >/dev/null 2>&1 || true
165
137
  fi
166
138
 
167
- # Build user-visible message. When OpenSpec is off-but-enable-able, point the
168
- # user at `/chorus enable openspec` the skill walks the actual install/init.
169
- # active -> (OpenSpec Enabled)
170
- # not set up -> (OpenSpec off — run `/chorus enable openspec` to set it up)
171
- # explicit opt-out -> (OpenSpec off) [neutral, no nag — respects the choice]
139
+ # Build user-visible message. Always states the active spec mode (lite is the
140
+ # default); an explicit openspec that can't be honored is flagged as not usable.
141
+ # lite -> (Spec: lite)
142
+ # off -> (Spec: off)
143
+ # openspec (usable) -> (Spec: openspec)
144
+ # openspec (broken) -> (Spec: openspec — not usable)
172
145
  USER_MSG="Chorus connected at ${CHORUS_URL}"
173
- if [ "$CHORUS_OPENSPEC_ACTIVE" = "1" ]; then
174
- USER_MSG="${USER_MSG} (OpenSpec Enabled)"
175
- elif [ "$OPENSPEC_OPTOUT" = "1" ]; then
176
- USER_MSG="${USER_MSG} (OpenSpec off)"
146
+ if [ "$SPEC_MODE" = "lite" ]; then
147
+ USER_MSG="${USER_MSG} (Spec: lite)"
148
+ elif [ "$SPEC_MODE" = "off" ]; then
149
+ USER_MSG="${USER_MSG} (Spec: off)"
150
+ elif [ -n "$SPEC_FAIL" ]; then
151
+ USER_MSG="${USER_MSG} (Spec: openspec — not usable)"
177
152
  else
178
- USER_MSG="${USER_MSG} (OpenSpec off — run \`/chorus enable openspec\` to set it up)"
153
+ USER_MSG="${USER_MSG} (Spec: openspec)"
179
154
  fi
180
155
  if [ -n "$MAIN_SESSION" ]; then
181
156
  USER_MSG="${USER_MSG} (resumed session)"
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/env bash
2
+ # resolve-spec-mode.sh — resolve the active Chorus spec mode for a repo.
3
+ #
4
+ # Pure (env + filesystem only; no network). Sourced by on-session-start.sh and
5
+ # driven directly by tests/test-spec-mode-resolution.sh. Bash 3.2 compatible.
6
+ #
7
+ # Inputs (env):
8
+ # CHORUS_SPEC_MODE explicit override: lite | openspec | off (else unset)
9
+ # CHORUS_OPENSPEC_MODE legacy opt-out: "off" disables OpenSpec
10
+ # CLAUDE_PLUGIN_OPTION_ENABLEOPENSPEC plugin toggle: "false" disables OpenSpec (default "true")
11
+ # PROJECT_ROOT repo root to probe for openspec/ (defaults to $PWD)
12
+ # command -v openspec OpenSpec CLI presence on PATH
13
+ #
14
+ # Outputs (vars set in the caller's shell when sourced):
15
+ # SPEC_MODE lite | openspec | off (value surfaced to Claude)
16
+ # SPEC_REASON human-readable one-liner
17
+ # SPEC_FAIL non-empty => stage skill MUST halt (unsatisfiable explicit openspec)
18
+ # OPENSPEC_USABLE 1 | 0
19
+ # OPENSPEC_USABLE_REASON human-readable
20
+ # OPENSPEC_HINT install hint when OpenSpec is merely missing (else empty)
21
+ # CHORUS_OPENSPEC_ACTIVE 1 only when the resolved mode is a USABLE openspec
22
+ #
23
+ # Resolution (per owner): an explicit CHORUS_SPEC_MODE wins; when UNSET, OpenSpec
24
+ # stays the default whenever it is usable (openspec/ dir + CLI, not disabled), and
25
+ # lite is the fallback only when OpenSpec is absent or disabled.
26
+
27
+ : "${PROJECT_ROOT:=$PWD}"
28
+
29
+ # --- Is OpenSpec usable? (needs openspec/ dir + CLI on PATH + not disabled) ---
30
+ OPENSPEC_DISABLED=0
31
+ OPENSPEC_DISABLED_REASON=""
32
+ if [ "${CLAUDE_PLUGIN_OPTION_ENABLEOPENSPEC:-true}" != "true" ]; then
33
+ OPENSPEC_DISABLED=1
34
+ OPENSPEC_DISABLED_REASON="enableOpenSpec userConfig=false (plugin-level opt-out)"
35
+ elif [ "${CHORUS_OPENSPEC_MODE:-}" = "off" ]; then
36
+ OPENSPEC_DISABLED=1
37
+ OPENSPEC_DISABLED_REASON="CHORUS_OPENSPEC_MODE=off (legacy opt-out)"
38
+ fi
39
+
40
+ OPENSPEC_USABLE=0
41
+ OPENSPEC_USABLE_REASON=""
42
+ OPENSPEC_HINT=""
43
+ if [ "$OPENSPEC_DISABLED" = "1" ]; then
44
+ OPENSPEC_USABLE_REASON="$OPENSPEC_DISABLED_REASON"
45
+ elif [ ! -d "${PROJECT_ROOT}/openspec" ]; then
46
+ OPENSPEC_USABLE_REASON="no openspec/ directory at ${PROJECT_ROOT}/openspec"
47
+ OPENSPEC_HINT="npm i -g @fission-ai/openspec && openspec init"
48
+ elif ! command -v openspec >/dev/null 2>&1; then
49
+ OPENSPEC_USABLE_REASON="openspec/ directory present but \`openspec\` CLI not on PATH"
50
+ OPENSPEC_HINT="npm i -g @fission-ai/openspec"
51
+ else
52
+ OPENSPEC_USABLE=1
53
+ OPENSPEC_USABLE_REASON="openspec/ directory + openspec CLI both present"
54
+ fi
55
+
56
+ # --- Resolve CHORUS_SPEC_MODE ---
57
+ SPEC_FAIL=""
58
+ case "${CHORUS_SPEC_MODE:-}" in
59
+ lite)
60
+ SPEC_MODE="lite"
61
+ SPEC_REASON="explicit — Chorus-native lightweight specs in .chorus/specs/<slug>/"
62
+ ;;
63
+ off)
64
+ SPEC_MODE="off"
65
+ SPEC_REASON="explicit — free-form, no spec artifact"
66
+ ;;
67
+ openspec)
68
+ SPEC_MODE="openspec"
69
+ if [ "$OPENSPEC_USABLE" = "1" ]; then
70
+ SPEC_REASON="explicit; ${OPENSPEC_USABLE_REASON}"
71
+ elif [ "$OPENSPEC_DISABLED" = "1" ]; then
72
+ SPEC_REASON="explicit, but OpenSpec is disabled: ${OPENSPEC_USABLE_REASON}"
73
+ SPEC_FAIL="config conflict — CHORUS_SPEC_MODE=openspec vs OpenSpec disabled (${OPENSPEC_USABLE_REASON}); re-enable OpenSpec or set CHORUS_SPEC_MODE=lite"
74
+ else
75
+ SPEC_REASON="explicit, but OpenSpec is not installed: ${OPENSPEC_USABLE_REASON}"
76
+ SPEC_FAIL="OpenSpec not usable (${OPENSPEC_USABLE_REASON})"
77
+ fi
78
+ ;;
79
+ "")
80
+ # Unset: OpenSpec is the default when usable; lite is the fallback otherwise.
81
+ if [ "$OPENSPEC_USABLE" = "1" ]; then
82
+ SPEC_MODE="openspec"
83
+ SPEC_REASON="default — ${OPENSPEC_USABLE_REASON}; set CHORUS_SPEC_MODE=lite for Chorus-native specs, =off to disable"
84
+ else
85
+ SPEC_MODE="lite"
86
+ SPEC_REASON="default — OpenSpec not usable (${OPENSPEC_USABLE_REASON}); using Chorus-native lightweight specs in .chorus/specs/<slug>/"
87
+ fi
88
+ ;;
89
+ *)
90
+ # Unrecognized value: treat like unset (OpenSpec-if-usable, else lite).
91
+ if [ "$OPENSPEC_USABLE" = "1" ]; then
92
+ SPEC_MODE="openspec"
93
+ SPEC_REASON="CHORUS_SPEC_MODE='${CHORUS_SPEC_MODE}' unrecognized; falling back to default (${OPENSPEC_USABLE_REASON})"
94
+ else
95
+ SPEC_MODE="lite"
96
+ SPEC_REASON="CHORUS_SPEC_MODE='${CHORUS_SPEC_MODE}' unrecognized; OpenSpec not usable, defaulting to lite"
97
+ fi
98
+ ;;
99
+ esac
100
+
101
+ # Back-compat flag for the openspec-aware skill: active only when the resolved
102
+ # mode is a USABLE openspec.
103
+ if [ "$SPEC_MODE" = "openspec" ] && [ -z "$SPEC_FAIL" ]; then
104
+ CHORUS_OPENSPEC_ACTIVE=1
105
+ else
106
+ CHORUS_OPENSPEC_ACTIVE=0
107
+ fi
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env bash
2
+ # test-resolver-drift.sh — enforce the single-source invariant for the bash
3
+ # spec-mode resolver. resolve-spec-mode.sh is COPIED into each bash plugin port
4
+ # (Claude Code, Codex, Kiro, …); those copies MUST stay byte-identical to the
5
+ # canonical Claude Code copy, or the "one computation of the mode" guarantee
6
+ # silently rots as ports diverge. The 13-case matrix test covers the canonical
7
+ # copy; this guard makes every other copy equal to it. Bash 3.2 compatible.
8
+ set -u
9
+
10
+ # Repo root = four levels up from this script (tests → bin → chorus-plugin → public → repo).
11
+ ROOT="$(cd "$(dirname "$0")/../../../.." && pwd)"
12
+ CANON="$ROOT/public/chorus-plugin/bin/resolve-spec-mode.sh"
13
+
14
+ if [ ! -f "$CANON" ]; then
15
+ echo "FATAL: canonical resolver not found at $CANON" >&2
16
+ exit 1
17
+ fi
18
+
19
+ PASS=0
20
+ FAIL=0
21
+ echo "resolver drift-guard (canonical: public/chorus-plugin/bin/resolve-spec-mode.sh):"
22
+
23
+ # Every bash copy under public/, plugins/ or packages/ (excludes node_modules /
24
+ # build output). packages/ is included because the OpenClaw plugin — which has no
25
+ # SessionStart channel and so resolves the mode from its skill — SHIPS this
26
+ # resolver rather than hand-rolling the rule in Markdown.
27
+ COPIES=$(find "$ROOT/public" "$ROOT/plugins" "$ROOT/packages" -name resolve-spec-mode.sh 2>/dev/null \
28
+ | grep -v '/node_modules/' | grep -v '/dist/' | sort)
29
+
30
+ for f in $COPIES; do
31
+ rel="${f#$ROOT/}"
32
+ if [ "$f" = "$CANON" ]; then
33
+ echo " -- $rel (canonical)"
34
+ continue
35
+ fi
36
+ if diff -q "$CANON" "$f" >/dev/null 2>&1; then
37
+ PASS=$((PASS + 1)); echo " PASS $rel (byte-identical)"
38
+ else
39
+ FAIL=$((FAIL + 1)); echo " FAIL $rel DIFFERS from canonical:"
40
+ diff "$CANON" "$f" | sed 's/^/ /'
41
+ fi
42
+ done
43
+
44
+ echo ""
45
+ echo "Results: $PASS identical copy(ies), $FAIL drifted"
46
+ [ "$FAIL" -eq 0 ]
@@ -0,0 +1,328 @@
1
+ #!/usr/bin/env bash
2
+ # test-skill-harness-fidelity-negative.sh — negative cases for the fidelity guard.
3
+ #
4
+ # A blacklist guard that passes on a tree it never scanned is worse than no guard,
5
+ # so this harness plants each blacklisted literal into a synthetic repo and asserts
6
+ # the guard actually FAILS. Every case runs twice: once under a plain path and once
7
+ # under a path containing a space, because the original guard word-split its scope
8
+ # string and reported "3 PASS" on a repo checked out under e.g.
9
+ # "/Users/me/My Repos/Chorus" while having searched nothing.
10
+ #
11
+ # Bash 3.2 compatible.
12
+ set -u
13
+
14
+ GUARD="$(cd "$(dirname "$0")" && pwd)/test-skill-harness-fidelity.sh"
15
+ if [ ! -x "$GUARD" ]; then
16
+ echo "FATAL: guard not found or not executable at $GUARD" >&2
17
+ exit 1
18
+ fi
19
+
20
+ PASS=0
21
+ FAIL=0
22
+ TMPROOT="$(mktemp -d)"
23
+ trap 'rm -rf "$TMPROOT"' EXIT
24
+
25
+ # scaffold <repo-root> — a minimal tree with every path the guard scans, all clean.
26
+ # Missing paths are themselves a scan error now, so the clean case must be complete.
27
+ scaffold() {
28
+ _r="$1"
29
+ mkdir -p "$_r/public/chorus-plugin/bin/tests" \
30
+ "$_r/public/chorus-plugin/skills/develop" \
31
+ "$_r/public/chorus-plugin/agents" \
32
+ "$_r/public/kiro-plugin/.kiro/skills" \
33
+ "$_r/public/kiro-plugin/.kiro/agents" \
34
+ "$_r/public/kiro-plugin/.kiro/steering" \
35
+ "$_r/public/skill/proposal-reviewer-chorus" \
36
+ "$_r/packages/chorus-dsh/skills" \
37
+ "$_r/packages/chorus-dsh/skills/proposal-reviewer-chorus" \
38
+ "$_r/packages/chorus-pi/agents" \
39
+ "$_r/packages/openclaw-plugin/skills/proposal-reviewer" \
40
+ "$_r/plugins/chorus/skills" \
41
+ "$_r/plugins/chorus/skills/chorus-proposal-reviewer" \
42
+ "$_r/docs"
43
+ printf 'clean skill text, wait using your harness mechanism\n' \
44
+ > "$_r/public/chorus-plugin/skills/develop/SKILL.md"
45
+ printf '# SPEC_LITE\nthe template is inlined here\n' > "$_r/docs/SPEC_LITE.md"
46
+ cp "$GUARD" "$_r/public/chorus-plugin/bin/tests/$(basename "$GUARD")"
47
+
48
+ # ── The seven proposal-reviewer surfaces, all carrying the canonical rule.
49
+ # Checks 4-6 fail on a missing enumerated path, so a clean tree needs all seven
50
+ # present AND compliant. The truthful "Any shell command beyond read-only
51
+ # inspection —" sentence is included deliberately: it must not trip check 4.
52
+ for _pr in "public/chorus-plugin/agents/proposal-reviewer.md" \
53
+ "plugins/chorus/skills/chorus-proposal-reviewer/SKILL.md" \
54
+ "packages/chorus-pi/agents/chorus-proposal-reviewer.md" \
55
+ "packages/chorus-dsh/skills/proposal-reviewer-chorus/SKILL.md" \
56
+ "packages/openclaw-plugin/skills/proposal-reviewer/SKILL.md" \
57
+ "public/skill/proposal-reviewer-chorus/SKILL.md"; do
58
+ printf 'Bash is READ-ONLY inspection only: ls, cat, grep/rg, find.\n' > "$_r/$_pr"
59
+ printf 'No file writes, no git write ops, no installs, no test/build runs.\n' >> "$_r/$_pr"
60
+ printf 'Any shell command beyond read-only inspection — no file writes.\n' >> "$_r/$_pr"
61
+ printf 'Use it to confirm a file or directory exists before flagging it as missing.\n' >> "$_r/$_pr"
62
+ done
63
+ # Claude Code's file additionally needs the frontmatter list check 6 reads.
64
+ cat > "$_r/public/chorus-plugin/agents/proposal-reviewer.md" <<'CCAGENT'
65
+ ---
66
+ disallowedTools:
67
+ - Agent
68
+ - Edit
69
+ - Write
70
+ ---
71
+ Bash is READ-ONLY inspection only: ls, cat, grep/rg, find.
72
+ No file writes, no git write ops, no installs, no test/build runs.
73
+ Any shell command beyond read-only inspection — no file writes.
74
+ Use it to confirm a file or directory exists before flagging it as missing.
75
+ CCAGENT
76
+ # Kiro states the rule inside a JSON prompt string and names its tool `shell`.
77
+ cat > "$_r/public/kiro-plugin/.kiro/agents/chorus-proposal-reviewer.json" <<'KIROAGENT'
78
+ {
79
+ "name": "chorus-proposal-reviewer",
80
+ "tools": [
81
+ "read",
82
+ "shell",
83
+ "@chorus"
84
+ ],
85
+ "prompt": "Shell is READ-ONLY inspection only: ls, cat, grep/rg, find. No file writes, no git write ops, no installs, no test/build runs. Use it to confirm a file or directory exists before flagging it as missing."
86
+ }
87
+ KIROAGENT
88
+ # ── Check 4's extra scope: the Kiro orchestrator prompt and steering doc.
89
+ # Not reviewer definitions (so check 5 never looks at them), but they describe the
90
+ # grant to the agent that spawns the reviewer — a false claim here misleads it.
91
+ printf 'chorus-proposal-reviewer is scoped `tools: ["read", "shell", "@chorus"]`.\n' \
92
+ > "$_r/public/kiro-plugin/.kiro/agents/chorus.md"
93
+ printf 'chorus-proposal-reviewer is scoped `tools: ["read", "shell", "@chorus"]`.\n' \
94
+ > "$_r/public/kiro-plugin/.kiro/steering/chorus.md"
95
+ }
96
+
97
+ # run_guard <repo-root> — echo the guard's exit code, discarding its output.
98
+ run_guard() {
99
+ "$1/public/chorus-plugin/bin/tests/$(basename "$GUARD")" >/dev/null 2>&1
100
+ echo $?
101
+ }
102
+
103
+ # expect <label> <repo-root> <want-rc-zero|want-rc-nonzero>
104
+ expect() {
105
+ _label="$1"; _r="$2"; _want="$3"
106
+ _rc="$(run_guard "$_r")"
107
+ case "$_want" in
108
+ zero) if [ "$_rc" -eq 0 ]; then PASS=$((PASS+1)); echo " PASS $_label (exit 0)"
109
+ else FAIL=$((FAIL+1)); echo " FAIL $_label — wanted exit 0, got $_rc"; fi ;;
110
+ nonzero) if [ "$_rc" -ne 0 ]; then PASS=$((PASS+1)); echo " PASS $_label (exit $_rc)"
111
+ else FAIL=$((FAIL+1)); echo " FAIL $_label — guard reported PASS but the literal is present"; fi ;;
112
+ esac
113
+ }
114
+
115
+ # case_in <dirname> — build a fresh scaffold under TMPROOT/<dirname>, echo its path.
116
+ case_in() {
117
+ _d="$TMPROOT/$1"
118
+ rm -rf "$_d"; mkdir -p "$_d"
119
+ scaffold "$_d"
120
+ echo "$_d"
121
+ }
122
+
123
+ echo "skill/harness fidelity guard — negative cases (plain path AND path with a space):"
124
+ echo ""
125
+
126
+ for dirname in "plain" "with spaces"; do
127
+ echo "--- repo root: .../$dirname"
128
+
129
+ R="$(case_in "$dirname")"
130
+ expect "clean tree passes" "$R" zero
131
+
132
+ R="$(case_in "$dirname")"
133
+ printf 'Use TeamCreate to spawn the team\n' >> "$R/plugins/chorus/skills/note.md"
134
+ expect "check 1 catches TeamCreate" "$R" nonzero
135
+
136
+ R="$(case_in "$dirname")"
137
+ printf 'Run the reviewer synchronously and read the result\n' \
138
+ >> "$R/public/chorus-plugin/skills/develop/SKILL.md"
139
+ expect "check 2 catches 'reviewer synchronously'" "$R" nonzero
140
+
141
+ R="$(case_in "$dirname")"
142
+ printf 'the subagent waits and returns the VERDICT to you\n' \
143
+ >> "$R/public/kiro-plugin/.kiro/skills/SKILL.md"
144
+ expect "check 2 catches 'waits and returns the VERDICT' (kiro)" "$R" nonzero
145
+
146
+ R="$(case_in "$dirname")"
147
+ printf 'spawn it in **foreground** so it blocks\n' >> "$R/packages/chorus-dsh/skills/SKILL.md"
148
+ expect "check 2 catches 'in **foreground**' (dsh)" "$R" nonzero
149
+
150
+ R="$(case_in "$dirname")"
151
+ printf 'the launch returns the VERDICT inline\n' \
152
+ >> "$R/public/chorus-plugin/skills/develop/SKILL.md"
153
+ expect "check 2 catches 'returns the VERDICT inline'" "$R" nonzero
154
+
155
+ # dsh legitimately keeps run_in_background: false, so only this exact
156
+ # parenthesised imperative is blacklisted — not the flag itself.
157
+ R="$(case_in "$dirname")"
158
+ printf 'wait for it (do NOT set run_in_background)\n' \
159
+ >> "$R/packages/chorus-dsh/skills/SKILL.md"
160
+ expect "check 2 catches '(do NOT set run_in_background)' (dsh)" "$R" nonzero
161
+
162
+ R="$(case_in "$dirname")"
163
+ printf 'Copy .chorus/specs/TEMPLATE/spec.md to start\n' >> "$R/docs/SPEC_LITE.md"
164
+ expect "check 3 catches .chorus/specs/TEMPLATE" "$R" nonzero
165
+
166
+ # chorus-pi is excluded from check 2 on purpose: its blocking `subagent` really
167
+ # does return the VERDICT, so the phrase is true there and must NOT trip a FAIL.
168
+ R="$(case_in "$dirname")"
169
+ mkdir -p "$R/packages/chorus-pi/skills"
170
+ printf 'the blocking subagent waits and returns the VERDICT\n' \
171
+ >> "$R/packages/chorus-pi/skills/SKILL.md"
172
+ expect "check 2 still exempts packages/chorus-pi" "$R" zero
173
+
174
+ # dsh's real wording must stay green. If someone later replaces the literal
175
+ # blacklist with a proximity rule pairing run_in_background against
176
+ # "foreground"/"synchronous"/"inline", this case fails a correct tree — which
177
+ # is exactly the regression the guard's header forbids.
178
+ R="$(case_in "$dirname")"
179
+ printf 'Spawn the reviewer with run_in_background: false and read its result.\n' \
180
+ >> "$R/packages/chorus-dsh/skills/SKILL.md"
181
+ expect "check 2 allows dsh's legitimate run_in_background: false" "$R" zero
182
+
183
+ # A scan that cannot run must never look like "no hits".
184
+ R="$(case_in "$dirname")"
185
+ rm -rf "$R/packages/chorus-dsh"
186
+ expect "missing scope path fails instead of passing" "$R" nonzero
187
+
188
+ # ── Check 4 — shell-disabled claims, one fixture per phrasing family ──────
189
+ R="$(case_in "$dirname")"
190
+ printf -- '- **You are READ-ONLY.** Do NOT run Bash.\n' \
191
+ >> "$R/packages/chorus-dsh/skills/proposal-reviewer-chorus/SKILL.md"
192
+ expect "check 4 catches 'Do NOT run Bash' (dsh reviewer)" "$R" nonzero
193
+
194
+ R="$(case_in "$dirname")"
195
+ printf 'You have `read` and `@chorus` tools — no `shell`, no `write`.\n' \
196
+ >> "$R/public/kiro-plugin/.kiro/agents/chorus-proposal-reviewer.json"
197
+ expect "check 4 catches 'no \`shell\`' (kiro reviewer)" "$R" nonzero
198
+
199
+ R="$(case_in "$dirname")"
200
+ printf 'Bash is disabled for this agent.\n' \
201
+ >> "$R/packages/chorus-pi/agents/chorus-proposal-reviewer.md"
202
+ expect "check 4 catches 'Bash is disabled' (pi reviewer)" "$R" nonzero
203
+
204
+ R="$(case_in "$dirname")"
205
+ printf 'Running any shell commands is prohibited.\n' \
206
+ >> "$R/plugins/chorus/skills/chorus-proposal-reviewer/SKILL.md"
207
+ expect "check 4 catches 'Running any shell commands' (codex reviewer)" "$R" nonzero
208
+
209
+ R="$(case_in "$dirname")"
210
+ printf 'You cannot run shell commands.\n' \
211
+ >> "$R/public/skill/proposal-reviewer-chorus/SKILL.md"
212
+ expect "check 4 catches 'cannot run shell' (standalone skill)" "$R" nonzero
213
+
214
+ R="$(case_in "$dirname")"
215
+ printf 'Do not edit files or run Bash commands.\n' \
216
+ >> "$R/packages/openclaw-plugin/skills/proposal-reviewer/SKILL.md"
217
+ expect "check 4 catches 'or run Bash commands' (openclaw reviewer)" "$R" nonzero
218
+
219
+ # Check 4's extra scope: the orchestrator prompt and the steering doc. These two
220
+ # carried the "no `shell`" claim while sitting outside the guard, which is how the
221
+ # false statement survived the fix — so each gets its own fixture.
222
+ R="$(case_in "$dirname")"
223
+ printf 'Each reviewer is scoped `tools: ["read", "@chorus"]`, no `shell`.\n' \
224
+ >> "$R/public/kiro-plugin/.kiro/agents/chorus.md"
225
+ expect "check 4 catches 'no \`shell\`' (kiro orchestrator prompt)" "$R" nonzero
226
+
227
+ R="$(case_in "$dirname")"
228
+ printf 'The reviewer cannot run shell commands.\n' \
229
+ >> "$R/public/kiro-plugin/.kiro/steering/chorus.md"
230
+ expect "check 4 catches 'cannot run shell' (kiro steering doc)" "$R" nonzero
231
+
232
+ R="$(case_in "$dirname")"
233
+ rm -f "$R/public/kiro-plugin/.kiro/agents/chorus.md"
234
+ expect "a deleted check-4-only file fails instead of being skipped" "$R" nonzero
235
+
236
+ # The clean tree passes with neither of those two files carrying the canonical
237
+ # rule markers — that is check 5 correctly ignoring them (they are orchestrator
238
+ # prose, not reviewer definitions). Adding them to PR_FILES would break it.
239
+
240
+ # The truthful sentence every surface keeps must NOT trip check 4. This is the
241
+ # false positive an under-anchored blacklist (a bare "shell"/"Bash") would cause.
242
+ R="$(case_in "$dirname")"
243
+ printf 'Any shell command beyond read-only inspection — no git write ops.\n' \
244
+ >> "$R/public/skill/proposal-reviewer-chorus/SKILL.md"
245
+ expect "check 4 allows the truthful 'beyond read-only inspection' prose" "$R" zero
246
+
247
+ # ── Check 5 — the canonical rule must be present, all three markers ───────
248
+ R="$(case_in "$dirname")"
249
+ grep -v 'READ-ONLY inspection only' \
250
+ "$R/packages/openclaw-plugin/skills/proposal-reviewer/SKILL.md" > "$R/tmp.md"
251
+ mv "$R/tmp.md" "$R/packages/openclaw-plugin/skills/proposal-reviewer/SKILL.md"
252
+ expect "check 5 catches a missing read-only-inspection marker (openclaw)" "$R" nonzero
253
+
254
+ R="$(case_in "$dirname")"
255
+ grep -v 'before flagging it as missing' \
256
+ "$R/packages/chorus-dsh/skills/proposal-reviewer-chorus/SKILL.md" > "$R/tmp.md"
257
+ mv "$R/tmp.md" "$R/packages/chorus-dsh/skills/proposal-reviewer-chorus/SKILL.md"
258
+ expect "check 5 catches a missing existence-check obligation (dsh)" "$R" nonzero
259
+
260
+ R="$(case_in "$dirname")"
261
+ grep -v 'no installs, no test/build runs' \
262
+ "$R/packages/chorus-pi/agents/chorus-proposal-reviewer.md" > "$R/tmp.md"
263
+ mv "$R/tmp.md" "$R/packages/chorus-pi/agents/chorus-proposal-reviewer.md"
264
+ expect "check 5 catches a missing forbidden-command list (pi)" "$R" nonzero
265
+
266
+ # ── Enumerated path deleted — must FAIL, never be silently skipped ────────
267
+ R="$(case_in "$dirname")"
268
+ rm -f "$R/public/skill/proposal-reviewer-chorus/SKILL.md"
269
+ expect "a deleted enumerated surface fails instead of being skipped" "$R" nonzero
270
+
271
+ # ── Check 6 — the tool grants behind the rule ────────────────────────────
272
+ R="$(case_in "$dirname")"
273
+ # awk, not `sed 's/…/…\n…/'` — BSD sed (macOS) does not expand \n in the
274
+ # replacement, so the sed form would silently insert a literal "n" and the
275
+ # fixture would prove nothing.
276
+ awk '{print} /^ - Agent$/{print " - Bash"}' \
277
+ "$R/public/chorus-plugin/agents/proposal-reviewer.md" > "$R/tmp.md"
278
+ mv "$R/tmp.md" "$R/public/chorus-plugin/agents/proposal-reviewer.md"
279
+ expect "check 6 catches '- Bash' re-added to disallowedTools (claude code)" "$R" nonzero
280
+
281
+ # Two evasions of a whole-line `- Bash` match, both of which YAML accepts and a
282
+ # harness would honour: flow style, and a quoted entry.
283
+ R="$(case_in "$dirname")"
284
+ awk '/^disallowedTools:$/{print "disallowedTools: [Bash, Agent, Edit, Write]"; skip=1; next}
285
+ skip&&/^[[:space:]]*-[[:space:]]/{next} {skip=0; print}' \
286
+ "$R/public/chorus-plugin/agents/proposal-reviewer.md" > "$R/tmp.md"
287
+ mv "$R/tmp.md" "$R/public/chorus-plugin/agents/proposal-reviewer.md"
288
+ expect "check 6 catches Bash in a YAML flow-style disallowedTools (claude code)" "$R" nonzero
289
+
290
+ R="$(case_in "$dirname")"
291
+ awk '{print} /^ - Agent$/{print " - \"Bash\""}' \
292
+ "$R/public/chorus-plugin/agents/proposal-reviewer.md" > "$R/tmp.md"
293
+ mv "$R/tmp.md" "$R/public/chorus-plugin/agents/proposal-reviewer.md"
294
+ expect "check 6 catches a quoted '- \"Bash\"' entry (claude code)" "$R" nonzero
295
+
296
+ # Two more evasions YAML accepts inside the list: a `#` comment line and a blank
297
+ # line before `- Bash`. An extractor that treats either as the end of the list
298
+ # reports PASS on a tree whose deny list really does contain Bash.
299
+ R="$(case_in "$dirname")"
300
+ awk '{print} /^ - Agent$/{print " # restrict shell"; print " - Bash"}' \
301
+ "$R/public/chorus-plugin/agents/proposal-reviewer.md" > "$R/tmp.md"
302
+ mv "$R/tmp.md" "$R/public/chorus-plugin/agents/proposal-reviewer.md"
303
+ expect "check 6 catches '- Bash' after a comment line in the list (claude code)" "$R" nonzero
304
+
305
+ R="$(case_in "$dirname")"
306
+ awk '{print} /^ - Agent$/{print ""; print " - Bash"}' \
307
+ "$R/public/chorus-plugin/agents/proposal-reviewer.md" > "$R/tmp.md"
308
+ mv "$R/tmp.md" "$R/public/chorus-plugin/agents/proposal-reviewer.md"
309
+ expect "check 6 catches '- Bash' after a blank line in the list (claude code)" "$R" nonzero
310
+
311
+ R="$(case_in "$dirname")"
312
+ grep -v '"shell",' "$R/public/kiro-plugin/.kiro/agents/chorus-proposal-reviewer.json" \
313
+ > "$R/tmp.json"
314
+ mv "$R/tmp.json" "$R/public/kiro-plugin/.kiro/agents/chorus-proposal-reviewer.json"
315
+ expect "check 6 catches \`shell\` dropped from kiro's tools" "$R" nonzero
316
+
317
+ # A `Bash` mention elsewhere in the Claude Code agent body is not a tool denial —
318
+ # only a `- Bash` entry inside the disallowedTools list is.
319
+ R="$(case_in "$dirname")"
320
+ printf 'Bash inspection findings belong in the VERDICT comment.\n' \
321
+ >> "$R/public/chorus-plugin/agents/proposal-reviewer.md"
322
+ expect "check 6 does not fire on 'Bash' outside the disallowedTools list" "$R" zero
323
+
324
+ echo ""
325
+ done
326
+
327
+ echo "Results: $PASS passed, $FAIL failed"
328
+ [ "$FAIL" -eq 0 ]