@guyghost/swarm-dao-core 0.4.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 (260) 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/registry.d.ts.map +1 -1
  90. package/dist/commands/registry.js +18 -3
  91. package/dist/commands/registry.js.map +1 -1
  92. package/dist/config.d.ts +17 -0
  93. package/dist/config.d.ts.map +1 -1
  94. package/dist/config.js +9 -1
  95. package/dist/config.js.map +1 -1
  96. package/dist/control/gates.d.ts +4 -1
  97. package/dist/control/gates.d.ts.map +1 -1
  98. package/dist/control/gates.js +5 -10
  99. package/dist/control/gates.js.map +1 -1
  100. package/dist/delivery/dry-run.d.ts.map +1 -1
  101. package/dist/delivery/dry-run.js +3 -44
  102. package/dist/delivery/dry-run.js.map +1 -1
  103. package/dist/delivery/execution-isolation.d.ts +34 -0
  104. package/dist/delivery/execution-isolation.d.ts.map +1 -0
  105. package/dist/delivery/execution-isolation.js +97 -0
  106. package/dist/delivery/execution-isolation.js.map +1 -0
  107. package/dist/delivery/index.d.ts +1 -0
  108. package/dist/delivery/index.d.ts.map +1 -1
  109. package/dist/delivery/index.js +1 -0
  110. package/dist/delivery/index.js.map +1 -1
  111. package/dist/delivery/plans.d.ts +3 -1
  112. package/dist/delivery/plans.d.ts.map +1 -1
  113. package/dist/delivery/plans.js +2 -2
  114. package/dist/delivery/plans.js.map +1 -1
  115. package/dist/domain/dry-run.d.ts +3 -0
  116. package/dist/domain/dry-run.d.ts.map +1 -0
  117. package/dist/domain/dry-run.js +28 -0
  118. package/dist/domain/dry-run.js.map +1 -0
  119. package/dist/domain/index.d.ts +6 -0
  120. package/dist/domain/index.d.ts.map +1 -0
  121. package/dist/domain/index.js +7 -0
  122. package/dist/domain/index.js.map +1 -0
  123. package/dist/governance/agents.d.ts.map +1 -1
  124. package/dist/governance/agents.js +107 -169
  125. package/dist/governance/agents.js.map +1 -1
  126. package/dist/governance/charter.d.ts +14 -0
  127. package/dist/governance/charter.d.ts.map +1 -0
  128. package/dist/governance/charter.js +65 -0
  129. package/dist/governance/charter.js.map +1 -0
  130. package/dist/governance/edit-gate.d.ts +47 -0
  131. package/dist/governance/edit-gate.d.ts.map +1 -0
  132. package/dist/governance/edit-gate.js +156 -0
  133. package/dist/governance/edit-gate.js.map +1 -0
  134. package/dist/governance/index.d.ts +1 -0
  135. package/dist/governance/index.d.ts.map +1 -1
  136. package/dist/governance/index.js +1 -0
  137. package/dist/governance/index.js.map +1 -1
  138. package/dist/governance/proposal.machine.d.ts +2 -114
  139. package/dist/governance/proposal.machine.d.ts.map +1 -1
  140. package/dist/governance/proposal.machine.js +2 -180
  141. package/dist/governance/proposal.machine.js.map +1 -1
  142. package/dist/governance/proposal.utils.d.ts +5 -2
  143. package/dist/governance/proposal.utils.d.ts.map +1 -1
  144. package/dist/governance/proposal.utils.js +7 -4
  145. package/dist/governance/proposal.utils.js.map +1 -1
  146. package/dist/governance/voting.d.ts.map +1 -1
  147. package/dist/governance/voting.js +24 -14
  148. package/dist/governance/voting.js.map +1 -1
  149. package/dist/host-tools/github-config.d.ts.map +1 -1
  150. package/dist/host-tools/github-config.js +17 -5
  151. package/dist/host-tools/github-config.js.map +1 -1
  152. package/dist/host-tools/handlers.d.ts +14 -11
  153. package/dist/host-tools/handlers.d.ts.map +1 -1
  154. package/dist/host-tools/handlers.js +204 -343
  155. package/dist/host-tools/handlers.js.map +1 -1
  156. package/dist/index.d.ts +5 -0
  157. package/dist/index.d.ts.map +1 -1
  158. package/dist/index.js +10 -0
  159. package/dist/index.js.map +1 -1
  160. package/dist/integrations/github.d.ts.map +1 -1
  161. package/dist/integrations/github.js +5 -2
  162. package/dist/integrations/github.js.map +1 -1
  163. package/dist/intelligence/delegation.d.ts +3 -2
  164. package/dist/intelligence/delegation.d.ts.map +1 -1
  165. package/dist/intelligence/delegation.js.map +1 -1
  166. package/dist/intelligence/index.d.ts +1 -0
  167. package/dist/intelligence/index.d.ts.map +1 -1
  168. package/dist/intelligence/index.js +1 -0
  169. package/dist/intelligence/index.js.map +1 -1
  170. package/dist/intelligence/roundtable.d.ts +4 -2
  171. package/dist/intelligence/roundtable.d.ts.map +1 -1
  172. package/dist/intelligence/roundtable.js +2 -2
  173. package/dist/intelligence/roundtable.js.map +1 -1
  174. package/dist/intelligence/sequential.d.ts +36 -0
  175. package/dist/intelligence/sequential.d.ts.map +1 -0
  176. package/dist/intelligence/sequential.js +91 -0
  177. package/dist/intelligence/sequential.js.map +1 -0
  178. package/dist/intelligence/swarm.d.ts +8 -4
  179. package/dist/intelligence/swarm.d.ts.map +1 -1
  180. package/dist/intelligence/swarm.js +10 -3
  181. package/dist/intelligence/swarm.js.map +1 -1
  182. package/dist/intelligence/synthesis.d.ts.map +1 -1
  183. package/dist/intelligence/synthesis.js +16 -4
  184. package/dist/intelligence/synthesis.js.map +1 -1
  185. package/dist/models/graph-engineering.machine.d.ts +219 -0
  186. package/dist/models/graph-engineering.machine.d.ts.map +1 -0
  187. package/dist/models/graph-engineering.machine.js +214 -0
  188. package/dist/models/graph-engineering.machine.js.map +1 -0
  189. package/dist/models/improvement-loop.machine.d.ts +239 -0
  190. package/dist/models/improvement-loop.machine.d.ts.map +1 -0
  191. package/dist/models/improvement-loop.machine.js +254 -0
  192. package/dist/models/improvement-loop.machine.js.map +1 -0
  193. package/dist/models/index.d.ts +5 -0
  194. package/dist/models/index.d.ts.map +1 -0
  195. package/dist/models/index.js +5 -0
  196. package/dist/models/index.js.map +1 -0
  197. package/dist/models/product-loop.machine.d.ts +531 -0
  198. package/dist/models/product-loop.machine.d.ts.map +1 -0
  199. package/dist/models/product-loop.machine.js +699 -0
  200. package/dist/models/product-loop.machine.js.map +1 -0
  201. package/dist/models/proposal.machine.d.ts +82 -0
  202. package/dist/models/proposal.machine.d.ts.map +1 -0
  203. package/dist/models/proposal.machine.js +68 -0
  204. package/dist/models/proposal.machine.js.map +1 -0
  205. package/dist/observability/attention.d.ts +40 -0
  206. package/dist/observability/attention.d.ts.map +1 -0
  207. package/dist/observability/attention.js +119 -0
  208. package/dist/observability/attention.js.map +1 -0
  209. package/dist/observability/index.d.ts +1 -0
  210. package/dist/observability/index.d.ts.map +1 -1
  211. package/dist/observability/index.js +1 -0
  212. package/dist/observability/index.js.map +1 -1
  213. package/dist/observability/logging.d.ts +6 -0
  214. package/dist/observability/logging.d.ts.map +1 -1
  215. package/dist/observability/logging.js +36 -6
  216. package/dist/observability/logging.js.map +1 -1
  217. package/dist/observability/metrics.d.ts +7 -0
  218. package/dist/observability/metrics.d.ts.map +1 -1
  219. package/dist/observability/metrics.js +179 -43
  220. package/dist/observability/metrics.js.map +1 -1
  221. package/dist/persistence.d.ts +3 -0
  222. package/dist/persistence.d.ts.map +1 -1
  223. package/dist/persistence.js +88 -17
  224. package/dist/persistence.js.map +1 -1
  225. package/dist/ports/clock.d.ts +7 -0
  226. package/dist/ports/clock.d.ts.map +1 -0
  227. package/dist/ports/clock.js +5 -0
  228. package/dist/ports/clock.js.map +1 -0
  229. package/dist/ports/host.d.ts +8 -0
  230. package/dist/ports/host.d.ts.map +1 -0
  231. package/dist/ports/host.js +2 -0
  232. package/dist/ports/host.js.map +1 -0
  233. package/dist/ports/index.d.ts +5 -0
  234. package/dist/ports/index.d.ts.map +1 -0
  235. package/dist/ports/index.js +5 -0
  236. package/dist/ports/index.js.map +1 -0
  237. package/dist/ports/repository.d.ts +7 -0
  238. package/dist/ports/repository.d.ts.map +1 -0
  239. package/dist/ports/repository.js +2 -0
  240. package/dist/ports/repository.js.map +1 -0
  241. package/dist/ports/workspace.d.ts +14 -0
  242. package/dist/ports/workspace.d.ts.map +1 -0
  243. package/dist/ports/workspace.js +14 -0
  244. package/dist/ports/workspace.js.map +1 -0
  245. package/dist/presenters/index.d.ts +2 -0
  246. package/dist/presenters/index.d.ts.map +1 -0
  247. package/dist/presenters/index.js +2 -0
  248. package/dist/presenters/index.js.map +1 -0
  249. package/dist/presenters/proposal.presenter.d.ts +30 -0
  250. package/dist/presenters/proposal.presenter.d.ts.map +1 -0
  251. package/dist/presenters/proposal.presenter.js +47 -0
  252. package/dist/presenters/proposal.presenter.js.map +1 -0
  253. package/dist/utils/host.d.ts.map +1 -1
  254. package/dist/utils/host.js +77 -6
  255. package/dist/utils/host.js.map +1 -1
  256. package/dist/utils/security.d.ts +7 -1
  257. package/dist/utils/security.d.ts.map +1 -1
  258. package/dist/utils/security.js +18 -2
  259. package/dist/utils/security.js.map +1 -1
  260. package/package.json +13 -1
