@arcanea/council 0.1.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.
@@ -0,0 +1,378 @@
1
+ /**
2
+ * V3 Gossip Protocol Consensus
3
+ * Eventually consistent consensus for large-scale distributed systems
4
+ */
5
+ import { EventEmitter } from 'events';
6
+ import { SWARM_CONSTANTS, } from '../types.js';
7
+ export class GossipConsensus extends EventEmitter {
8
+ config;
9
+ node;
10
+ nodes = new Map();
11
+ proposals = new Map();
12
+ messageQueue = [];
13
+ gossipInterval;
14
+ proposalCounter = 0;
15
+ constructor(nodeId, config = {}) {
16
+ super();
17
+ this.config = {
18
+ threshold: config.threshold ?? SWARM_CONSTANTS.DEFAULT_CONSENSUS_THRESHOLD,
19
+ timeoutMs: config.timeoutMs ?? SWARM_CONSTANTS.DEFAULT_CONSENSUS_TIMEOUT_MS,
20
+ maxRounds: config.maxRounds ?? 10,
21
+ requireQuorum: config.requireQuorum ?? false, // Gossip is eventually consistent
22
+ fanout: config.fanout ?? 3,
23
+ gossipIntervalMs: config.gossipIntervalMs ?? 100,
24
+ maxHops: config.maxHops ?? 10,
25
+ convergenceThreshold: config.convergenceThreshold ?? 0.9,
26
+ };
27
+ this.node = {
28
+ id: nodeId,
29
+ state: new Map(),
30
+ version: 0,
31
+ neighbors: new Set(),
32
+ seenMessages: new Set(),
33
+ lastSync: new Date(),
34
+ };
35
+ }
36
+ async initialize() {
37
+ this.startGossipLoop();
38
+ this.emit('initialized', { nodeId: this.node.id });
39
+ }
40
+ async shutdown() {
41
+ if (this.gossipInterval) {
42
+ clearInterval(this.gossipInterval);
43
+ }
44
+ this.emit('shutdown');
45
+ }
46
+ addNode(nodeId) {
47
+ this.nodes.set(nodeId, {
48
+ id: nodeId,
49
+ state: new Map(),
50
+ version: 0,
51
+ neighbors: new Set(),
52
+ seenMessages: new Set(),
53
+ lastSync: new Date(),
54
+ });
55
+ // Add as neighbor with some probability (random mesh)
56
+ if (Math.random() < 0.5) {
57
+ this.node.neighbors.add(nodeId);
58
+ this.nodes.get(nodeId).neighbors.add(this.node.id);
59
+ }
60
+ }
61
+ removeNode(nodeId) {
62
+ this.nodes.delete(nodeId);
63
+ this.node.neighbors.delete(nodeId);
64
+ for (const node of this.nodes.values()) {
65
+ node.neighbors.delete(nodeId);
66
+ }
67
+ }
68
+ addNeighbor(nodeId) {
69
+ if (this.nodes.has(nodeId)) {
70
+ this.node.neighbors.add(nodeId);
71
+ }
72
+ }
73
+ removeNeighbor(nodeId) {
74
+ this.node.neighbors.delete(nodeId);
75
+ }
76
+ async propose(value) {
77
+ this.proposalCounter++;
78
+ const proposalId = `gossip_${this.node.id}_${this.proposalCounter}`;
79
+ const proposal = {
80
+ id: proposalId,
81
+ proposerId: this.node.id,
82
+ value,
83
+ term: this.node.version,
84
+ timestamp: new Date(),
85
+ votes: new Map(),
86
+ status: 'pending',
87
+ };
88
+ this.proposals.set(proposalId, proposal);
89
+ // Self-vote
90
+ proposal.votes.set(this.node.id, {
91
+ voterId: this.node.id,
92
+ approve: true,
93
+ confidence: 1.0,
94
+ timestamp: new Date(),
95
+ });
96
+ // Create gossip message
97
+ const message = {
98
+ id: `msg_${proposalId}`,
99
+ type: 'proposal',
100
+ senderId: this.node.id,
101
+ version: ++this.node.version,
102
+ payload: { proposalId, value },
103
+ timestamp: new Date(),
104
+ ttl: this.config.maxHops ?? 10,
105
+ hops: 0,
106
+ path: [this.node.id],
107
+ };
108
+ // Queue for gossip
109
+ this.queueMessage(message);
110
+ return proposal;
111
+ }
112
+ async vote(proposalId, vote) {
113
+ const proposal = this.proposals.get(proposalId);
114
+ if (!proposal) {
115
+ return;
116
+ }
117
+ proposal.votes.set(vote.voterId, vote);
118
+ // Create vote gossip message
119
+ const message = {
120
+ id: `vote_${proposalId}_${vote.voterId}`,
121
+ type: 'vote',
122
+ senderId: this.node.id,
123
+ version: ++this.node.version,
124
+ payload: { proposalId, vote },
125
+ timestamp: new Date(),
126
+ ttl: this.config.maxHops ?? 10,
127
+ hops: 0,
128
+ path: [this.node.id],
129
+ };
130
+ this.queueMessage(message);
131
+ // Check convergence
132
+ await this.checkConvergence(proposalId);
133
+ }
134
+ async awaitConsensus(proposalId) {
135
+ const startTime = Date.now();
136
+ const maxWait = this.config.timeoutMs ?? 30000;
137
+ return new Promise((resolve, reject) => {
138
+ const checkInterval = setInterval(() => {
139
+ const proposal = this.proposals.get(proposalId);
140
+ if (!proposal) {
141
+ clearInterval(checkInterval);
142
+ reject(new Error(`Proposal ${proposalId} not found`));
143
+ return;
144
+ }
145
+ if (proposal.status !== 'pending') {
146
+ clearInterval(checkInterval);
147
+ resolve(this.createResult(proposal, Date.now() - startTime));
148
+ return;
149
+ }
150
+ // Check convergence
151
+ this.checkConvergence(proposalId);
152
+ if (Date.now() - startTime > maxWait) {
153
+ clearInterval(checkInterval);
154
+ // Gossip is eventually consistent, so mark as accepted if threshold met
155
+ const totalNodes = this.nodes.size + 1;
156
+ const votes = proposal.votes.size;
157
+ const threshold = this.config.convergenceThreshold ?? 0.9;
158
+ if (votes / totalNodes >= threshold) {
159
+ proposal.status = 'accepted';
160
+ }
161
+ else {
162
+ proposal.status = 'expired';
163
+ }
164
+ resolve(this.createResult(proposal, Date.now() - startTime));
165
+ }
166
+ }, 50);
167
+ });
168
+ }
169
+ // ===== GOSSIP PROTOCOL =====
170
+ startGossipLoop() {
171
+ this.gossipInterval = setInterval(() => {
172
+ this.gossipRound();
173
+ }, this.config.gossipIntervalMs ?? 100);
174
+ }
175
+ async gossipRound() {
176
+ if (this.messageQueue.length === 0) {
177
+ return;
178
+ }
179
+ // Select random neighbors (fanout)
180
+ const fanout = Math.min(this.config.fanout ?? 3, this.node.neighbors.size);
181
+ const neighbors = this.selectRandomNeighbors(fanout);
182
+ // Send queued messages to selected neighbors
183
+ const messages = this.messageQueue.splice(0, 10); // Process up to 10 per round
184
+ for (const message of messages) {
185
+ for (const neighborId of neighbors) {
186
+ await this.sendToNeighbor(neighborId, message);
187
+ }
188
+ }
189
+ this.node.lastSync = new Date();
190
+ }
191
+ selectRandomNeighbors(count) {
192
+ const neighbors = Array.from(this.node.neighbors);
193
+ const selected = [];
194
+ while (selected.length < count && neighbors.length > 0) {
195
+ const idx = Math.floor(Math.random() * neighbors.length);
196
+ selected.push(neighbors.splice(idx, 1)[0]);
197
+ }
198
+ return selected;
199
+ }
200
+ async sendToNeighbor(neighborId, message) {
201
+ const neighbor = this.nodes.get(neighborId);
202
+ if (!neighbor) {
203
+ return;
204
+ }
205
+ // Check if already seen
206
+ if (neighbor.seenMessages.has(message.id)) {
207
+ return;
208
+ }
209
+ // Deliver message to neighbor node
210
+ const deliveredMessage = {
211
+ ...message,
212
+ hops: message.hops + 1,
213
+ path: [...message.path, neighborId],
214
+ };
215
+ // Process at neighbor
216
+ await this.processReceivedMessage(neighbor, deliveredMessage);
217
+ this.emit('message.sent', { to: neighborId, message: deliveredMessage });
218
+ }
219
+ async processReceivedMessage(node, message) {
220
+ // Mark as seen
221
+ node.seenMessages.add(message.id);
222
+ // Check TTL
223
+ if (message.ttl <= 0 || message.hops >= (this.config.maxHops ?? 10)) {
224
+ return;
225
+ }
226
+ switch (message.type) {
227
+ case 'proposal':
228
+ await this.handleProposalMessage(node, message);
229
+ break;
230
+ case 'vote':
231
+ await this.handleVoteMessage(node, message);
232
+ break;
233
+ case 'state':
234
+ await this.handleStateMessage(node, message);
235
+ break;
236
+ }
237
+ // Propagate to neighbors (gossip)
238
+ if (message.hops < (this.config.maxHops ?? 10)) {
239
+ const propagateMessage = {
240
+ ...message,
241
+ ttl: message.ttl - 1,
242
+ };
243
+ // Add to queue if this is our node
244
+ if (node.id === this.node.id) {
245
+ this.queueMessage(propagateMessage);
246
+ }
247
+ }
248
+ }
249
+ async handleProposalMessage(node, message) {
250
+ const { proposalId, value } = message.payload;
251
+ if (!this.proposals.has(proposalId)) {
252
+ const proposal = {
253
+ id: proposalId,
254
+ proposerId: message.senderId,
255
+ value,
256
+ term: message.version,
257
+ timestamp: message.timestamp,
258
+ votes: new Map(),
259
+ status: 'pending',
260
+ };
261
+ this.proposals.set(proposalId, proposal);
262
+ // Auto-vote (simplified)
263
+ if (node.id === this.node.id) {
264
+ await this.vote(proposalId, {
265
+ voterId: this.node.id,
266
+ approve: true,
267
+ confidence: 0.9,
268
+ timestamp: new Date(),
269
+ });
270
+ }
271
+ }
272
+ }
273
+ async handleVoteMessage(node, message) {
274
+ const { proposalId, vote } = message.payload;
275
+ const proposal = this.proposals.get(proposalId);
276
+ if (proposal && !proposal.votes.has(vote.voterId)) {
277
+ proposal.votes.set(vote.voterId, vote);
278
+ await this.checkConvergence(proposalId);
279
+ }
280
+ }
281
+ async handleStateMessage(node, message) {
282
+ const state = message.payload;
283
+ // Merge state (last-writer-wins)
284
+ if (message.version > node.version) {
285
+ for (const [key, value] of Object.entries(state)) {
286
+ node.state.set(key, value);
287
+ }
288
+ node.version = message.version;
289
+ }
290
+ }
291
+ queueMessage(message) {
292
+ // Avoid duplicates
293
+ if (!this.node.seenMessages.has(message.id)) {
294
+ this.node.seenMessages.add(message.id);
295
+ this.messageQueue.push(message);
296
+ }
297
+ }
298
+ async checkConvergence(proposalId) {
299
+ const proposal = this.proposals.get(proposalId);
300
+ if (!proposal || proposal.status !== 'pending') {
301
+ return;
302
+ }
303
+ const totalNodes = this.nodes.size + 1;
304
+ const votes = proposal.votes.size;
305
+ const threshold = this.config.convergenceThreshold ?? 0.9;
306
+ const approvalThreshold = this.config.threshold ?? 0.66;
307
+ // Check if we've converged (enough nodes have voted)
308
+ if (votes / totalNodes >= threshold) {
309
+ const approvingVotes = Array.from(proposal.votes.values()).filter(v => v.approve).length;
310
+ if (approvingVotes / votes >= approvalThreshold) {
311
+ proposal.status = 'accepted';
312
+ this.emit('consensus.achieved', { proposalId, approved: true });
313
+ }
314
+ else {
315
+ proposal.status = 'rejected';
316
+ this.emit('consensus.achieved', { proposalId, approved: false });
317
+ }
318
+ }
319
+ }
320
+ createResult(proposal, durationMs) {
321
+ const totalNodes = this.nodes.size + 1;
322
+ const approvingVotes = Array.from(proposal.votes.values()).filter(v => v.approve).length;
323
+ return {
324
+ proposalId: proposal.id,
325
+ approved: proposal.status === 'accepted',
326
+ approvalRate: proposal.votes.size > 0
327
+ ? approvingVotes / proposal.votes.size
328
+ : 0,
329
+ participationRate: proposal.votes.size / totalNodes,
330
+ finalValue: proposal.value,
331
+ rounds: this.node.version,
332
+ durationMs,
333
+ };
334
+ }
335
+ // ===== STATE QUERIES =====
336
+ getConvergence(proposalId) {
337
+ const proposal = this.proposals.get(proposalId);
338
+ if (!proposal)
339
+ return 0;
340
+ const totalNodes = this.nodes.size + 1;
341
+ return proposal.votes.size / totalNodes;
342
+ }
343
+ getVersion() {
344
+ return this.node.version;
345
+ }
346
+ getNeighborCount() {
347
+ return this.node.neighbors.size;
348
+ }
349
+ getSeenMessageCount() {
350
+ return this.node.seenMessages.size;
351
+ }
352
+ getQueueDepth() {
353
+ return this.messageQueue.length;
354
+ }
355
+ // Anti-entropy: sync full state with a random neighbor
356
+ async antiEntropy() {
357
+ if (this.node.neighbors.size === 0)
358
+ return;
359
+ const neighbors = Array.from(this.node.neighbors);
360
+ const randomNeighbor = neighbors[Math.floor(Math.random() * neighbors.length)];
361
+ const stateMessage = {
362
+ id: `state_${this.node.id}_${Date.now()}`,
363
+ type: 'state',
364
+ senderId: this.node.id,
365
+ version: this.node.version,
366
+ payload: Object.fromEntries(this.node.state),
367
+ timestamp: new Date(),
368
+ ttl: 1,
369
+ hops: 0,
370
+ path: [this.node.id],
371
+ };
372
+ await this.sendToNeighbor(randomNeighbor, stateMessage);
373
+ }
374
+ }
375
+ export function createGossipConsensus(nodeId, config) {
376
+ return new GossipConsensus(nodeId, config);
377
+ }
378
+ //# sourceMappingURL=gossip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gossip.js","sourceRoot":"","sources":["../../src/consensus/gossip.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @arcanea/council — Council Engine Factory
3
+ *
4
+ * Creates the appropriate consensus engine based on the selected Council Protocol.
5
+ * Maps Arcanea's Council terminology to the underlying consensus implementations:
6
+ *
7
+ * council-vote → Raft (leader election, log replication)
8
+ * shinkamis-decree → Byzantine BFT (fault-tolerant under hostile agents)
9
+ * whisper → Gossip (eventual consistency via propagation)
10
+ * gate-quorum → Arcanea-native frequency-weighted Guardian voting
11
+ * ancient-accord → Paxos (falls back to Raft — same lineage)
12
+ */
13
+ import { EventEmitter } from 'node:events';
14
+ import type { CouncilProtocol, CouncilConfig, Petition, Seal, CouncilResult, ICouncilEngine } from '../types.js';
15
+ import type { GuardianName, Element } from '../external-types.js';
16
+ import { type ByzantineConfig } from './byzantine.js';
17
+ import { type RaftConfig } from './raft.js';
18
+ import { type GossipConfig } from './gossip.js';
19
+ import { type GateQuorumOptions } from './gate-quorum.js';
20
+ export interface CouncilEngineOptions {
21
+ protocol: CouncilProtocol;
22
+ nodeId: string;
23
+ byzantine?: ByzantineConfig;
24
+ raft?: RaftConfig;
25
+ gossip?: GossipConfig;
26
+ gateQuorum?: GateQuorumOptions;
27
+ }
28
+ /**
29
+ * Unified Council Engine that wraps the selected consensus protocol.
30
+ * Provides a consistent ICouncilEngine interface regardless of the
31
+ * underlying algorithm. Adapts between ported claude-flow field names
32
+ * and Arcanea's Council terminology at the boundary.
33
+ */
34
+ export declare class CouncilEngine extends EventEmitter implements ICouncilEngine {
35
+ private protocol;
36
+ private engine;
37
+ private usesLegacyFields;
38
+ private addNodeFn;
39
+ private removeNodeFn;
40
+ constructor(options: CouncilEngineOptions);
41
+ initialize(config?: CouncilConfig): Promise<void>;
42
+ shutdown(): Promise<void>;
43
+ addNode(nodeId: string, options?: {
44
+ isPrimary?: boolean;
45
+ guardian?: GuardianName;
46
+ }): void;
47
+ removeNode(nodeId: string): void;
48
+ propose(value: unknown): Promise<Petition>;
49
+ vote(petitionId: string, seal: Seal): Promise<void>;
50
+ awaitConsensus(petitionId: string): Promise<CouncilResult>;
51
+ getProtocol(): CouncilProtocol;
52
+ }
53
+ export declare function selectCouncilProtocol(element?: Element): CouncilProtocol;
54
+ export declare function createCouncilEngine(options: CouncilEngineOptions): CouncilEngine;
55
+ export { ByzantineConsensus, type ByzantineConfig } from './byzantine.js';
56
+ export { RaftConsensus, type RaftConfig } from './raft.js';
57
+ export { GossipConsensus, type GossipConfig } from './gossip.js';
58
+ export { GateQuorumConsensus, type GateQuorumOptions } from './gate-quorum.js';
59
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/consensus/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EACV,eAAe,EACf,aAAa,EACb,QAAQ,EACR,IAAI,EACJ,aAAa,EAIb,cAAc,EACf,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAsB,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAuB,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AA2E/E,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,eAAe,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IAGf,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,UAAU,CAAC,EAAE,iBAAiB,CAAC;CAChC;AAED;;;;;GAKG;AACH,qBAAa,aAAc,SAAQ,YAAa,YAAW,cAAc;IACvE,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,gBAAgB,CAAU;IAClC,OAAO,CAAC,SAAS,CAA8D;IAC/E,OAAO,CAAC,YAAY,CAA2B;gBAEnC,OAAO,EAAE,oBAAoB;IAwDnC,UAAU,CAAC,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAK/B,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,YAAY,CAAA;KAAE,GAAG,IAAI;IAIzF,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI1B,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;IAK1C,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAOnD,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAKhE,WAAW,IAAI,eAAe;CAG/B;AAwBD,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,eAAe,CAGxE;AAID,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAEhF;AAGD,OAAO,EAAE,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,193 @@
1
+ /**
2
+ * @arcanea/council — Council Engine Factory
3
+ *
4
+ * Creates the appropriate consensus engine based on the selected Council Protocol.
5
+ * Maps Arcanea's Council terminology to the underlying consensus implementations:
6
+ *
7
+ * council-vote → Raft (leader election, log replication)
8
+ * shinkamis-decree → Byzantine BFT (fault-tolerant under hostile agents)
9
+ * whisper → Gossip (eventual consistency via propagation)
10
+ * gate-quorum → Arcanea-native frequency-weighted Guardian voting
11
+ * ancient-accord → Paxos (falls back to Raft — same lineage)
12
+ */
13
+ import { EventEmitter } from 'node:events';
14
+ import { ByzantineConsensus } from './byzantine.js';
15
+ import { RaftConsensus } from './raft.js';
16
+ import { GossipConsensus } from './gossip.js';
17
+ import { GateQuorumConsensus } from './gate-quorum.js';
18
+ /** Adapt a ConsensusProposal (old fields) to a Petition (Arcanea fields) */
19
+ function toPetition(cp) {
20
+ return {
21
+ id: cp.id,
22
+ petitionerId: cp.proposerId,
23
+ value: cp.value,
24
+ term: cp.term,
25
+ timestamp: cp.timestamp,
26
+ seals: adaptVotesToSeals(cp.votes),
27
+ status: cp.status,
28
+ };
29
+ }
30
+ /** Adapt a votes Map<string, ConsensusVote> to seals Map<string, Seal> */
31
+ function adaptVotesToSeals(votes) {
32
+ const seals = new Map();
33
+ for (const [key, vote] of votes) {
34
+ seals.set(key, {
35
+ guardianId: vote.voterId,
36
+ approve: vote.approve,
37
+ confidence: vote.confidence,
38
+ timestamp: vote.timestamp,
39
+ reason: vote.reason,
40
+ });
41
+ }
42
+ return seals;
43
+ }
44
+ /** Adapt a Seal (Arcanea) to ConsensusVote (old) for ported engines */
45
+ function toConsensusVote(seal) {
46
+ return {
47
+ voterId: seal.guardianId,
48
+ approve: seal.approve,
49
+ confidence: seal.confidence,
50
+ timestamp: seal.timestamp,
51
+ reason: seal.reason,
52
+ };
53
+ }
54
+ /** Adapt a ConsensusResult (old) to CouncilResult (Arcanea) */
55
+ function toCouncilResult(cr) {
56
+ return {
57
+ petitionId: cr.proposalId,
58
+ approved: cr.approved,
59
+ approvalRate: cr.approvalRate,
60
+ participationRate: cr.participationRate,
61
+ finalValue: cr.finalValue,
62
+ rounds: cr.rounds,
63
+ durationMs: cr.durationMs,
64
+ };
65
+ }
66
+ /**
67
+ * Unified Council Engine that wraps the selected consensus protocol.
68
+ * Provides a consistent ICouncilEngine interface regardless of the
69
+ * underlying algorithm. Adapts between ported claude-flow field names
70
+ * and Arcanea's Council terminology at the boundary.
71
+ */
72
+ export class CouncilEngine extends EventEmitter {
73
+ protocol;
74
+ engine;
75
+ usesLegacyFields;
76
+ addNodeFn;
77
+ removeNodeFn;
78
+ constructor(options) {
79
+ super();
80
+ this.protocol = options.protocol;
81
+ this.usesLegacyFields = options.protocol !== 'gate-quorum';
82
+ switch (options.protocol) {
83
+ case 'shinkamis-decree': {
84
+ const byz = new ByzantineConsensus(options.nodeId, options.byzantine);
85
+ this.engine = byz;
86
+ this.addNodeFn = (id, opts) => byz.addNode(id, opts?.isPrimary ?? false);
87
+ this.removeNodeFn = (id) => byz.removeNode(id);
88
+ break;
89
+ }
90
+ case 'council-vote':
91
+ case 'ancient-accord': {
92
+ const raft = new RaftConsensus(options.nodeId, options.raft);
93
+ this.engine = raft;
94
+ this.addNodeFn = (id) => raft.addPeer(id);
95
+ this.removeNodeFn = (id) => raft.removePeer(id);
96
+ break;
97
+ }
98
+ case 'whisper': {
99
+ const gossip = new GossipConsensus(options.nodeId, options.gossip);
100
+ this.engine = gossip;
101
+ this.addNodeFn = (id) => gossip.addNode(id);
102
+ this.removeNodeFn = (id) => gossip.removeNode(id);
103
+ break;
104
+ }
105
+ case 'gate-quorum': {
106
+ const gq = new GateQuorumConsensus(options.nodeId, options.gateQuorum);
107
+ this.engine = gq;
108
+ this.addNodeFn = (id, opts) => gq.addNode(id, opts);
109
+ this.removeNodeFn = (id) => gq.removeNode(id);
110
+ break;
111
+ }
112
+ default: {
113
+ const fallback = new RaftConsensus(options.nodeId);
114
+ this.engine = fallback;
115
+ this.usesLegacyFields = true;
116
+ this.addNodeFn = (id) => fallback.addPeer(id);
117
+ this.removeNodeFn = (id) => fallback.removePeer(id);
118
+ }
119
+ }
120
+ // Forward all events from the underlying engine
121
+ const originalEmit = this.engine.emit.bind(this.engine);
122
+ this.engine.emit = (event, ...args) => {
123
+ this.emit(event, ...args);
124
+ return originalEmit(event, ...args);
125
+ };
126
+ }
127
+ async initialize(config) {
128
+ await this.engine.initialize(config);
129
+ this.emit('council.initialized', { protocol: this.protocol });
130
+ }
131
+ async shutdown() {
132
+ await this.engine.shutdown();
133
+ this.emit('council.shutdown', { protocol: this.protocol });
134
+ }
135
+ addNode(nodeId, options) {
136
+ this.addNodeFn(nodeId, options);
137
+ }
138
+ removeNode(nodeId) {
139
+ this.removeNodeFn(nodeId);
140
+ }
141
+ async propose(value) {
142
+ const result = await this.engine.propose(value);
143
+ return this.usesLegacyFields ? toPetition(result) : result;
144
+ }
145
+ async vote(petitionId, seal) {
146
+ if (this.usesLegacyFields) {
147
+ return this.engine.vote(petitionId, toConsensusVote(seal));
148
+ }
149
+ return this.engine.vote(petitionId, seal);
150
+ }
151
+ async awaitConsensus(petitionId) {
152
+ const result = await this.engine.awaitConsensus(petitionId);
153
+ return this.usesLegacyFields ? toCouncilResult(result) : result;
154
+ }
155
+ getProtocol() {
156
+ return this.protocol;
157
+ }
158
+ }
159
+ // ── Protocol Selection ─────────────────────────────────────────
160
+ /**
161
+ * Element-based protocol routing.
162
+ * Each element has a natural affinity for a Council Protocol:
163
+ *
164
+ * earth → council-vote (Raft) — stable leadership
165
+ * fire → shinkamis-decree (Byzantine) — adversarial resilience
166
+ * water → whisper (Gossip) — fluid propagation
167
+ * wind → gate-quorum — dynamic, frequency-driven
168
+ * void → shinkamis-decree — fault tolerance in the unknown
169
+ * spirit → gate-quorum — transcendent, weighted by consciousness
170
+ */
171
+ const ELEMENT_PROTOCOL_MAP = {
172
+ earth: 'council-vote',
173
+ fire: 'shinkamis-decree',
174
+ water: 'whisper',
175
+ wind: 'gate-quorum',
176
+ void: 'shinkamis-decree',
177
+ spirit: 'gate-quorum',
178
+ };
179
+ export function selectCouncilProtocol(element) {
180
+ if (!element)
181
+ return 'gate-quorum'; // Arcanea's native protocol is the default
182
+ return ELEMENT_PROTOCOL_MAP[element] ?? 'gate-quorum';
183
+ }
184
+ // ── Factory ────────────────────────────────────────────────────
185
+ export function createCouncilEngine(options) {
186
+ return new CouncilEngine(options);
187
+ }
188
+ // Re-export consensus implementations
189
+ export { ByzantineConsensus } from './byzantine.js';
190
+ export { RaftConsensus } from './raft.js';
191
+ export { GossipConsensus } from './gossip.js';
192
+ export { GateQuorumConsensus } from './gate-quorum.js';
193
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/consensus/index.ts"],"names":[],"mappings":"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"}