@guyghost/swarm-dao-core 0.3.0 → 0.5.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 (304) hide show
  1. package/dist/adapters/attention/fs-attention.store.d.ts +17 -0
  2. package/dist/adapters/attention/fs-attention.store.d.ts.map +1 -0
  3. package/dist/adapters/attention/fs-attention.store.js +59 -0
  4. package/dist/adapters/attention/fs-attention.store.js.map +1 -0
  5. package/dist/adapters/git-workspace.d.ts +26 -0
  6. package/dist/adapters/git-workspace.d.ts.map +1 -0
  7. package/dist/adapters/git-workspace.js +84 -0
  8. package/dist/adapters/git-workspace.js.map +1 -0
  9. package/dist/adapters/index.d.ts +6 -0
  10. package/dist/adapters/index.d.ts.map +1 -0
  11. package/dist/adapters/index.js +6 -0
  12. package/dist/adapters/index.js.map +1 -0
  13. package/dist/adapters/persistence/file-dao-state.repository.d.ts +15 -0
  14. package/dist/adapters/persistence/file-dao-state.repository.d.ts.map +1 -0
  15. package/dist/adapters/persistence/file-dao-state.repository.js +85 -0
  16. package/dist/adapters/persistence/file-dao-state.repository.js.map +1 -0
  17. package/dist/adapters/persistence/in-memory-dao-state.repository.d.ts +10 -0
  18. package/dist/adapters/persistence/in-memory-dao-state.repository.d.ts.map +1 -0
  19. package/dist/adapters/persistence/in-memory-dao-state.repository.js +14 -0
  20. package/dist/adapters/persistence/in-memory-dao-state.repository.js.map +1 -0
  21. package/dist/adapters/persistence/legacy-dao-state.repository.d.ts +11 -0
  22. package/dist/adapters/persistence/legacy-dao-state.repository.d.ts.map +1 -0
  23. package/dist/adapters/persistence/legacy-dao-state.repository.js +14 -0
  24. package/dist/adapters/persistence/legacy-dao-state.repository.js.map +1 -0
  25. package/dist/application/index.d.ts +16 -0
  26. package/dist/application/index.d.ts.map +1 -0
  27. package/dist/application/index.js +16 -0
  28. package/dist/application/index.js.map +1 -0
  29. package/dist/application/initialize-dao.use-case.d.ts +20 -0
  30. package/dist/application/initialize-dao.use-case.d.ts.map +1 -0
  31. package/dist/application/initialize-dao.use-case.js +17 -0
  32. package/dist/application/initialize-dao.use-case.js.map +1 -0
  33. package/dist/application/proposals/control-proposal.use-case.d.ts +23 -0
  34. package/dist/application/proposals/control-proposal.use-case.d.ts.map +1 -0
  35. package/dist/application/proposals/control-proposal.use-case.js +53 -0
  36. package/dist/application/proposals/control-proposal.use-case.js.map +1 -0
  37. package/dist/application/proposals/create-amendment-proposal.use-case.d.ts +25 -0
  38. package/dist/application/proposals/create-amendment-proposal.use-case.d.ts.map +1 -0
  39. package/dist/application/proposals/create-amendment-proposal.use-case.js +39 -0
  40. package/dist/application/proposals/create-amendment-proposal.use-case.js.map +1 -0
  41. package/dist/application/proposals/create-proposal.use-case.d.ts +34 -0
  42. package/dist/application/proposals/create-proposal.use-case.d.ts.map +1 -0
  43. package/dist/application/proposals/create-proposal.use-case.js +49 -0
  44. package/dist/application/proposals/create-proposal.use-case.js.map +1 -0
  45. package/dist/application/proposals/deliberate-proposal.use-case.d.ts +35 -0
  46. package/dist/application/proposals/deliberate-proposal.use-case.d.ts.map +1 -0
  47. package/dist/application/proposals/deliberate-proposal.use-case.js +67 -0
  48. package/dist/application/proposals/deliberate-proposal.use-case.js.map +1 -0
  49. package/dist/application/proposals/dry-run-proposal.use-case.d.ts +21 -0
  50. package/dist/application/proposals/dry-run-proposal.use-case.d.ts.map +1 -0
  51. package/dist/application/proposals/dry-run-proposal.use-case.js +20 -0
  52. package/dist/application/proposals/dry-run-proposal.use-case.js.map +1 -0
  53. package/dist/application/proposals/execute-proposal.use-case.d.ts +29 -0
  54. package/dist/application/proposals/execute-proposal.use-case.d.ts.map +1 -0
  55. package/dist/application/proposals/execute-proposal.use-case.js +66 -0
  56. package/dist/application/proposals/execute-proposal.use-case.js.map +1 -0
  57. package/dist/application/proposals/rate-proposal.use-case.d.ts +24 -0
  58. package/dist/application/proposals/rate-proposal.use-case.d.ts.map +1 -0
  59. package/dist/application/proposals/rate-proposal.use-case.js +33 -0
  60. package/dist/application/proposals/rate-proposal.use-case.js.map +1 -0
  61. package/dist/application/proposals/record-deliberation-outputs.use-case.d.ts +21 -0
  62. package/dist/application/proposals/record-deliberation-outputs.use-case.d.ts.map +1 -0
  63. package/dist/application/proposals/record-deliberation-outputs.use-case.js +65 -0
  64. package/dist/application/proposals/record-deliberation-outputs.use-case.js.map +1 -0
  65. package/dist/application/proposals/rollback-proposal.use-case.d.ts +20 -0
  66. package/dist/application/proposals/rollback-proposal.use-case.d.ts.map +1 -0
  67. package/dist/application/proposals/rollback-proposal.use-case.js +17 -0
  68. package/dist/application/proposals/rollback-proposal.use-case.js.map +1 -0
  69. package/dist/application/proposals/round-table.use-case.d.ts +27 -0
  70. package/dist/application/proposals/round-table.use-case.d.ts.map +1 -0
  71. package/dist/application/proposals/round-table.use-case.js +55 -0
  72. package/dist/application/proposals/round-table.use-case.js.map +1 -0
  73. package/dist/application/proposals/ship-proposal.use-case.d.ts +26 -0
  74. package/dist/application/proposals/ship-proposal.use-case.d.ts.map +1 -0
  75. package/dist/application/proposals/ship-proposal.use-case.js +60 -0
  76. package/dist/application/proposals/ship-proposal.use-case.js.map +1 -0
  77. package/dist/application/proposals/start-deliberation.use-case.d.ts +21 -0
  78. package/dist/application/proposals/start-deliberation.use-case.d.ts.map +1 -0
  79. package/dist/application/proposals/start-deliberation.use-case.js +30 -0
  80. package/dist/application/proposals/start-deliberation.use-case.js.map +1 -0
  81. package/dist/application/proposals/transition-proposal.use-case.d.ts +20 -0
  82. package/dist/application/proposals/transition-proposal.use-case.d.ts.map +1 -0
  83. package/dist/application/proposals/transition-proposal.use-case.js +19 -0
  84. package/dist/application/proposals/transition-proposal.use-case.js.map +1 -0
  85. package/dist/application/proposals/update-proposal.use-case.d.ts +26 -0
  86. package/dist/application/proposals/update-proposal.use-case.d.ts.map +1 -0
  87. package/dist/application/proposals/update-proposal.use-case.js +19 -0
  88. package/dist/application/proposals/update-proposal.use-case.js.map +1 -0
  89. package/dist/commands/index.d.ts +2 -0
  90. package/dist/commands/index.d.ts.map +1 -0
  91. package/dist/commands/index.js +2 -0
  92. package/dist/commands/index.js.map +1 -0
  93. package/dist/commands/registry.d.ts +46 -0
  94. package/dist/commands/registry.d.ts.map +1 -0
  95. package/dist/commands/registry.js +367 -0
  96. package/dist/commands/registry.js.map +1 -0
  97. package/dist/config.d.ts +17 -0
  98. package/dist/config.d.ts.map +1 -1
  99. package/dist/config.js +9 -1
  100. package/dist/config.js.map +1 -1
  101. package/dist/control/gates.d.ts +4 -1
  102. package/dist/control/gates.d.ts.map +1 -1
  103. package/dist/control/gates.js +22 -10
  104. package/dist/control/gates.js.map +1 -1
  105. package/dist/delivery/dependencies.d.ts.map +1 -1
  106. package/dist/delivery/dependencies.js +15 -7
  107. package/dist/delivery/dependencies.js.map +1 -1
  108. package/dist/delivery/dry-run.d.ts.map +1 -1
  109. package/dist/delivery/dry-run.js +3 -44
  110. package/dist/delivery/dry-run.js.map +1 -1
  111. package/dist/delivery/execution-isolation.d.ts +34 -0
  112. package/dist/delivery/execution-isolation.d.ts.map +1 -0
  113. package/dist/delivery/execution-isolation.js +97 -0
  114. package/dist/delivery/execution-isolation.js.map +1 -0
  115. package/dist/delivery/execution.d.ts.map +1 -1
  116. package/dist/delivery/execution.js +7 -5
  117. package/dist/delivery/execution.js.map +1 -1
  118. package/dist/delivery/index.d.ts +1 -0
  119. package/dist/delivery/index.d.ts.map +1 -1
  120. package/dist/delivery/index.js +1 -0
  121. package/dist/delivery/index.js.map +1 -1
  122. package/dist/delivery/plans.d.ts +3 -1
  123. package/dist/delivery/plans.d.ts.map +1 -1
  124. package/dist/delivery/plans.js +2 -2
  125. package/dist/delivery/plans.js.map +1 -1
  126. package/dist/domain/dry-run.d.ts +3 -0
  127. package/dist/domain/dry-run.d.ts.map +1 -0
  128. package/dist/domain/dry-run.js +28 -0
  129. package/dist/domain/dry-run.js.map +1 -0
  130. package/dist/domain/index.d.ts +6 -0
  131. package/dist/domain/index.d.ts.map +1 -0
  132. package/dist/domain/index.js +7 -0
  133. package/dist/domain/index.js.map +1 -0
  134. package/dist/governance/agents.d.ts +2 -0
  135. package/dist/governance/agents.d.ts.map +1 -1
  136. package/dist/governance/agents.js +148 -173
  137. package/dist/governance/agents.js.map +1 -1
  138. package/dist/governance/charter.d.ts +14 -0
  139. package/dist/governance/charter.d.ts.map +1 -0
  140. package/dist/governance/charter.js +65 -0
  141. package/dist/governance/charter.js.map +1 -0
  142. package/dist/governance/delegation.machine.d.ts +316 -0
  143. package/dist/governance/delegation.machine.d.ts.map +1 -0
  144. package/dist/governance/delegation.machine.js +387 -0
  145. package/dist/governance/delegation.machine.js.map +1 -0
  146. package/dist/governance/delegation.utils.d.ts +55 -0
  147. package/dist/governance/delegation.utils.d.ts.map +1 -0
  148. package/dist/governance/delegation.utils.js +157 -0
  149. package/dist/governance/delegation.utils.js.map +1 -0
  150. package/dist/governance/edit-gate.d.ts +47 -0
  151. package/dist/governance/edit-gate.d.ts.map +1 -0
  152. package/dist/governance/edit-gate.js +156 -0
  153. package/dist/governance/edit-gate.js.map +1 -0
  154. package/dist/governance/index.d.ts +3 -0
  155. package/dist/governance/index.d.ts.map +1 -1
  156. package/dist/governance/index.js +3 -0
  157. package/dist/governance/index.js.map +1 -1
  158. package/dist/governance/lifecycle.d.ts +0 -6
  159. package/dist/governance/lifecycle.d.ts.map +1 -1
  160. package/dist/governance/lifecycle.js +7 -31
  161. package/dist/governance/lifecycle.js.map +1 -1
  162. package/dist/governance/proposal.machine.d.ts +2 -130
  163. package/dist/governance/proposal.machine.d.ts.map +1 -1
  164. package/dist/governance/proposal.machine.js +2 -377
  165. package/dist/governance/proposal.machine.js.map +1 -1
  166. package/dist/governance/proposal.utils.d.ts +22 -165
  167. package/dist/governance/proposal.utils.d.ts.map +1 -1
  168. package/dist/governance/proposal.utils.js +52 -119
  169. package/dist/governance/proposal.utils.js.map +1 -1
  170. package/dist/governance/scoring.d.ts.map +1 -1
  171. package/dist/governance/scoring.js +36 -16
  172. package/dist/governance/scoring.js.map +1 -1
  173. package/dist/governance/voting.d.ts.map +1 -1
  174. package/dist/governance/voting.js +24 -14
  175. package/dist/governance/voting.js.map +1 -1
  176. package/dist/host-tools/github-config.d.ts.map +1 -1
  177. package/dist/host-tools/github-config.js +17 -5
  178. package/dist/host-tools/github-config.js.map +1 -1
  179. package/dist/host-tools/handlers.d.ts +14 -11
  180. package/dist/host-tools/handlers.d.ts.map +1 -1
  181. package/dist/host-tools/handlers.js +204 -335
  182. package/dist/host-tools/handlers.js.map +1 -1
  183. package/dist/host-tools/messages.d.ts +10 -4
  184. package/dist/host-tools/messages.d.ts.map +1 -1
  185. package/dist/host-tools/messages.js +14 -17
  186. package/dist/host-tools/messages.js.map +1 -1
  187. package/dist/index.d.ts +6 -0
  188. package/dist/index.d.ts.map +1 -1
  189. package/dist/index.js +12 -0
  190. package/dist/index.js.map +1 -1
  191. package/dist/integrations/github.d.ts.map +1 -1
  192. package/dist/integrations/github.js +5 -2
  193. package/dist/integrations/github.js.map +1 -1
  194. package/dist/integrations/http.d.ts +12 -1
  195. package/dist/integrations/http.d.ts.map +1 -1
  196. package/dist/integrations/http.js +114 -17
  197. package/dist/integrations/http.js.map +1 -1
  198. package/dist/intelligence/delegation.d.ts +41 -0
  199. package/dist/intelligence/delegation.d.ts.map +1 -0
  200. package/dist/intelligence/delegation.js +162 -0
  201. package/dist/intelligence/delegation.js.map +1 -0
  202. package/dist/intelligence/index.d.ts +2 -0
  203. package/dist/intelligence/index.d.ts.map +1 -1
  204. package/dist/intelligence/index.js +2 -0
  205. package/dist/intelligence/index.js.map +1 -1
  206. package/dist/intelligence/model.d.ts +28 -2
  207. package/dist/intelligence/model.d.ts.map +1 -1
  208. package/dist/intelligence/model.js +36 -3
  209. package/dist/intelligence/model.js.map +1 -1
  210. package/dist/intelligence/roundtable.d.ts +4 -2
  211. package/dist/intelligence/roundtable.d.ts.map +1 -1
  212. package/dist/intelligence/roundtable.js +2 -2
  213. package/dist/intelligence/roundtable.js.map +1 -1
  214. package/dist/intelligence/sequential.d.ts +36 -0
  215. package/dist/intelligence/sequential.d.ts.map +1 -0
  216. package/dist/intelligence/sequential.js +91 -0
  217. package/dist/intelligence/sequential.js.map +1 -0
  218. package/dist/intelligence/swarm.d.ts +19 -4
  219. package/dist/intelligence/swarm.d.ts.map +1 -1
  220. package/dist/intelligence/swarm.js +107 -53
  221. package/dist/intelligence/swarm.js.map +1 -1
  222. package/dist/intelligence/synthesis.d.ts.map +1 -1
  223. package/dist/intelligence/synthesis.js +16 -4
  224. package/dist/intelligence/synthesis.js.map +1 -1
  225. package/dist/models/graph-engineering.machine.d.ts +219 -0
  226. package/dist/models/graph-engineering.machine.d.ts.map +1 -0
  227. package/dist/models/graph-engineering.machine.js +214 -0
  228. package/dist/models/graph-engineering.machine.js.map +1 -0
  229. package/dist/models/improvement-loop.machine.d.ts +239 -0
  230. package/dist/models/improvement-loop.machine.d.ts.map +1 -0
  231. package/dist/models/improvement-loop.machine.js +254 -0
  232. package/dist/models/improvement-loop.machine.js.map +1 -0
  233. package/dist/models/index.d.ts +5 -0
  234. package/dist/models/index.d.ts.map +1 -0
  235. package/dist/models/index.js +5 -0
  236. package/dist/models/index.js.map +1 -0
  237. package/dist/models/product-loop.machine.d.ts +531 -0
  238. package/dist/models/product-loop.machine.d.ts.map +1 -0
  239. package/dist/models/product-loop.machine.js +699 -0
  240. package/dist/models/product-loop.machine.js.map +1 -0
  241. package/dist/models/proposal.machine.d.ts +82 -0
  242. package/dist/models/proposal.machine.d.ts.map +1 -0
  243. package/dist/models/proposal.machine.js +68 -0
  244. package/dist/models/proposal.machine.js.map +1 -0
  245. package/dist/observability/attention.d.ts +40 -0
  246. package/dist/observability/attention.d.ts.map +1 -0
  247. package/dist/observability/attention.js +119 -0
  248. package/dist/observability/attention.js.map +1 -0
  249. package/dist/observability/index.d.ts +1 -0
  250. package/dist/observability/index.d.ts.map +1 -1
  251. package/dist/observability/index.js +1 -0
  252. package/dist/observability/index.js.map +1 -1
  253. package/dist/observability/logging.d.ts +6 -0
  254. package/dist/observability/logging.d.ts.map +1 -1
  255. package/dist/observability/logging.js +36 -6
  256. package/dist/observability/logging.js.map +1 -1
  257. package/dist/observability/metrics.d.ts +7 -0
  258. package/dist/observability/metrics.d.ts.map +1 -1
  259. package/dist/observability/metrics.js +179 -43
  260. package/dist/observability/metrics.js.map +1 -1
  261. package/dist/persistence.d.ts +5 -6
  262. package/dist/persistence.d.ts.map +1 -1
  263. package/dist/persistence.js +197 -140
  264. package/dist/persistence.js.map +1 -1
  265. package/dist/ports/clock.d.ts +7 -0
  266. package/dist/ports/clock.d.ts.map +1 -0
  267. package/dist/ports/clock.js +5 -0
  268. package/dist/ports/clock.js.map +1 -0
  269. package/dist/ports/host.d.ts +8 -0
  270. package/dist/ports/host.d.ts.map +1 -0
  271. package/dist/ports/host.js +2 -0
  272. package/dist/ports/host.js.map +1 -0
  273. package/dist/ports/index.d.ts +5 -0
  274. package/dist/ports/index.d.ts.map +1 -0
  275. package/dist/ports/index.js +5 -0
  276. package/dist/ports/index.js.map +1 -0
  277. package/dist/ports/repository.d.ts +7 -0
  278. package/dist/ports/repository.d.ts.map +1 -0
  279. package/dist/ports/repository.js +2 -0
  280. package/dist/ports/repository.js.map +1 -0
  281. package/dist/ports/workspace.d.ts +14 -0
  282. package/dist/ports/workspace.d.ts.map +1 -0
  283. package/dist/ports/workspace.js +14 -0
  284. package/dist/ports/workspace.js.map +1 -0
  285. package/dist/presenters/index.d.ts +2 -0
  286. package/dist/presenters/index.d.ts.map +1 -0
  287. package/dist/presenters/index.js +2 -0
  288. package/dist/presenters/index.js.map +1 -0
  289. package/dist/presenters/proposal.presenter.d.ts +30 -0
  290. package/dist/presenters/proposal.presenter.d.ts.map +1 -0
  291. package/dist/presenters/proposal.presenter.js +47 -0
  292. package/dist/presenters/proposal.presenter.js.map +1 -0
  293. package/dist/types/index.d.ts +70 -0
  294. package/dist/types/index.d.ts.map +1 -1
  295. package/dist/types/index.js +12 -0
  296. package/dist/types/index.js.map +1 -1
  297. package/dist/utils/host.d.ts.map +1 -1
  298. package/dist/utils/host.js +77 -6
  299. package/dist/utils/host.js.map +1 -1
  300. package/dist/utils/security.d.ts +7 -1
  301. package/dist/utils/security.d.ts.map +1 -1
  302. package/dist/utils/security.js +18 -2
  303. package/dist/utils/security.js.map +1 -1
  304. package/package.json +13 -1