@@ -0,0 +1,156 @@
1
+ // ============================================================
2
+ // Swarm DAO Core — Edit Gate (mode-based path governance)
3
+ // ============================================================
4
+ // Wires the `mode` and `criticalPaths` configuration into a deterministic
5
+ // pre-edit decision agents can consult before touching the repository:
6
+ //
7
+ // - opt-in (default): everything is allowed; critical paths are flagged
8
+ // informationally.
9
+ // - suggest: everything is allowed; uncovered critical paths produce a
10
+ // non-blocking nudge toward the proposal workflow.
11
+ // - enforce: critical paths are only editable when an approved,
12
+ // controlled, or executed proposal declares them in affectedPaths.
13
+ //
14
+ // Pure: no I/O, no clock, no host SDK. The host handler feeds it the
15
+ // project config and the approved proposals; the model decides.
16
+ import { isCriticalPath } from "../config.js";
17
+ const AUTHORITY_STATUSES = new Set(["approved", "controlled", "executed"]);
18
+ /**
19
+ * Lexically normalize a repository-relative path so glob matching cannot be
20
+ * evaded by spelling variants (absolute paths, `./` prefixes, `a/../b`
21
+ * segments, duplicate slashes). Fail closed: anything that cannot be
22
+ * normalized to a deterministic in-repo path is refused, never allowed.
23
+ */
24
+ export function normalizeEditPath(raw) {
25
+ if (raw.length === 0)
26
+ return { ok: false, reason: "empty path" };
27
+ if (raw.startsWith("/") || /^[A-Za-z]:[\\/]/.test(raw)) {
28
+ return { ok: false, reason: "absolute paths are not supported — pass repository-relative paths" };
29
+ }
30
+ if (raw.includes("\\")) {
31
+ return { ok: false, reason: "backslashes are not supported — use forward slashes" };
32
+ }
33
+ const segments = [];
34
+ for (const segment of raw.split("/")) {
35
+ if (segment.length === 0 || segment === ".")
36
+ continue;
37
+ if (segment === "..") {
38
+ if (segments.length === 0) {
39
+ return { ok: false, reason: "path escapes the repository root" };
40
+ }
41
+ segments.pop();
42
+ continue;
43
+ }
44
+ segments.push(segment);
45
+ }
46
+ if (segments.length === 0)
47
+ return { ok: false, reason: "path normalizes to the repository root" };
48
+ return { ok: true, path: segments.join("/") };
49
+ }
50
+ const isAuthority = (approval) => AUTHORITY_STATUSES.has(approval.status) && Boolean(approval.affectedPaths?.length);
51
+ export function evaluateEditGate(input) {
52
+ // Fail open on unknown modes, consistent with canEditWithoutProposal():
53
+ // only an explicit "enforce" ever blocks. loadConfig merges unvalidated
54
+ // JSON, so a typo in .dao/config.json must not lock the repository.
55
+ const mode = input.mode === "enforce" || input.mode === "suggest" ? input.mode : "opt-in";
56
+ const authorities = input.approved.filter(isAuthority);
57
+ const seen = new Set();
58
+ const verdicts = [];
59
+ for (const raw of input.paths) {
60
+ const trimmed = raw.trim();
61
+ if (trimmed.length === 0)
62
+ continue;
63
+ // Unmatchable spellings are refused in every mode — a path the gate
64
+ // cannot normalize must never come back as allowed.
65
+ const normalized = normalizeEditPath(trimmed);
66
+ if (!normalized.ok) {
67
+ verdicts.push({
68
+ path: trimmed,
69
+ critical: false,
70
+ allowed: false,
71
+ reason: `unmatchable path: ${normalized.reason}`,
72
+ });
73
+ continue;
74
+ }
75
+ const path = normalized.path;
76
+ if (seen.has(path))
77
+ continue;
78
+ seen.add(path);
79
+ const critical = isCriticalPath(path, [...input.criticalPaths]);
80
+ const covering = critical
81
+ ? authorities.find((approval) => isCriticalPath(path, approval.affectedPaths ?? []))
82
+ : undefined;
83
+ if (!critical) {
84
+ verdicts.push({ path, critical, allowed: true, reason: "not a critical path" });
85
+ continue;
86
+ }
87
+ if (mode === "opt-in") {
88
+ verdicts.push({
89
+ path,
90
+ critical,
91
+ allowed: true,
92
+ reason: covering
93
+ ? `critical path, covered by approved proposal #${covering.proposalId}`
94
+ : "critical path (mode is opt-in: edits allowed, proposal optional)",
95
+ });
96
+ continue;
97
+ }
98
+ if (mode === "suggest") {
99
+ verdicts.push({
100
+ path,
101
+ critical,
102
+ allowed: true,
103
+ reason: covering
104
+ ? `critical path, covered by approved proposal #${covering.proposalId}`
105
+ : "critical path — consider governing this change with a proposal",
106
+ ...(covering ? { coveredByProposalId: covering.proposalId } : {}),
107
+ });
108
+ continue;
109
+ }
110
+ // enforce
111
+ if (covering) {
112
+ verdicts.push({
113
+ path,
114
+ critical,
115
+ allowed: true,
116
+ reason: `critical path covered by approved proposal #${covering.proposalId}`,
117
+ coveredByProposalId: covering.proposalId,
118
+ });
119
+ }
120
+ else {
121
+ verdicts.push({
122
+ path,
123
+ critical,
124
+ allowed: false,
125
+ reason: "enforce mode: critical path without an approved proposal",
126
+ });
127
+ }
128
+ }
129
+ const denied = verdicts.filter((verdict) => !verdict.allowed);
130
+ const uncoveredCritical = verdicts.filter((verdict) => verdict.critical && !verdict.coveredByProposalId);
131
+ let guidance = null;
132
+ if (mode === "suggest" && uncoveredCritical.length > 0) {
133
+ guidance =
134
+ "Suggestion: create a proposal (`dao_propose`) covering these critical paths and deliberate it before proceeding.";
135
+ }
136
+ else if (mode === "enforce" && denied.length > 0) {
137
+ guidance =
138
+ "Blocked by enforce mode: create a proposal (`dao_propose`) with these paths in affectedPaths, deliberate, and get it approved before editing.";
139
+ }
140
+ return { mode, allowed: denied.length === 0, verdicts, guidance };
141
+ }
142
+ /** Human-readable rendering; pure formatting. */
143
+ export function formatEditGate(decision) {
144
+ const header = decision.allowed ? "# ✅ Edit Gate — Allowed" : `# 🛑 Edit Gate — Blocked (${decision.mode} mode)`;
145
+ const rows = decision.verdicts
146
+ .map((verdict) => {
147
+ const flag = verdict.allowed ? "✅" : "❌";
148
+ const critical = verdict.critical ? " [critical]" : "";
149
+ const covered = verdict.coveredByProposalId ? ` (covered by #${verdict.coveredByProposalId})` : "";
150
+ return `- ${flag} \`${verdict.path}\`${critical}${covered} — ${verdict.reason}`;
151
+ })
152
+ .join("\n");
153
+ const guidance = decision.guidance ? `\n\n${decision.guidance}` : "";
154
+ return `${header}\n\nMode: **${decision.mode}**\n\n${rows}${guidance}`;
155
+ }
156
+ //# sourceMappingURL=edit-gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit-gate.js","sourceRoot":"","sources":["../../src/governance/edit-gate.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ export * from "./agents.js";
2
2
  export * from "./amendments.js";
