@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,280 @@
1
+ /**
2
+ * @arcanea/council — Gate Quorum Consensus
3
+ *
4
+ * Arcanea-specific consensus protocol where the Ten Guardians vote
5
+ * with weights determined by their Gate frequency (174-1111 Hz).
6
+ *
7
+ * Higher-frequency Guardians have more voting weight:
8
+ * Lyssandria (174 Hz) = 1.0x weight (broad acceptance, foundation)
9
+ * Shinkami (1111 Hz) = 6.38x weight (selective, source)
10
+ *
11
+ * Element affinity boosts votes from Guardians whose element matches the task.
12
+ * Shinkami can override any decision (Source authority).
13
+ */
14
+ import { EventEmitter } from 'node:events';
15
+ import { GUARDIANS, } from '../external-types.js';
16
+ const BASE_FREQUENCY = 174; // Foundation Gate — lowest frequency
17
+ export class GateQuorumConsensus extends EventEmitter {
18
+ config;
19
+ nodeId;
20
+ nodes = new Map();
21
+ proposals = new Map();
22
+ proposalVotes = new Map();
23
+ initialized = false;
24
+ constructor(nodeId, options = {}) {
25
+ super();
26
+ this.nodeId = nodeId;
27
+ this.config = {
28
+ quorumSize: options.quorumSize ?? 5,
29
+ weightByFrequency: options.weightByFrequency ?? true,
30
+ approvalThreshold: options.approvalThreshold ?? 0.6,
31
+ tieBreaker: options.tieBreaker ?? 'highest-frequency',
32
+ elementAffinity: options.elementAffinity,
33
+ voteTimeoutMs: options.voteTimeoutMs ?? 30000,
34
+ shinkamOverride: options.shinkamOverride ?? true,
35
+ };
36
+ }
37
+ async initialize(config) {
38
+ if (config) {
39
+ this.config = {
40
+ ...this.config,
41
+ approvalThreshold: config.threshold,
42
+ voteTimeoutMs: config.timeoutMs,
43
+ };
44
+ }
45
+ this.initialized = true;
46
+ this.emit('initialized', { nodeId: this.nodeId, protocol: 'gate-quorum' });
47
+ }
48
+ async shutdown() {
49
+ this.proposals.clear();
50
+ this.proposalVotes.clear();
51
+ this.emit('shutdown');
52
+ }
53
+ /**
54
+ * Add a Guardian node to the quorum.
55
+ */
56
+ addNode(nodeId, options) {
57
+ const guardian = options?.guardian;
58
+ if (guardian && GUARDIANS[guardian]) {
59
+ const profile = GUARDIANS[guardian];
60
+ this.nodes.set(nodeId, {
61
+ guardian,
62
+ frequency: profile.frequency,
63
+ element: profile.element,
64
+ });
65
+ }
66
+ else {
67
+ this.nodes.set(nodeId, {
68
+ frequency: BASE_FREQUENCY,
69
+ element: 'void',
70
+ });
71
+ }
72
+ }
73
+ removeNode(nodeId) {
74
+ this.nodes.delete(nodeId);
75
+ }
76
+ /**
77
+ * Submit a petition to the Gate Quorum.
78
+ */
79
+ async propose(value) {
80
+ const petition = {
81
+ id: `gq_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
82
+ petitionerId: this.nodeId,
83
+ value,
84
+ term: 1,
85
+ timestamp: new Date(),
86
+ seals: new Map(),
87
+ status: 'pending',
88
+ };
89
+ this.proposals.set(petition.id, petition);
90
+ this.proposalVotes.set(petition.id, []);
91
+ this.emit('consensus.proposed', {
92
+ proposalId: petition.id,
93
+ protocol: 'gate-quorum',
94
+ quorumSize: this.config.quorumSize,
95
+ });
96
+ return petition;
97
+ }
98
+ /**
99
+ * Cast a vote (seal) on a petition. Weight is calculated from Guardian frequency.
100
+ */
101
+ async vote(petitionId, seal) {
102
+ const petition = this.proposals.get(petitionId);
103
+ if (!petition || petition.status !== 'pending')
104
+ return;
105
+ petition.seals.set(seal.guardianId, seal);
106
+ // Calculate weight from Guardian data
107
+ const nodeData = this.nodes.get(seal.guardianId);
108
+ const frequency = nodeData?.frequency ?? BASE_FREQUENCY;
109
+ const element = nodeData?.element ?? 'void';
110
+ const guardian = nodeData?.guardian;
111
+ let weight = this.config.weightByFrequency
112
+ ? frequency / BASE_FREQUENCY
113
+ : 1.0;
114
+ // Element affinity bonus
115
+ if (this.config.elementAffinity && this.config.elementAffinity === element) {
116
+ weight *= 1.25; // 25% bonus for matching element
117
+ }
118
+ const quorumVote = {
119
+ guardian: guardian ?? 'shinkami',
120
+ frequency,
121
+ element,
122
+ vote: seal.approve ? 'approve' : 'reject',
123
+ weight,
124
+ reason: seal.reason,
125
+ timestamp: Date.now(),
126
+ };
127
+ this.proposalVotes.get(petitionId)?.push(quorumVote);
128
+ // Check if quorum reached
129
+ if (petition.seals.size >= this.config.quorumSize) {
130
+ await this.resolveQuorum(petitionId);
131
+ }
132
+ }
133
+ /**
134
+ * Wait for consensus on a petition.
135
+ */
136
+ async awaitConsensus(petitionId) {
137
+ const petition = this.proposals.get(petitionId);
138
+ if (!petition) {
139
+ throw new Error(`Petition ${petitionId} not found`);
140
+ }
141
+ const startTime = Date.now();
142
+ // Wait for resolution or timeout
143
+ return new Promise((resolve, reject) => {
144
+ const checkInterval = setInterval(() => {
145
+ const p = this.proposals.get(petitionId);
146
+ if (!p) {
147
+ clearInterval(checkInterval);
148
+ reject(new Error('Petition removed'));
149
+ return;
150
+ }
151
+ if (p.status !== 'pending') {
152
+ clearInterval(checkInterval);
153
+ const votes = this.proposalVotes.get(petitionId) ?? [];
154
+ resolve({
155
+ petitionId,
156
+ approved: p.status === 'accepted',
157
+ approvalRate: this.calculateApprovalRate(votes),
158
+ participationRate: votes.length / Math.max(this.nodes.size, 1),
159
+ finalValue: p.value,
160
+ rounds: 1,
161
+ durationMs: Date.now() - startTime,
162
+ });
163
+ return;
164
+ }
165
+ if (Date.now() - startTime > this.config.voteTimeoutMs) {
166
+ clearInterval(checkInterval);
167
+ p.status = 'expired';
168
+ resolve({
169
+ petitionId,
170
+ approved: false,
171
+ approvalRate: 0,
172
+ participationRate: (p.seals.size) / Math.max(this.nodes.size, 1),
173
+ finalValue: p.value,
174
+ rounds: 1,
175
+ durationMs: Date.now() - startTime,
176
+ });
177
+ }
178
+ }, 100);
179
+ });
180
+ }
181
+ // ── Private ──────────────────────────────────────────────
182
+ async resolveQuorum(petitionId) {
183
+ const petition = this.proposals.get(petitionId);
184
+ const votes = this.proposalVotes.get(petitionId);
185
+ if (!petition || !votes)
186
+ return;
187
+ let totalWeight = 0;
188
+ let approvalWeight = 0;
189
+ let rejectionWeight = 0;
190
+ let abstainWeight = 0;
191
+ let shinkamOverrideUsed = false;
192
+ for (const v of votes) {
193
+ totalWeight += v.weight;
194
+ if (v.vote === 'approve')
195
+ approvalWeight += v.weight;
196
+ else if (v.vote === 'reject')
197
+ rejectionWeight += v.weight;
198
+ else
199
+ abstainWeight += v.weight;
200
+ }
201
+ // Check for Shinkami override
202
+ if (this.config.shinkamOverride) {
203
+ const shinkamVote = votes.find((v) => v.guardian === 'shinkami');
204
+ if (shinkamVote && shinkamVote.vote !== 'abstain') {
205
+ // Shinkami at 1111 Hz has overwhelming weight
206
+ petition.status = shinkamVote.vote === 'approve' ? 'accepted' : 'rejected';
207
+ shinkamOverrideUsed = true;
208
+ this.emit('consensus.achieved', {
209
+ petitionId,
210
+ approved: petition.status === 'accepted',
211
+ override: 'shinkami',
212
+ });
213
+ return;
214
+ }
215
+ }
216
+ // Standard weighted vote resolution
217
+ const effectiveTotal = totalWeight - abstainWeight;
218
+ if (effectiveTotal <= 0) {
219
+ petition.status = 'expired';
220
+ return;
221
+ }
222
+ const approvalRatio = approvalWeight / effectiveTotal;
223
+ if (approvalRatio >= this.config.approvalThreshold) {
224
+ petition.status = 'accepted';
225
+ }
226
+ else if ((1 - approvalRatio) >= this.config.approvalThreshold) {
227
+ petition.status = 'rejected';
228
+ }
229
+ else {
230
+ // Tie — use tiebreaker
231
+ petition.status = this.resolveTie(votes);
232
+ }
233
+ const result = {
234
+ approved: petition.status === 'accepted',
235
+ totalWeight,
236
+ approvalWeight,
237
+ rejectionWeight,
238
+ abstainWeight,
239
+ votes,
240
+ shinkamOverrideUsed,
241
+ durationMs: Date.now() - petition.timestamp.getTime(),
242
+ };
243
+ this.emit('consensus.achieved', {
244
+ petitionId,
245
+ ...result,
246
+ });
247
+ }
248
+ resolveTie(votes) {
249
+ switch (this.config.tieBreaker) {
250
+ case 'highest-frequency': {
251
+ // Guardian with highest frequency wins
252
+ const sorted = [...votes].sort((a, b) => b.frequency - a.frequency);
253
+ return sorted[0]?.vote === 'approve' ? 'accepted' : 'rejected';
254
+ }
255
+ case 'element-affinity': {
256
+ // Guardians matching the element affinity win
257
+ if (this.config.elementAffinity) {
258
+ const matching = votes.filter((v) => v.element === this.config.elementAffinity);
259
+ const approvals = matching.filter((v) => v.vote === 'approve').length;
260
+ return approvals > matching.length / 2 ? 'accepted' : 'rejected';
261
+ }
262
+ return 'rejected';
263
+ }
264
+ case 'random':
265
+ default:
266
+ return Math.random() > 0.5 ? 'accepted' : 'rejected';
267
+ }
268
+ }
269
+ calculateApprovalRate(votes) {
270
+ const nonAbstain = votes.filter((v) => v.vote !== 'abstain');
271
+ if (nonAbstain.length === 0)
272
+ return 0;
273
+ const approvals = nonAbstain.filter((v) => v.vote === 'approve');
274
+ return approvals.length / nonAbstain.length;
275
+ }
276
+ }
277
+ export function createGateQuorumConsensus(nodeId, options) {
278
+ return new GateQuorumConsensus(nodeId, options);
279
+ }
280
+ //# sourceMappingURL=gate-quorum.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate-quorum.js","sourceRoot":"","sources":["../../src/consensus/gate-quorum.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * V3 Gossip Protocol Consensus
3
+ * Eventually consistent consensus for large-scale distributed systems
4
+ */
5
+ import { EventEmitter } from 'events';
6
+ import { ConsensusProposal, ConsensusVote, ConsensusResult, ConsensusConfig } from '../types.js';
7
+ export interface GossipMessage {
8
+ id: string;
9
+ type: 'proposal' | 'vote' | 'state' | 'ack';
10
+ senderId: string;
11
+ version: number;
12
+ payload: unknown;
13
+ timestamp: Date;
14
+ ttl: number;
15
+ hops: number;
16
+ path: string[];
17
+ }
18
+ export interface GossipNode {
19
+ id: string;
20
+ state: Map<string, unknown>;
21
+ version: number;
22
+ neighbors: Set<string>;
23
+ seenMessages: Set<string>;
24
+ lastSync: Date;
25
+ }
26
+ export interface GossipConfig extends Partial<ConsensusConfig> {
27
+ fanout?: number;
28
+ gossipIntervalMs?: number;
29
+ maxHops?: number;
30
+ convergenceThreshold?: number;
31
+ }
32
+ export declare class GossipConsensus extends EventEmitter {
33
+ private config;
34
+ private node;
35
+ private nodes;
36
+ private proposals;
37
+ private messageQueue;
38
+ private gossipInterval?;
39
+ private proposalCounter;
40
+ constructor(nodeId: string, config?: GossipConfig);
41
+ initialize(): Promise<void>;
42
+ shutdown(): Promise<void>;
43
+ addNode(nodeId: string): void;
44
+ removeNode(nodeId: string): void;
45
+ addNeighbor(nodeId: string): void;
46
+ removeNeighbor(nodeId: string): void;
47
+ propose(value: unknown): Promise<ConsensusProposal>;
48
+ vote(proposalId: string, vote: ConsensusVote): Promise<void>;
49
+ awaitConsensus(proposalId: string): Promise<ConsensusResult>;
50
+ private startGossipLoop;
51
+ private gossipRound;
52
+ private selectRandomNeighbors;
53
+ private sendToNeighbor;
54
+ private processReceivedMessage;
55
+ private handleProposalMessage;
56
+ private handleVoteMessage;
57
+ private handleStateMessage;
58
+ private queueMessage;
59
+ private checkConvergence;
60
+ private createResult;
61
+ getConvergence(proposalId: string): number;
62
+ getVersion(): number;
63
+ getNeighborCount(): number;
64
+ getSeenMessageCount(): number;
65
+ getQueueDepth(): number;
66
+ antiEntropy(): Promise<void>;
67
+ }
68
+ export declare function createGossipConsensus(nodeId: string, config?: GossipConfig): GossipConsensus;
69
+ //# sourceMappingURL=gossip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gossip.d.ts","sourceRoot":"","sources":["../../src/consensus/gossip.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,eAAe,EAEhB,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,IAAI,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACvB,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B,QAAQ,EAAE,IAAI,CAAC;CAChB;AAED,MAAM,WAAW,YAAa,SAAQ,OAAO,CAAC,eAAe,CAAC;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,KAAK,CAAsC;IACnD,OAAO,CAAC,SAAS,CAA6C;IAC9D,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,cAAc,CAAC,CAAiB;IACxC,OAAO,CAAC,eAAe,CAAa;gBAExB,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,YAAiB;IAuB/C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAK3B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAO/B,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAiB7B,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAShC,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAMjC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI9B,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA2CnD,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IA2B5D,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IA2ClE,OAAO,CAAC,eAAe;YAMT,WAAW;IAwBzB,OAAO,CAAC,qBAAqB;YAYf,cAAc;YAwBd,sBAAsB;YAsCtB,qBAAqB;YAkCrB,iBAAiB;YAgBjB,kBAAkB;IAehC,OAAO,CAAC,YAAY;YAQN,gBAAgB;IA2B9B,OAAO,CAAC,YAAY;IAqBpB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAQ1C,UAAU,IAAI,MAAM;IAIpB,gBAAgB,IAAI,MAAM;IAI1B,mBAAmB,IAAI,MAAM;IAI7B,aAAa,IAAI,MAAM;IAKjB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;CAoBnC;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,YAAY,GACpB,eAAe,CAEjB"}