@@ -1,288 +1,198 @@
1
+ import { createExecutionWorkspace } from "../adapters/git-workspace.js";
2
+ import { LegacyDaoStateRepository } from "../adapters/persistence/legacy-dao-state.repository.js";
3
+ import { InitializeDaoUseCase } from "../application/initialize-dao.use-case.js";
4
+ import { ControlProposalUseCase } from "../application/proposals/control-proposal.use-case.js";
5
+ import { CreateAmendmentProposalUseCase } from "../application/proposals/create-amendment-proposal.use-case.js";
6
+ import { CreateProposalUseCase } from "../application/proposals/create-proposal.use-case.js";
7
+ import { DeliberateProposalUseCase } from "../application/proposals/deliberate-proposal.use-case.js";
8
+ import { DryRunProposalUseCase } from "../application/proposals/dry-run-proposal.use-case.js";
9
+ import { ExecuteProposalUseCase } from "../application/proposals/execute-proposal.use-case.js";
10
+ import { RateProposalUseCase } from "../application/proposals/rate-proposal.use-case.js";
11
+ import { RecordDeliberationOutputsUseCase } from "../application/proposals/record-deliberation-outputs.use-case.js";
12
+ import { RollbackProposalUseCase } from "../application/proposals/rollback-proposal.use-case.js";
13
+ import { RoundTableUseCase } from "../application/proposals/round-table.use-case.js";
14
+ import { ShipProposalUseCase } from "../application/proposals/ship-proposal.use-case.js";
15
+ import { StartDeliberationUseCase } from "../application/proposals/start-deliberation.use-case.js";
16
+ import { UpdateProposalUseCase } from "../application/proposals/update-proposal.use-case.js";
1
17
  import { loadConfig } from "../config.js";