3
3
  export * from "./delegation.machine.js";
4
4
  export * from "./delegation.utils.js";
5
+ export * from "./edit-gate.js";
5
6
  export * from "./lifecycle.js";
6
7
  export * from "./proposal.machine.js";
7
8
  export * from "./proposal.utils.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/governance/index.ts"],"names":[],"mappings":"AACA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/governance/index.ts"],"names":[],"mappings":"AACA,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC"}
@@ -3,6 +3,7 @@ export * from "./agents.js";
3
3
  export * from "./amendments.js";
4
4
  export * from "./delegation.machine.js";
5
5
  export * from "./delegation.utils.js";
6
+ export * from "./edit-gate.js";
6
7
  export * from "./lifecycle.js";
7
8
  export * from "./proposal.machine.js";
8
9
  export * from "./proposal.utils.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/governance/index.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/governance/index.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC"}
@@ -1,115 +1,3 @@
1
- import type { ControlCheckResult, Proposal, ProposalStatus, TallyResult } from "../types/index.js";
2
- export interface ProposalContext {
3
- proposal: Proposal;
4
- errorMessage?: string;
5
- lastTransitionTime: string;
6
- }
7
- export interface ProposalMachineInput {
8
- proposal: Proposal;
9
- lastTransitionTime?: string;
10
- }
11
- export type ProposalEvent = {
12
- type: "DELIBERATE";
13
- } | {
14
- type: "APPROVE";
15
- tally: TallyResult;
16
- } | {
17
- type: "REJECT";
18
- } | {
19
- type: "CONTROL_PASS";
20
- result: ControlCheckResult;
21
- } | {
22
- type: "CONTROL_FAIL";
23
- } | {
24
- type: "EXECUTE_SUCCESS";
25
- } | {
26
- type: "FAIL";
27
- } | {
28
- type: "DISCARD";
29
- } | {
30
- type: "ERROR";
31
- message: string;
32
- };
33
- export declare const PROPOSAL_FINAL_STATUSES: ReadonlySet<ProposalStatus>;
34
- export declare function isProposalFinal(status: ProposalStatus): boolean;
35
- declare function buildProposalMachine(initial: ProposalStatus): import("xstate").StateMachine<ProposalContext, {
36
- type: "DELIBERATE";
37
- } | {
38
- type: "APPROVE";
39
- tally: TallyResult;
40
- } | {
41
- type: "REJECT";
42
- } | {
43
- type: "CONTROL_PASS";
44
- result: ControlCheckResult;
45
- } | {
46
- type: "CONTROL_FAIL";
47
- } | {
48
- type: "EXECUTE_SUCCESS";
49
- } | {
50
- type: "FAIL";
51
- } | {
52
- type: "DISCARD";
53
- } | {
54
- type: "ERROR";
55
- message: string;
56
- }, {}, never, never, {
57
- type: "tallyApproved";
58
- params: unknown;
59
- } | {
60
- type: "gatesPassed";
61
- params: unknown;
62
- }, never, "open" | "deliberating" | "approved" | "controlled" | "rejected" | "executed" | "failed", string, ProposalMachineInput, import("xstate").NonReducibleUnknown, import("xstate").EventObject, import("xstate").MetaObject, {
63
- id: "proposalLifecycle";
64
- states: {
65
- readonly open: {};
66
- readonly deliberating: {};
67
- readonly approved: {};
68
- readonly controlled: {};
69
- readonly executed: {};
70
- readonly failed: {};
71
- readonly rejected: {};
72
- };
73
- }>;
74
- export declare function createProposalMachine(initial: ProposalStatus): import("xstate").StateMachine<ProposalContext, {
75
- type: "DELIBERATE";
76
- } | {
77
- type: "APPROVE";
78
- tally: TallyResult;
79
- } | {
80
- type: "REJECT";
81
- } | {
82
- type: "CONTROL_PASS";
83
- result: ControlCheckResult;
84
- } | {
85
- type: "CONTROL_FAIL";
86
- } | {
87
- type: "EXECUTE_SUCCESS";
88
- } | {
89
- type: "FAIL";
90
- } | {
91
- type: "DISCARD";
92
- } | {
93
- type: "ERROR";
94
- message: string;
95
- }, {}, never, never, {
96
- type: "tallyApproved";
97
- params: unknown;
98
- } | {
99
- type: "gatesPassed";
100
- params: unknown;
101
- }, never, "open" | "deliberating" | "approved" | "controlled" | "rejected" | "executed" | "failed", string, ProposalMachineInput, import("xstate").NonReducibleUnknown, import("xstate").EventObject, import("xstate").MetaObject, {
102
- id: "proposalLifecycle";
103
- states: {
104
- readonly open: {};
105
- readonly deliberating: {};
106
- readonly approved: {};
107
- readonly controlled: {};
108
- readonly executed: {};
109
- readonly failed: {};
110
- readonly rejected: {};
111
- };
112
- }>;
113
- export type ProposalMachine = ReturnType<typeof buildProposalMachine>;
114
- export {};
1
+ /** @deprecated Behavioral models now live in `/models`, the source of truth. */
2
+ export * from "../models/proposal.machine.js";
115
3
  //# sourceMappingURL=proposal.machine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"proposal.machine.d.ts","sourceRoot":"","sources":["../../src/governance/proposal.machine.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,QAAQ,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAInG,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,QAAQ,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,GACtB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,kBAAkB,CAAA;CAAE,GACpD;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GACxB;IAAE,IAAI,EAAE,iBAAiB,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAIvC,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,cAAc,CAA+C,CAAC;AAEhH,wBAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAE/D;AA2BD,iBAAS,oBAAoB,CAAC,OAAO,EAAE,cAAc;UA3CzC,YAAY;;UACZ,SAAS;WAAS,WAAW;;UAC7B,QAAQ;;UACR,cAAc;YAAU,kBAAkB;;UAC1C,cAAc;;UACd,iBAAiB;;UACjB,MAAM;;UACN,SAAS;;UACT,OAAO;aAAW,MAAM;;;;;;;;;;;;;;;;;;GAgKnC;AAUD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,cAAc;UAlLjD,YAAY;;UACZ,SAAS;WAAS,WAAW;;UAC7B,QAAQ;;UACR,cAAc;YAAU,kBAAkB;;UAC1C,cAAc;;UACd,iBAAiB;;UACjB,MAAM;;UACN,SAAS;;UACT,OAAO;aAAW,MAAM;;;;;;;;;;;;;;;;;;GAiLnC;AAED,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC"}