2
18
  import { formatAuditTrail } from "../control/audit.js";
3
- import { formatControlResult, runGates } from "../control/gates.js";
4
19
  import { formatAllArtefacts, generateAllArtefacts } from "../delivery/artefacts.js";
5
- import { getUnexecutedDependencies } from "../delivery/dependencies.js";
6
- import { formatDryRun, formatRollback, performDryRun, performRollback } from "../delivery/dry-run.js";
7
- import { executeProposal } from "../delivery/execution.js";
8
- import { formatPlan, generateDeliveryPlan, getPlan } from "../delivery/plans.js";
20
+ import { formatPlan, getPlan } from "../delivery/plans.js";
9
21
  import { formatAgentsTable, initializeAgents, loadAgentDefinitions } from "../governance/agents.js";
10
- import { validateAmendmentPayload } from "../governance/amendments.js";
11
- import { classifyRiskZone, transitionProposal } from "../governance/lifecycle.js";
12
- import { calculateCompositeScore, formatCompositeScore } from "../governance/scoring.js";
13
- import { formatTallyResult, parseVoteFromOutput, tallyVotes } from "../governance/voting.js";
22
+ import { evaluateEditGate, formatEditGate } from "../governance/edit-gate.js";
14
23
  import { computeHealthScore, formatHealthScore, generateDashboard } from "../health-score.js";
15
24
  import { ghBranchNameFor, ghCreateBranch, ghCreatePullRequest, isGitHubEnabled } from "../integrations/github.js";
16
- import { formatRoundTableResults, runRoundTable } from "../intelligence/roundtable.js";
17
- import { buildDispatchInstructions, createDispatchModelContext, dispatchSwarm, formatDispatchPlan, } from "../intelligence/swarm.js";
18
- import { synthesize } from "../intelligence/synthesis.js";
19
- import { addRating, createProposal, createProposalsBatch, getAllAuditLog, getOrCreateState, getProposal, getState, initStorage, recordAudit, saveState, storeCompositeScore, storeDeliberationBatch, storeDeliveryPlan, storeSynthesis, } from "../persistence.js";
20
- import { PROPOSAL_TYPE_LABELS, PROPOSAL_TYPES } from "../types/index.js";
25
+ import { formatRoundTableResults } from "../intelligence/roundtable.js";
26
+ import { buildDispatchInstructions, createDispatchModelContext, formatDispatchPlan } from "../intelligence/swarm.js";
27
+ import { recordProposalExecuted } from "../observability/metrics.js";
28
+ import { getAllAuditLog, getOrCreateState, getProposal, getState, initStorage } from "../persistence.js";
29
+ import { systemClock } from "../ports/clock.js";
30
+ import { presentAmendment, presentControl, presentDeliberation, presentDryRun, presentExecution, presentInitialization, presentProposalCreated, presentProposalUpdated, presentRating, presentRollback, presentShip, } from "../presenters/proposal.presenter.js";
31
+ import { PROPOSAL_TYPES } from "../types/index.js";
21
32
  import { loadGitHubConfigFromDaoRoot, saveGitHubConfigToDaoRoot } from "./github-config.js";
22
33
  import { DAO_ONBOARDING_MESSAGE } from "./messages.js";
23
34
  import { parseSafeJson } from "./utils.js";