1
+ {"version":3,"file":"proposal.machine.d.ts","sourceRoot":"","sources":["../../src/governance/proposal.machine.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,cAAc,+BAA+B,CAAC"}
@@ -1,181 +1,3 @@
1
- // ============================================================
2
- // Swarm DAO Core — Proposal Lifecycle State Machine
3
- // ------------------------------------------------------------
4
- // Single source of truth for proposal status transitions.
5
- //
6
- // Discipline: "Le modèle décide." The LLM (council/votes) produces
7
- // signals (a TallyResult, a ControlCheckResult). Those signals are
8
- // carried as event payloads and evaluated by guards. No call site
9
- // chooses a target status — it only emits the event that matches
10
- // what happened in the world. The machine owns every edge.
11
- //
12
- // The 7 machine states map 1:1 to `ProposalStatus`. There is no
13
- // hidden `executing`/`postmortem` pipeline: the runtime is
14
- // synchronous (deliberation is one tool call, execution is one
15
- // tool call), so those intermediate states had no observer and
16
- // were removed during distill.
17
- // ============================================================
18
- import { assign, setup } from "xstate";
19
- // ── Terminal statuses ────────────────────────────────────────
20
- export const PROPOSAL_FINAL_STATUSES = new Set(["executed", "failed", "rejected"]);
21
- export function isProposalFinal(status) {
22
- return PROPOSAL_FINAL_STATUSES.has(status);
23
- }
24
- // ── Machine ──────────────────────────────────────────────────
25
- //
26
- // Guards are the two real permission boundaries of the DAO:
27
- // • tallyApproved — the council's vote authorized approval.
28
- // • gatesPassed — quality control cleared the proposal for execution.
29
- //
30
- // Risk-zone / mandatory-dry-run is enforced upstream by the
31
- // `mandatory-dry-run` control gate (control/gates.ts), which makes
32
- // `ControlCheckResult.allGatesPassed` false for red-zone proposals
33
- // without a dry-run. Duplicating that check here would be unearned
34
- // complexity — the invariant already lives at the control boundary.
35
- const proposalSetup = setup({
36
- types: {
37
- context: {},
38
- input: {},
39
- events: {},
40
- },
41
- guards: {
42
- tallyApproved: ({ event }) => event.type === "APPROVE" && event.tally.approved === true,
43
- gatesPassed: ({ event }) => event.type === "CONTROL_PASS" && event.result.allGatesPassed === true && event.result.blockerCount === 0,
44
- },
45
- });
46
- function buildProposalMachine(initial) {
47
- return proposalSetup.createMachine({
48
- id: "proposalLifecycle",
49
- initial,
50
- context: ({ input }) => ({
51
- proposal: input.proposal,
52
- lastTransitionTime: input.lastTransitionTime ?? new Date().toISOString(),
53
- }),
54
- // Note on the escape hatches (DISCARD / ERROR): they are inlined
55
- // into every non-terminal state rather than declared at the root
56
- // `on:`. XState v5 does not resolve root-level `on:` targets that
57
- // reference top-level child states — it reads them as relative to
58
- // the root's (non-existent) parent and rejects the machine. Final
59
- // states (`executed`, `failed`, `rejected`) are `type: "final"`
60
- // and ignore events once the machine is done, so the hatches are
61
- // intentionally absent there.
62
- states: {
63
- open: {
64
- on: {
65
- DELIBERATE: {
66
- target: "deliberating",
67
- actions: assign({ lastTransitionTime: () => new Date().toISOString() }),
68
- },
69
- DISCARD: {
70
- target: "rejected",
71
- actions: assign({ lastTransitionTime: () => new Date().toISOString() }),
72
- },
73
- ERROR: {
74
- target: "failed",
75
- actions: assign({
76
- lastTransitionTime: () => new Date().toISOString(),
77
- errorMessage: ({ event }) => (event.type === "ERROR" ? event.message : ""),
78
- }),
79
- },
80
- },
81
- },
82
- deliberating: {
83
- on: {
84
- APPROVE: {
85
- target: "approved",
86
- guard: "tallyApproved",
87
- actions: assign({ lastTransitionTime: () => new Date().toISOString() }),
88
- },
89
- REJECT: {
90
- target: "rejected",
91
- actions: assign({ lastTransitionTime: () => new Date().toISOString() }),
92
- },
93
- DISCARD: {
94
- target: "rejected",
95
- actions: assign({ lastTransitionTime: () => new Date().toISOString() }),
96
- },
97
- ERROR: {
98
- target: "failed",
99
- actions: assign({
100
- lastTransitionTime: () => new Date().toISOString(),
101
- errorMessage: ({ event }) => (event.type === "ERROR" ? event.message : ""),
102
- }),
103
- },
104
- },
105
- },
106
- approved: {
107
- on: {
108
- CONTROL_PASS: {
109
- target: "controlled",
110
- guard: "gatesPassed",
111
- actions: assign({ lastTransitionTime: () => new Date().toISOString() }),
112
- },
113
- CONTROL_FAIL: {
114
- target: "failed",
115
- actions: assign({ lastTransitionTime: () => new Date().toISOString() }),
116
- },
117
- REJECT: {
118
- target: "rejected",
119
- actions: assign({ lastTransitionTime: () => new Date().toISOString() }),
120
- },
121
- FAIL: {
122
- target: "failed",
123
- actions: assign({ lastTransitionTime: () => new Date().toISOString() }),
124
- },
125
- DISCARD: {
126
- target: "rejected",
127
- actions: assign({ lastTransitionTime: () => new Date().toISOString() }),
128
- },
129
- ERROR: {
130
- target: "failed",
131
- actions: assign({
132
- lastTransitionTime: () => new Date().toISOString(),
133
- errorMessage: ({ event }) => (event.type === "ERROR" ? event.message : ""),
134
- }),
135
- },
136
- },
137
- },
138
- controlled: {
139
- on: {
140
- EXECUTE_SUCCESS: {
141
- target: "executed",
142
- actions: assign({ lastTransitionTime: () => new Date().toISOString() }),
143
- },
144
- FAIL: {
145
- target: "failed",
146
- actions: assign({ lastTransitionTime: () => new Date().toISOString() }),
147
- },
148
- DISCARD: {
149
- target: "rejected",
150
- actions: assign({ lastTransitionTime: () => new Date().toISOString() }),
151
- },
152
- ERROR: {
153
- target: "failed",
154
- actions: assign({
155
- lastTransitionTime: () => new Date().toISOString(),
156
- errorMessage: ({ event }) => (event.type === "ERROR" ? event.message : ""),
157
- }),
158
- },
159
- },
160
- },
161
- executed: { type: "final" },
162
- failed: { type: "final" },
163
- rejected: { type: "final" },
164
- },
165
- });
166
- }
167
- // ── Factory (with memoization) ───────────────────────────────
168
- //
169
- // A machine is created per starting status so an actor can be
170
- // rehydrated at the persisted status of a proposal. The machine
171
- // definition is identical; only `initial` differs.
172
- const machineCache = new Map();
173
- export function createProposalMachine(initial) {
174
- let machine = machineCache.get(initial);
175
- if (!machine) {
176
- machine = buildProposalMachine(initial);
177
- machineCache.set(initial, machine);
178
- }
179
- return machine;
180
- }
1
+ /** @deprecated Behavioral models now live in `/models`, the source of truth. */
2
+ export * from "../models/proposal.machine.js";
181
3
  //# sourceMappingURL=proposal.machine.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"proposal.machine.js","sourceRoot":"","sources":["../../src/governance/proposal.machine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"proposal.machine.js","sourceRoot":"","sources":["../../src/governance/proposal.machine.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,cAAc,+BAA+B,CAAC"}
@@ -1,5 +1,6 @@
1
+ import { type ProposalEvent } from "../models/proposal.machine.js";
2
+ import type { ClockPort } from "../ports/clock.js";
1
3
  import type { Proposal, ProposalStatus } from "../types/index.js";
2
- import { type ProposalEvent } from "./proposal.machine.js";
3
4
  export type DispatchResult = {
4
5
  ok: true;
5
6
  status: ProposalStatus;
@@ -16,5 +17,7 @@ export type DispatchResult = {
16
17
  * from the current status — the caller must surface that error and
17
18
  * MUST NOT mutate the status itself.
18
19
  */
19
- export declare function dispatchProposalEvent(proposal: Proposal, event: ProposalEvent): DispatchResult;
20
+ export declare function dispatchProposalEvent(proposal: Proposal, event: ProposalEvent, options?: {
21
+ clock?: ClockPort;
22
+ }): DispatchResult;
20
23
  //# sourceMappingURL=proposal.utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"proposal.utils.d.ts","sourceRoot":"","sources":["../../src/governance/proposal.utils.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAGL,KAAK,aAAa,EAEnB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,MAAM,cAAc,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,cAAc,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjG;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,GAAG,cAAc,CAsC9F"}
1
+ {"version":3,"file":"proposal.utils.d.ts","sourceRoot":"","sources":["../../src/governance/proposal.utils.ts"],"names":[],"mappings":"AAYA,OAAO,EAGL,KAAK,aAAa,EAEnB,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAElE,MAAM,MAAM,cAAc,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,cAAc,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjG;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,aAAa,EACpB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,SAAS,CAAA;CAAO,GAClC,cAAc,CAwChB"}
@@ -9,7 +9,8 @@
9
9
  // status back to the proposal. There is no other status writer.
10
10
  // ============================================================
11
11
  import { createActor } from "xstate";
12
- import { createProposalMachine, isProposalFinal, } from "./proposal.machine.js";
12
+ import { createProposalMachine, isProposalFinal, } from "../models/proposal.machine.js";
13
+ import { systemClock } from "../ports/clock.js";
13
14
  /**
14
15
  * Apply a lifecycle event to a proposal. Enforces the machine's
15
16
  * topology AND its guards. On success, `proposal.status` (and
@@ -19,7 +20,7 @@ import { createProposalMachine, isProposalFinal, } from "./proposal.machine.js";
19
20
  * from the current status — the caller must surface that error and
20
21
  * MUST NOT mutate the status itself.
21
22
  */
22
- export function dispatchProposalEvent(proposal, event) {
23
+ export function dispatchProposalEvent(proposal, event, options = {}) {
23
24
  // Terminal states are final: no event may leave them. This guard
24
25
  // makes the invariant explicit rather than relying on the actor's
25
26
  // "done" status, so the model stays correct regardless of how the
@@ -30,11 +31,13 @@ export function dispatchProposalEvent(proposal, event) {
30
31
  error: `Proposal is in terminal status "${proposal.status}"; no transitions are permitted.`,
31
32
  };
32
33
  }
34
+ const transitionTime = (options.clock ?? systemClock).now();
33
35
  const machine = createProposalMachine(proposal.status);
34
36
  const actor = createActor(machine, {
35
37
  input: {
36
38
  proposal,
37
- lastTransitionTime: new Date().toISOString(),
39
+ transitionTime,
40
+ lastTransitionTime: transitionTime,
38
41
  },
39
42
  });
40
43
  actor.start();
@@ -49,7 +52,7 @@ export function dispatchProposalEvent(proposal, event) {
49
52
  const status = actor.getSnapshot().value;
50
53
  proposal.status = status;
51
54
  if (isProposalFinal(status) && !proposal.resolvedAt) {
52
- proposal.resolvedAt = new Date().toISOString();
55
+ proposal.resolvedAt = transitionTime;
53
56
  }
54
57
  return { ok: true, status };
55
58
  }
@@ -1 +1 @@
1
- {"version":3,"file":"proposal.utils.js","sourceRoot":"","sources":["../../src/governance/proposal.utils.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,6CAA6C;AAC7C,+DAA+D;AAC/D,6DAA6D;AAC7D,kEAAkE;AAClE,iEAAiE;AACjE,kEAAkE;AAClE,+DAA+D;AAC/D,gEAAgE;AAChE,+DAA+D;AAE/D,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,EACL,qBAAqB,EACrB,eAAe,GAGhB,MAAM,uBAAuB,CAAC;AAI/B;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAkB,EAAE,KAAoB;IAC5E,iEAAiE;IACjE,kEAAkE;IAClE,kEAAkE;IAClE,iEAAiE;IACjE,IAAI,eAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACrC,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,mCAAmC,QAAQ,CAAC,MAAM,kCAAkC;SAC5F,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,qBAAqB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,EAAE;QACjC,KAAK,EAAE;YACL,QAAQ;YACR,kBAAkB,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACd;KACjC,CAAC,CAAC;IACH,KAAK,CAAC,KAAK,EAAE,CAAC;IAEd,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IACnC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,UAAU,KAAK,CAAC,IAAI,mCAAmC,QAAQ,CAAC,MAAM,IAAI;SAClF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,KAAuB,CAAC;IAE3D,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;IACzB,IAAI,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;QACpD,QAAQ,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACjD,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC9B,CAAC"}
1
+ {"version":3,"file":"proposal.utils.js","sourceRoot":"","sources":["../../src/governance/proposal.utils.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,6CAA6C;AAC7C,+DAA+D;AAC/D,6DAA6D;AAC7D,kEAAkE;AAClE,iEAAiE;AACjE,kEAAkE;AAClE,+DAA+D;AAC/D,gEAAgE;AAChE,+DAA+D;AAE/D,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EACL,qBAAqB,EACrB,eAAe,GAGhB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAKhD;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CACnC,QAAkB,EAClB,KAAoB,EACpB,UAAiC,EAAE;IAEnC,iEAAiE;IACjE,kEAAkE;IAClE,kEAAkE;IAClE,iEAAiE;IACjE,IAAI,eAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACrC,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,mCAAmC,QAAQ,CAAC,MAAM,kCAAkC;SAC5F,CAAC;IACJ,CAAC;IAED,MAAM,cAAc,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,WAAW,CAAC,CAAC,GAAG,EAAE,CAAC;IAC5D,MAAM,OAAO,GAAG,qBAAqB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,EAAE;QACjC,KAAK,EAAE;YACL,QAAQ;YACR,cAAc;YACd,kBAAkB,EAAE,cAAc;SACJ;KACjC,CAAC,CAAC;IACH,KAAK,CAAC,KAAK,EAAE,CAAC;IAEd,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IACnC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,UAAU,KAAK,CAAC,IAAI,mCAAmC,QAAQ,CAAC,MAAM,IAAI;SAClF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClB,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,KAAuB,CAAC;IAE3D,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;IACzB,IAAI,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;QACpD,QAAQ,CAAC,UAAU,GAAG,cAAc,CAAC;IACvC,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC9B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"voting.d.ts","sourceRoot":"","sources":["../../src/governance/voting.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAgB,MAAM,mBAAmB,CAAC;AAW3G,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,IAAI,GAAG,SAAS,CAclB;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,CAG9E;AAID,wBAAgB,UAAU,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,GAAG,WAAW,CAgD7E;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAe5D"}
1
+ {"version":3,"file":"voting.d.ts","sourceRoot":"","sources":["../../src/governance/voting.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAgB,MAAM,mBAAmB,CAAC;AAW3G,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,IAAI,GAAG,SAAS,CAclB;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,CAG9E;AAID,wBAAgB,UAAU,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,GAAG,WAAW,CAuD7E;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAe5D"}
@@ -29,21 +29,31 @@ export function parseVoteFromAgentOutput(output) {
29
29
  export function tallyVotes(proposal, config) {
30
30
  const votes = proposal.votes || [];
31
31
  const totalAgents = proposal.agentOutputs?.length || votes.length;
32
- const weightedFor = votes
33
- .filter((v) => v.position === "for")
34
- .reduce((sum, v) => sum + normalizeVoteWeight(v.weight), 0);
35
- const weightedAgainst = votes
36
- .filter((v) => v.position === "against")
37
- .reduce((sum, v) => sum + normalizeVoteWeight(v.weight), 0);
38
- const weightedAbstain = votes
39
- .filter((v) => v.position === "abstain")
40
- .reduce((sum, v) => sum + normalizeVoteWeight(v.weight), 0);
32
+ // Single pass over votes: accumulate weighted totals + voting-agent count.
33
+ let weightedFor = 0;
34
+ let weightedAgainst = 0;
35
+ let weightedAbstain = 0;
36
+ let totalObservedWeight = 0;
37
+ let votingAgents = 0;
38
+ for (const v of votes) {
39
+ const w = normalizeVoteWeight(v.weight);
40
+ totalObservedWeight += w;
41
+ if (v.position === "for") {
42
+ weightedFor += w;
43
+ votingAgents++;
44
+ }
45
+ else if (v.position === "against") {
46
+ weightedAgainst += w;
47
+ votingAgents++;
48
+ }
49
+ else {
50
+ weightedAbstain += w;
51
+ }
52
+ }
41
53
  const totalVotingWeight = weightedFor + weightedAgainst + weightedAbstain;
42
- const votingAgents = votes.filter((v) => v.position !== "abstain").length;
43
- // Quorum check: % of total agent weight that participated
44
- const totalPossibleWeight = totalAgents > 0
45
- ? votes.reduce((sum, v) => sum + normalizeVoteWeight(v.weight), 0) + (totalAgents - votes.length) * 1
46
- : totalVotingWeight;
54
+ // Quorum check: % of total agent weight that participated.
55
+ // Unobserved agents (totalAgents - votes.length) each contribute default weight 1.
56
+ const totalPossibleWeight = totalAgents > 0 ? totalObservedWeight + (totalAgents - votes.length) * 1 : totalVotingWeight;
47
57
  const quorumPercent = totalPossibleWeight > 0 ? Math.round((totalVotingWeight / totalPossibleWeight) * 100) : 0;
48
58
  const quorumMet = quorumPercent >= config.quorumPercent;
49
59
  // Approval: % of non-abstain weight that voted for