24
- function requireInitialized() {
25
- const state = getState();
35
+ function repositoryOrLegacy(repository) {
36
+ return repository ?? new LegacyDaoStateRepository();
37
+ }
38
+ function requireInitialized(repository) {
39
+ const state = repository ? repository.get() : getState();
26
40
  if (!state.initialized)
27
41
  return DAO_ONBOARDING_MESSAGE;
28
42
  return null;
29
43
  }
30
44
  export async function handleDaoSetup(ctx, useDefaults = true) {
31
45
  await initStorage(ctx.workDir);
32
- const state = getOrCreateState(ctx.workDir);
33
- if (state.initialized) {
34
- return `DAO already initialized with ${state.agents.length} agents.`;
35
- }
46
+ if (!ctx.repository)
47
+ getOrCreateState(ctx.workDir);
36
48
  const agents = initializeAgents(useDefaults ? undefined : []);
37
- state.agents = agents;
38
- state.initialized = true;
39
- await saveState();
40
- return `# DAO Initialized\n\n${formatAgentsTable(agents)}\n\nRun \`dao_help\` to discover the workflow, then \`dao_propose\` to create proposals.`;
49
+ const result = await new InitializeDaoUseCase({ repository: repositoryOrLegacy(ctx.repository) }).execute({ agents });
50
+ return presentInitialization(result);
41
51
  }
42
- export async function handleDaoPropose(args) {
43
- const notReady = requireInitialized();
44
- if (notReady)
45
- return notReady;
46
- const proposal = await createProposal(args.title, args.type, args.description, "user", args.context);
47
- if (args.problemStatement !== undefined)
48
- proposal.problemStatement = args.problemStatement;
49
- if (args.acceptanceCriteria !== undefined)
50
- proposal.acceptanceCriteria = args.acceptanceCriteria;
51
- if (args.successMetrics !== undefined)
52
- proposal.successMetrics = args.successMetrics;
53
- if (args.rollbackConditions !== undefined)
54
- proposal.rollbackConditions = args.rollbackConditions;
55
- if (args.affectedPaths !== undefined)
56
- proposal.affectedPaths = args.affectedPaths;
57
- proposal.riskZone = classifyRiskZone(proposal);
58
- await saveState();
59
- await recordAudit(proposal.id, "governance", "proposal_created", "user", `Proposal "${args.title}" created`);
60
- await saveState();
61
- const typeLabel = PROPOSAL_TYPE_LABELS[args.type] ?? args.type;
62
- return `# 📋 Proposal Created — #${proposal.id}\n\n**Title:** ${args.title}\n**Type:** ${typeLabel}\n**Zone:** ${proposal.riskZone}\n\nRun \`dao_deliberate proposalId=${proposal.id}\``;
52
+ export async function handleDaoPropose(args, repository) {
53
+ const useCase = new CreateProposalUseCase({ repository: repositoryOrLegacy(repository), clock: systemClock });
54
+ const result = await useCase.execute({ ...args, proposedBy: "user" });
55
+ if (!result.ok)
56
+ return result.error === "DAO not initialized. Run dao_setup first." ? DAO_ONBOARDING_MESSAGE : result.error;
57
+ return presentProposalCreated(result.proposal);
63
58
  }
64
59
  export async function handleDaoDeliberate(ctx, proposalId) {
65
- const notReady = requireInitialized();
60
+ const notReady = requireInitialized(ctx.repository);
66
61
  if (notReady)
67
62
  return notReady;
68
- const state = getState();
69
- const proposal = getProposal(proposalId);
63
+ const state = repositoryOrLegacy(ctx.repository).get();
64
+ const proposal = state.proposals.find((candidate) => candidate.id === proposalId);
70
65
  if (!proposal)
71
66
  return `Proposal #${proposalId} not found.`;
72
67
  if (proposal.status !== "open")
73
68
  return `Proposal #${proposal.id} is ${proposal.status}, must be open.`;
74
- const transition = transitionProposal(proposal, "deliberate");
75
- if (!transition.success)
76
- return `Cannot deliberate: ${transition.error}`;
77
- await recordAudit(proposal.id, "governance", "deliberation_started", "system", `Deliberation on #${proposal.id}`);
78
- await saveState();
79
69
  const projectConfig = await loadConfig(state.daoRoot);
80
70
  const agents = await loadAgentDefinitions(state.daoRoot, projectConfig);
81
- const modelContext = createDispatchModelContext(state.config.defaultModel, ctx.adapter, {
82
- parentSessionModel: ctx.getSessionModel?.(),
83
- hostDefaultModel: ctx.hostDefaultModel,
84
- });
85
71
  if (ctx.deliberationMode === "manual") {
72
+ const deliberation = await new StartDeliberationUseCase({
73
+ repository: repositoryOrLegacy(ctx.repository),
74
+ clock: systemClock,
75
+ }).execute({ proposalId });
76
+ if (!deliberation.ok)
77
+ return `Cannot deliberate: ${deliberation.error}`;
78
+ const modelContext = createDispatchModelContext(state.config.defaultModel, ctx.adapter, {
79
+ parentSessionModel: ctx.getSessionModel?.(),
80
+ hostDefaultModel: ctx.hostDefaultModel,
81
+ });
86
82
  const instructions = buildDispatchInstructions(proposal, agents, modelContext);
87
- const plan = formatDispatchPlan(proposal, instructions);
83
+ const plan = formatDispatchPlan(proposal, instructions, {
84
+ strategy: projectConfig.deliberation?.strategy,
85
+ charsPerAgent: projectConfig.deliberation?.charsPerAgent,
86
+ });
88
87
  const parentModel = ctx.getSessionModel?.() ?? ctx.hostDefaultModel;
89
88
  const parentNote = parentModel ? `\n\n**Parent session model:** ${parentModel}` : "";
90
89
  return `${plan}${parentNote}`;
91
90
  }
92
91
  const startTime = Date.now();
93
- const outputs = await dispatchSwarm(proposal, agents, ctx.adapter, state.config.maxConcurrent, modelContext, (update) => ctx.onDeliberationProgress?.(update));
94
- const votes = [];
95
- const persistedOutputs = [];
96
- for (const output of outputs) {
97
- if (output.content) {
98
- const vote = parseVoteFromOutput(output.agentId, output.agentName, agents.find((a) => a.id === output.agentId)?.weight ?? 1, output.content);
99
- if (vote) {
100
- vote.weight = agents.find((a) => a.id === output.agentId)?.weight ?? 1;
101
- votes.push(vote);
102
- }
103
- }
104
- persistedOutputs.push(output);
105
- }
106
- if (votes.length > 0 || persistedOutputs.length > 0) {
107
- await storeDeliberationBatch(proposal.id, votes, persistedOutputs);
108
- }
109
- proposal.votes = votes;
110
- const compositeScore = calculateCompositeScore(outputs);
111
- proposal.compositeScore = compositeScore;
112
- await storeCompositeScore(proposal.id, compositeScore);
113
- const tally = tallyVotes(proposal, state.config);
114
- const synthesisText = synthesize(proposal, agents, outputs, tally);
115
- proposal.synthesis = synthesisText;
116
- await storeSynthesis(proposal.id, synthesisText);
117
- if (tally.approved) {
118
- transitionProposal(proposal, "approve");
119
- await recordAudit(proposal.id, "intelligence", "deliberation_approved", "system", `Approved: ${tally.approvalScore}%`);
120
- }
121
- else {
122
- transitionProposal(proposal, "reject");
123
- await recordAudit(proposal.id, "intelligence", "deliberation_rejected", "system", `Rejected: ${tally.approvalScore}%`);
124
- }
125
- await saveState();
92
+ const useCase = new DeliberateProposalUseCase({
93
+ repository: repositoryOrLegacy(ctx.repository),
94
+ worker: ctx.adapter,
95
+ clock: systemClock,
96
+ });
97
+ const result = await useCase.execute({
98
+ proposalId,
99
+ agents,
100
+ strategy: projectConfig.deliberation?.strategy,
101
+ charsPerAgent: projectConfig.deliberation?.charsPerAgent,
102
+ parentSessionModel: ctx.getSessionModel?.(),
103
+ hostDefaultModel: ctx.hostDefaultModel,
104
+ onUpdate: (update) => ctx.onDeliberationProgress?.(update),
105
+ });
106
+ if (!result.ok)
107
+ return `Cannot deliberate: ${result.error}`;
126
108
  const duration = Date.now() - startTime;
127
- return `# 🗳️ Deliberation Complete — #${proposal.id} (${duration}ms)\n\n${formatTallyResult(tally)}\n\n${formatCompositeScore(compositeScore)}\n\n${synthesisText}\n\n> Next: \`${ctx.controlToolName} proposalId=${proposal.id}\``;
109
+ return presentDeliberation(proposal.id, result, { durationMs: duration, controlToolName: ctx.controlToolName });
128
110
  }
129
111
  export async function handleDaoRecordOutputs(ctx, proposalId, outputs) {
130
- const notReady = requireInitialized();
131
- if (notReady)
132
- return notReady;
133
- const state = getState();
134
- const proposal = getProposal(proposalId);
135
- if (!proposal)
136
- return `Proposal #${proposalId} not found.`;
137
- if (proposal.status !== "deliberating")
138
- return `Expected deliberating (current: ${proposal.status})`;
139
- const votes = [];
140
- const enrichedOutputs = [];
141
- for (const raw of outputs) {
142
- const agent = state.agents.find((a) => a.id === raw.agentId);
143
- if (!agent)
144
- continue;
145
- const output = {
146
- agentId: agent.id,
147
- agentName: agent.name,
148
- role: agent.role,
149
- content: raw.content || "",
150
- durationMs: raw.durationMs ?? 0,
151
- error: raw.error,
152
- };
153
- const vote = parseVoteFromOutput(agent.id, agent.name, agent.weight, output.content);
154
- if (vote) {
155
- output.vote = vote;
156
- votes.push(vote);
157
- }
158
- enrichedOutputs.push(output);
159
- }
160
- await storeDeliberationBatch(proposal.id, votes, enrichedOutputs);
161
- proposal.votes = votes;
162
- const compositeScore = calculateCompositeScore(enrichedOutputs);
163
- proposal.compositeScore = compositeScore;
164
- await storeCompositeScore(proposal.id, compositeScore);
165
- const synthesisText = synthesize(proposal, state.agents, enrichedOutputs);
166
- proposal.synthesis = synthesisText;
167
- await storeSynthesis(proposal.id, synthesisText);
168
- const tally = tallyVotes(proposal, state.config);
169
- if (tally.approved) {
170
- transitionProposal(proposal, "approve");
171
- await recordAudit(proposal.id, "intelligence", "deliberation_approved", "system", `Approved: ${tally.approvalScore}%`);
172
- }
173
- else {
174
- transitionProposal(proposal, "reject");
175
- await recordAudit(proposal.id, "intelligence", "deliberation_rejected", "system", `Rejected: ${tally.approvalScore}%`);
176
- }
177
- await saveState();
178
- return `# 🗳️ Deliberation Complete — #${proposal.id}\n\n${formatTallyResult(tally)}\n\n${formatCompositeScore(compositeScore)}\n\n${synthesisText}\n\n> Next: \`${ctx.controlToolName} proposalId=${proposal.id}\``;
112
+ const useCase = new RecordDeliberationOutputsUseCase({
113
+ repository: repositoryOrLegacy(ctx.repository),
114
+ clock: systemClock,
115
+ });
116
+ const result = await useCase.execute({ proposalId, outputs });
117
+ if (!result.ok)
118
+ return result.error;
119
+ return presentDeliberation(proposalId, result, { controlToolName: ctx.controlToolName });
179
120
  }
180
121
  export async function handleDaoControl(ctx, proposalId) {
181
- const notReady = requireInitialized();
122
+ const notReady = requireInitialized(ctx.repository);
182
123
  if (notReady)
183
124
  return notReady;
184
- const state = getState();
185
- const proposal = getProposal(proposalId);
186
- if (!proposal)
187
- return `Proposal #${proposalId} not found.`;
188
- if (proposal.status !== "approved")
189
- return `Must be approved (current: ${proposal.status})`;
190
- const result = runGates(proposal, state.config);
191
- if (result.allGatesPassed) {
192
- transitionProposal(proposal, "control");
193
- await recordAudit(proposal.id, "control", "gates_passed", "system", "All gates passed");
194
- if (!state.deliveryPlans[proposal.id]) {
195
- const plan = generateDeliveryPlan(proposal);
196
- await storeDeliveryPlan(proposal.id, plan);
197
- }
198
- }
199
- else {
200
- if (ctx.failOnGateFailure) {
201
- transitionProposal(proposal, "fail");
202
- }
203
- await recordAudit(proposal.id, "control", "gates_failed", "system", `${result.blockerCount} blockers`);
204
- }
205
- await saveState();
206
- return formatControlResult(result);
125
+ const useCase = new ControlProposalUseCase({ repository: repositoryOrLegacy(ctx.repository), clock: systemClock });
126
+ const result = await useCase.execute({ proposalId, failOnGateFailure: ctx.failOnGateFailure });
127
+ if (!result.ok)
128
+ return result.error;
129
+ return presentControl(result.control);
207
130
  }
208
- export async function handleDaoExecute(proposalId) {
209
- const proposal = getProposal(proposalId);
210
- if (!proposal)
211
- return `Proposal #${proposalId} not found.`;
212
- if (proposal.status !== "controlled") {
213
- return `Must be controlled (current: ${proposal.status}). Run dao_control first.`;
214
- }
215
- const result = await executeProposal(proposal);
216
- await saveState();
217
- await recordAudit(proposal.id, "delivery", "proposal_executed", "user", `Executed #${proposal.id}`);
218
- await saveState();
219
- return result.result;
131
+ export async function handleDaoExecute(ctx, proposalId) {
132
+ const repository = repositoryOrLegacy(ctx.repository);
133
+ const projectConfig = await loadConfig(repository.get().daoRoot);
134
+ const workspace = createExecutionWorkspace(projectConfig.execution, ctx.adapter, ctx.workDir);
135
+ const useCase = new ExecuteProposalUseCase({ repository, clock: systemClock, workspace });
136
+ const result = await useCase.execute({ proposalId, actor: "user" });
137
+ if (!result.ok)
138
+ return result.error;
139
+ recordProposalExecuted(result.proposal.id, result.proposal.type);
140
+ return presentExecution(result);
220
141
  }
221
142
  export async function handleDaoShip(ctx, proposalId, options) {
222
- const notReady = requireInitialized();
143
+ const notReady = requireInitialized(ctx.repository);
223
144
  if (notReady)
224
145
  return notReady;
225
- const state = getState();
226
- const proposal = getProposal(proposalId);
227
- if (!proposal)
228
- return `Proposal #${proposalId} not found.`;
229
- const cascade = options?.cascade === true;
230
- const force = options?.force === true;
231
- const shipped = [];
232
- const shipOne = async (id) => {
233
- const target = getProposal(id);
234
- if (!target)
235
- return `Proposal #${id} not found.`;
236
- if (target.status !== "controlled") {
237
- return `Proposal #${target.id} must be in 'controlled' state to ship (current: ${target.status})`;
238
- }
239
- const result = await executeProposal(target);
240
- if (!result.success)
241
- return result.result;
242
- await recordAudit(target.id, "delivery", "proposal-shipped", ctx.adapter.hostId, "shipped via dao_ship");
243
- return null;
244
- };
245
- if (!force) {
246
- const depsResolution = getUnexecutedDependencies(proposal.id, state.proposals);
247
- if (depsResolution.error)
248
- return depsResolution.error;
249
- const pendingDeps = depsResolution.order ?? [];
250
- if (pendingDeps.length > 0 && !cascade) {
251
- const lines = pendingDeps.map((depId) => {
252
- const dep = getProposal(depId);
253
- return dep ? `- #${dep.id} [${dep.status}] ${dep.title}` : `- #${depId} [missing]`;
254
- });
255
- return `Cannot ship proposal #${proposal.id}: unexecuted dependencies found.\n\n${lines.join("\n")}\n\nRetry with \`dao_ship proposalId=${proposal.id} cascade=true\` or \`force=true\`.`;
256
- }
257
- if (cascade && pendingDeps.length > 0) {
258
- const notControlled = pendingDeps.filter((depId) => getProposal(depId)?.status !== "controlled");
259
- if (notControlled.length > 0) {
260
- const details = notControlled
261
- .map((depId) => {
262
- const dep = getProposal(depId);
263
- return dep ? `#${dep.id} (${dep.status})` : `#${depId} (missing)`;
264
- })
265
- .join(", ");
266
- return `Cannot cascade ship: dependencies not in 'controlled' state: ${details}`;
267
- }
268
- for (const depId of pendingDeps) {
269
- const dep = getProposal(depId);
270
- if (!dep || dep.status === "executed")
271
- continue;
272
- const depError = await shipOne(depId);
273
- if (depError)
274
- return depError;
275
- shipped.push(depId);
276
- }
277
- }
146
+ const repository = repositoryOrLegacy(ctx.repository);
147
+ // Shipping executes controlled proposals, so it must honour the same
148
+ // execution isolation as dao_execute — otherwise host shipping would
149
+ // bypass a configured worktree.
150
+ const projectConfig = await loadConfig(repository.get().daoRoot);
151
+ const workspace = createExecutionWorkspace(projectConfig.execution, ctx.adapter, ctx.workDir);
152
+ const useCase = new ShipProposalUseCase({ repository, clock: systemClock, workspace });
153
+ const result = await useCase.execute({
154
+ proposalId,
155
+ actor: ctx.adapter.hostId,
156
+ cascade: options?.cascade,
157
+ force: options?.force,
158
+ });
159
+ if (!result.ok)
160
+ return result.error;
161
+ for (const id of result.shipped) {
162
+ const proposal = repositoryOrLegacy(ctx.repository)
163
+ .get()
164
+ .proposals.find((candidate) => candidate.id === id);
165
+ if (proposal)
166
+ recordProposalExecuted(proposal.id, proposal.type);
278
167
  }
279
- const targetError = await shipOne(proposal.id);
280
- if (targetError)
281
- return targetError;
282
- shipped.push(proposal.id);
283
- await saveState();
284
- const summary = shipped.map((id) => `- #${id}`).join("\n");
285
- return `# 🚀 Ship Complete\n\nShipped proposals:\n${summary}`;
168
+ return presentShip(result);
169
+ }
170
+ export async function handleDaoCheckEdit(ctx, paths) {
171
+ const repository = repositoryOrLegacy(ctx.repository);
172
+ const notReady = requireInitialized(ctx.repository);
173
+ if (notReady)
174
+ return notReady;
175
+ const cleaned = [...new Set(paths.map((path) => path.trim()).filter(Boolean))];
176
+ // Refuse oversized requests outright: silently truncating could let a
177
+ // protected file ride just past the cutoff and come back as allowed.
178
+ if (cleaned.length > 200) {
179
+ return `Too many paths provided (${cleaned.length}). Pass at most 200 paths per edit check.`;
180
+ }
181
+ if (cleaned.length === 0)
182
+ return "No paths provided. Pass the files you are about to edit.";
183
+ const state = repository.get();
184
+ const projectConfig = await loadConfig(state.daoRoot);
185
+ const decision = evaluateEditGate({
186
+ paths: cleaned,
187
+ mode: projectConfig.mode,
188
+ criticalPaths: projectConfig.criticalPaths ?? [],
189
+ approved: state.proposals.map((proposal) => ({
190
+ proposalId: proposal.id,
191
+ affectedPaths: proposal.affectedPaths,
192
+ status: proposal.status,
193
+ })),
194
+ });
195
+ return formatEditGate(decision);
286
196
  }
287
197
  export async function handleDaoList() {
288
198
  const notReady = requireInitialized();
@@ -334,109 +244,71 @@ export async function handleDaoArtefacts(proposalId) {
334
244
  return `Proposal #${proposalId} not found.`;
335
245
  return formatAllArtefacts(generateAllArtefacts(proposal));
336
246
  }
337
- export async function handleDaoDryRun(proposalId) {
338
- const proposal = getProposal(proposalId);
339
- if (!proposal)
340
- return `Proposal #${proposalId} not found.`;
341
- const result = await performDryRun(proposal);
342
- proposal.dryRunAt = new Date().toISOString();
343
- proposal.dryRunCanProceed = result.canProceed;
344
- await saveState();
345
- return formatDryRun(result);
247
+ export async function handleDaoDryRun(proposalId, repository) {
248
+ const result = await new DryRunProposalUseCase({
249
+ repository: repositoryOrLegacy(repository),
250
+ clock: systemClock,
251
+ }).execute({ proposalId });
252
+ return result.ok ? presentDryRun(result.analysis) : result.error;
346
253
  }
347
- export async function handleDaoRollback(proposalId) {
348
- return formatRollback(await performRollback(proposalId));
254
+ export async function handleDaoRollback(proposalId, repository) {
255
+ const result = await new RollbackProposalUseCase({ repository: repositoryOrLegacy(repository) }).execute({
256
+ proposalId,
257
+ });
258
+ return presentRollback(result);
349
259
  }
350
- export async function handleDaoDashboard() {
351
- const notReady = requireInitialized();
260
+ export async function handleDaoDashboard(repository) {
261
+ const notReady = requireInitialized(repository);
352
262
  if (notReady)
353
263
  return notReady;
354
- const state = getState();
264
+ const state = repositoryOrLegacy(repository).get();
355
265
  const dashboard = generateDashboard(state.proposals, state.outcomes, state.agents, state.healthSnapshots);
356
266
  const health = computeHealthScore(state.proposals, state.outcomes, state.config.healthWeights);
357
267
  return `${dashboard}\n\n${formatHealthScore(health)}`;
358
268
  }
359
269
  export async function handleDaoRoundtable(ctx) {
360
- const notReady = requireInitialized();
270
+ const notReady = requireInitialized(ctx.repository);
361
271
  if (notReady)
362
272
  return notReady;
363
273
  const state = getState();
364
274
  const projectConfig = await loadConfig(state.daoRoot);
365
275
  const agents = await loadAgentDefinitions(state.daoRoot, projectConfig);
366
- const modelContext = createDispatchModelContext(state.config.defaultModel, ctx.adapter, {
276
+ const result = await new RoundTableUseCase({
277
+ repository: repositoryOrLegacy(ctx.repository),
278
+ worker: ctx.adapter,
279
+ clock: systemClock,
280
+ }).execute({
281
+ agents,
367
282
  parentSessionModel: ctx.getSessionModel?.(),
368
283
  hostDefaultModel: ctx.hostDefaultModel,
369
284
  });
370
- const suggestions = await runRoundTable(ctx.adapter, agents, state.config.maxConcurrent, modelContext);
371
- const proposalIds = new Map();
372
- const parsedSuggestions = suggestions
373
- .map((suggestion) => ({ suggestion, parsed: suggestion.parsed }))
374
- .filter((entry) => Boolean(entry.parsed));
375
- try {
376
- const proposals = await createProposalsBatch(parsedSuggestions.map(({ suggestion, parsed }) => ({
377
- title: parsed.title,
378
- type: parsed.type,
379
- description: parsed.description,
380
- proposedBy: suggestion.agentId,
381
- })));
382
- for (const [index, { suggestion }] of parsedSuggestions.entries()) {
383
- const proposal = proposals[index];
384
- if (!proposal)
385
- continue;
386
- proposal.riskZone = classifyRiskZone(proposal);
387
- suggestion.proposalId = proposal.id;
388
- proposalIds.set(suggestion.agentId, proposal.id);
389
- await recordAudit(proposal.id, "intelligence", "roundtable_proposal_created", suggestion.agentId, "Auto-created from round table");
390
- }
391
- }
392
- catch (error) {
393
- const message = error instanceof Error ? error.message : String(error);
394
- for (const { suggestion } of parsedSuggestions) {
395
- suggestion.error = `Failed to create proposal: ${message}`;
396
- }
397
- }
398
- await saveState();
399
- return formatRoundTableResults(suggestions, proposalIds);
285
+ return result.ok ? formatRoundTableResults(result.suggestions, result.proposalIds) : result.error;
400
286
  }
401
287
  export async function handleDaoAudit(proposalId) {
402
288
  const entries = proposalId ? getAllAuditLog().filter((e) => e.proposalId === proposalId) : getAllAuditLog();
403
289
  return formatAuditTrail(entries, proposalId);
404
290
  }
405
- export async function handleDaoRate(proposalId, score, comment) {
406
- const proposal = getProposal(proposalId);
407
- if (!proposal)
408
- return `Proposal #${proposalId} not found.`;
409
- if (proposal.status !== "executed")
410
- return `Proposal #${proposal.id} is ${proposal.status}, must be executed.`;
411
- await addRating(proposal.id, {
412
- proposalId: proposal.id,
291
+ export async function handleDaoRate(proposalId, score, comment, repository) {
292
+ const result = await new RateProposalUseCase({
293
+ repository: repositoryOrLegacy(repository),
294
+ clock: systemClock,
295
+ }).execute({
296
+ proposalId,
413
297
  rater: "user",
414
298
  score,
415
299
  comment,
416
- ratedAt: new Date().toISOString(),
417
300
  });
418
- await saveState();
419
- return `# ⭐ Rating Recorded — #${proposal.id}\n\n**Score:** ${score}/5\n**Comment:** ${comment}`;
301
+ return result.ok ? presentRating(result.rating) : result.error;
420
302
  }
421
- export async function handleDaoUpdateProposal(proposalId, fields) {
422
- const proposal = getProposal(proposalId);
423
- if (!proposal)
424
- return `Proposal #${proposalId} not found.`;
425
- if (proposal.status !== "open")
426
- return `Must be open (current: ${proposal.status})`;
427
- if (fields.problemStatement !== undefined)
428
- proposal.problemStatement = fields.problemStatement;
429
- if (fields.acceptanceCriteria !== undefined)
430
- proposal.acceptanceCriteria = fields.acceptanceCriteria;
431
- if (fields.successMetrics !== undefined)
432
- proposal.successMetrics = fields.successMetrics;
433
- if (fields.rollbackConditions !== undefined)
434
- proposal.rollbackConditions = fields.rollbackConditions;
435
- await saveState();
436
- return `# 📝 Proposal Updated — #${proposal.id}\n\nUpdated fields applied.`;
303
+ export async function handleDaoUpdateProposal(proposalId, fields, repository) {
304
+ const result = await new UpdateProposalUseCase({ repository: repositoryOrLegacy(repository) }).execute({
305
+ proposalId,
306
+ fields,
307
+ });
308
+ return result.ok ? presentProposalUpdated(result.proposal) : result.error;
437
309
  }
438
- export async function handleDaoProposeAmendment(args) {
439
- const notReady = requireInitialized();
310
+ export async function handleDaoProposeAmendment(args, repository) {
311
+ const notReady = requireInitialized(repository);
440
312
  if (notReady)
441
313
  return notReady;
442
314
  let payload;
@@ -483,21 +355,16 @@ export async function handleDaoProposeAmendment(args) {
483
355
  }
484
356
  if (!payload)
485
357
  return "Error: amendment payload could not be constructed";
486
- const validation = validateAmendmentPayload(payload);
487
- if (!validation.valid)
488
- return `❌ Validation failed:\n${validation.errors.join("\n")}`;
489
- const proposal = await createProposal(args.title, "governance-change", args.description, "user");
490
- proposal.amendmentPayload = payload;
491
- proposal.amendmentOrigin = { source: "human" };
492
- proposal.amendmentState = "pending-vote";
493
- proposal.riskZone = classifyRiskZone(proposal);
494
- await saveState();
495
- await recordAudit(proposal.id, "governance", "amendment_proposed", "user", `Amendment: ${payload.type}`);
496
- await saveState();
497
- return `# 📜 Amendment Proposed — #${proposal.id}\n\nType: ${payload.type}\n\nRun \`dao_deliberate proposalId=${proposal.id}\``;
358
+ const result = await new CreateAmendmentProposalUseCase({
359
+ repository: repositoryOrLegacy(repository),
360
+ clock: systemClock,
361
+ }).execute({ title: args.title, description: args.description, payload, proposedBy: "user" });
362
+ if (!result.ok)
363
+ return `❌ ${result.error}`;
364
+ return presentAmendment(result);
498
365
  }
499
- export async function handleDaoConfigGithub(_ctx, args) {
500
- const state = getState();
366
+ export async function handleDaoConfigGithub(ctx, args) {
367
+ const state = repositoryOrLegacy(ctx.repository).get();
501
368
  await saveGitHubConfigToDaoRoot(state.daoRoot, args);
502
369
  return [
503
370
  `# GitHub Configured`,
@@ -509,14 +376,15 @@ export async function handleDaoConfigGithub(_ctx, args) {
509
376
  "Available: `dao_github_create_branch`, `dao_github_open_pr`",
510
377
  ].join("\n");
511
378
  }
512
- export async function handleDaoGithubCreateBranch(_ctx, proposalId) {
513
- const notReady = requireInitialized();
379
+ export async function handleDaoGithubCreateBranch(ctx, proposalId) {
380
+ const repository = repositoryOrLegacy(ctx.repository);
381
+ const notReady = requireInitialized(ctx.repository);
514
382
  if (notReady)
515
383
  return notReady;
516
- const proposal = getProposal(proposalId);
384
+ const proposal = repository.get().proposals.find((candidate) => candidate.id === proposalId);
517
385
  if (!proposal)
518
386
  return `Proposal #${proposalId} not found.`;
519
- const configured = await loadGitHubConfigFromDaoRoot(getState().daoRoot);
387
+ const configured = await loadGitHubConfigFromDaoRoot(repository.get().daoRoot);
520
388
  if (!configured || !isGitHubEnabled()) {
521
389
  return "GitHub not configured. Run `dao_config_github` with token, owner, and repo.";
522
390
  }
@@ -526,16 +394,17 @@ export async function handleDaoGithubCreateBranch(_ctx, proposalId) {
526
394
  return "Failed to create branch (GitHub API returned null)";
527
395
  return `# Branch Created\n\n**Branch:** ${branchName}\n**SHA:** ${result.sha.slice(0, 7)}`;
528
396
  }
529
- export async function handleDaoGithubOpenPr(_ctx, proposalId, headBranch) {
530
- const notReady = requireInitialized();
397
+ export async function handleDaoGithubOpenPr(ctx, proposalId, headBranch) {
398
+ const repository = repositoryOrLegacy(ctx.repository);
399
+ const notReady = requireInitialized(ctx.repository);
531
400
  if (notReady)
532
401
  return notReady;
533
- const proposal = getProposal(proposalId);
402
+ const proposal = repository.get().proposals.find((candidate) => candidate.id === proposalId);
534
403
  if (!proposal)
535
404
  return `Proposal #${proposalId} not found.`;
536
405
  if (!headBranch)
537
406
  return "headBranch is required";
538
- const configured = await loadGitHubConfigFromDaoRoot(getState().daoRoot);
407
+ const configured = await loadGitHubConfigFromDaoRoot(repository.get().daoRoot);
539
408
  if (!configured || !isGitHubEnabled()) {
540
409
  return "GitHub not configured. Run `dao_config_github` with token, owner, and repo.";
541
410
  }