@claude-flow/plugin-agent-federation 1.0.0-alpha.10

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 (90) hide show
  1. package/README.md +45 -0
  2. package/dist/application/federation-breaker-service.d.ts +182 -0
  3. package/dist/application/federation-breaker-service.d.ts.map +1 -0
  4. package/dist/application/federation-breaker-service.js +251 -0
  5. package/dist/application/federation-breaker-service.js.map +1 -0
  6. package/dist/application/federation-coordinator.d.ts +166 -0
  7. package/dist/application/federation-coordinator.d.ts.map +1 -0
  8. package/dist/application/federation-coordinator.js +412 -0
  9. package/dist/application/federation-coordinator.js.map +1 -0
  10. package/dist/application/inbound-dispatcher.d.ts +59 -0
  11. package/dist/application/inbound-dispatcher.d.ts.map +1 -0
  12. package/dist/application/inbound-dispatcher.js +96 -0
  13. package/dist/application/inbound-dispatcher.js.map +1 -0
  14. package/dist/application/policy-engine.d.ts +41 -0
  15. package/dist/application/policy-engine.d.ts.map +1 -0
  16. package/dist/application/policy-engine.js +184 -0
  17. package/dist/application/policy-engine.js.map +1 -0
  18. package/dist/application/spend-reporter.d.ts +150 -0
  19. package/dist/application/spend-reporter.d.ts.map +1 -0
  20. package/dist/application/spend-reporter.js +128 -0
  21. package/dist/application/spend-reporter.js.map +1 -0
  22. package/dist/application/trust-evaluator.d.ts +42 -0
  23. package/dist/application/trust-evaluator.d.ts.map +1 -0
  24. package/dist/application/trust-evaluator.js +132 -0
  25. package/dist/application/trust-evaluator.js.map +1 -0
  26. package/dist/bin.d.ts +13 -0
  27. package/dist/bin.d.ts.map +1 -0
  28. package/dist/bin.js +189 -0
  29. package/dist/bin.js.map +1 -0
  30. package/dist/cli-commands.d.ts +7 -0
  31. package/dist/cli-commands.d.ts.map +1 -0
  32. package/dist/cli-commands.js +198 -0
  33. package/dist/cli-commands.js.map +1 -0
  34. package/dist/domain/entities/federation-envelope.d.ts +45 -0
  35. package/dist/domain/entities/federation-envelope.d.ts.map +1 -0
  36. package/dist/domain/entities/federation-envelope.js +71 -0
  37. package/dist/domain/entities/federation-envelope.js.map +1 -0
  38. package/dist/domain/entities/federation-node.d.ts +104 -0
  39. package/dist/domain/entities/federation-node.d.ts.map +1 -0
  40. package/dist/domain/entities/federation-node.js +152 -0
  41. package/dist/domain/entities/federation-node.js.map +1 -0
  42. package/dist/domain/entities/federation-session.d.ts +55 -0
  43. package/dist/domain/entities/federation-session.d.ts.map +1 -0
  44. package/dist/domain/entities/federation-session.js +105 -0
  45. package/dist/domain/entities/federation-session.js.map +1 -0
  46. package/dist/domain/entities/trust-level.d.ts +17 -0
  47. package/dist/domain/entities/trust-level.d.ts.map +1 -0
  48. package/dist/domain/entities/trust-level.js +35 -0
  49. package/dist/domain/entities/trust-level.js.map +1 -0
  50. package/dist/domain/services/audit-service.d.ts +69 -0
  51. package/dist/domain/services/audit-service.d.ts.map +1 -0
  52. package/dist/domain/services/audit-service.js +149 -0
  53. package/dist/domain/services/audit-service.js.map +1 -0
  54. package/dist/domain/services/discovery-service.d.ts +51 -0
  55. package/dist/domain/services/discovery-service.d.ts.map +1 -0
  56. package/dist/domain/services/discovery-service.js +140 -0
  57. package/dist/domain/services/discovery-service.js.map +1 -0
  58. package/dist/domain/services/handshake-service.d.ts +48 -0
  59. package/dist/domain/services/handshake-service.d.ts.map +1 -0
  60. package/dist/domain/services/handshake-service.js +94 -0
  61. package/dist/domain/services/handshake-service.js.map +1 -0
  62. package/dist/domain/services/pii-pipeline-service.d.ts +65 -0
  63. package/dist/domain/services/pii-pipeline-service.d.ts.map +1 -0
  64. package/dist/domain/services/pii-pipeline-service.js +208 -0
  65. package/dist/domain/services/pii-pipeline-service.js.map +1 -0
  66. package/dist/domain/services/routing-service.d.ts +51 -0
  67. package/dist/domain/services/routing-service.d.ts.map +1 -0
  68. package/dist/domain/services/routing-service.js +147 -0
  69. package/dist/domain/services/routing-service.js.map +1 -0
  70. package/dist/domain/value-objects/federation-budget.d.ts +89 -0
  71. package/dist/domain/value-objects/federation-budget.d.ts.map +1 -0
  72. package/dist/domain/value-objects/federation-budget.js +165 -0
  73. package/dist/domain/value-objects/federation-budget.js.map +1 -0
  74. package/dist/domain/value-objects/federation-node-state.d.ts +92 -0
  75. package/dist/domain/value-objects/federation-node-state.d.ts.map +1 -0
  76. package/dist/domain/value-objects/federation-node-state.js +100 -0
  77. package/dist/domain/value-objects/federation-node-state.js.map +1 -0
  78. package/dist/index.d.ts +17 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +17 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/mcp-tools.d.ts +8 -0
  83. package/dist/mcp-tools.d.ts.map +1 -0
  84. package/dist/mcp-tools.js +343 -0
  85. package/dist/mcp-tools.js.map +1 -0
  86. package/dist/plugin.d.ts +18 -0
  87. package/dist/plugin.d.ts.map +1 -0
  88. package/dist/plugin.js +376 -0
  89. package/dist/plugin.js.map +1 -0
  90. package/package.json +44 -0
@@ -0,0 +1,208 @@
1
+ import { TrustLevel } from '../entities/trust-level.js';
2
+ const DEFAULT_CONFIDENCE_THRESHOLDS = {
3
+ autoBlock: 0.95,
4
+ autoRedact: 0.85,
5
+ flagForReview: 0.6,
6
+ ignore: 0.6,
7
+ };
8
+ const PII_PATTERNS = {
9
+ email: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g,
10
+ ssn: /\b\d{3}-\d{2}-\d{4}\b/g,
11
+ credit_card: /\b(?:\d{4}[-\s]?){3}\d{4}\b/g,
12
+ api_key: /\b(?:sk-[a-zA-Z0-9]{20,}|key-[a-zA-Z0-9]{20,})\b/g,
13
+ password: /(?:password|passwd|pwd)\s*[:=]\s*['"]?[^\s'"]{8,}['"]?/gi,
14
+ name: /\b(?:Mr\.|Mrs\.|Ms\.|Dr\.)\s+[A-Z][a-z]+(?:\s+[A-Z][a-z]+)+\b/g,
15
+ address: /\b\d{1,5}\s+(?:[A-Z][a-z]+\s+){1,3}(?:St|Ave|Blvd|Dr|Ln|Rd|Way|Ct)\b/g,
16
+ phone: /(?:\+?1[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/g,
17
+ ip_address: /\b(?:\d{1,3}\.){3}\d{1,3}\b|(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}/g,
18
+ jwt: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g,
19
+ aws_key: /\bAKIA[0-9A-Z]{16}\b/g,
20
+ private_key: /-----BEGIN\s+(?:RSA\s+|EC\s+|DSA\s+)?PRIVATE\s+KEY-----/g,
21
+ database_url: /(?:postgres|mysql|mongodb|redis):\/\/[^\s]+/g,
22
+ github_token: /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{36,}\b/g,
23
+ };
24
+ const DEFAULT_POLICY_MATRIX = {
25
+ ssn: { [TrustLevel.UNTRUSTED]: 'block', [TrustLevel.VERIFIED]: 'block', [TrustLevel.ATTESTED]: 'block', [TrustLevel.TRUSTED]: 'block', [TrustLevel.PRIVILEGED]: 'block' },
26
+ credit_card: { [TrustLevel.UNTRUSTED]: 'block', [TrustLevel.VERIFIED]: 'block', [TrustLevel.ATTESTED]: 'block', [TrustLevel.TRUSTED]: 'block', [TrustLevel.PRIVILEGED]: 'block' },
27
+ api_key: { [TrustLevel.UNTRUSTED]: 'block', [TrustLevel.VERIFIED]: 'block', [TrustLevel.ATTESTED]: 'block', [TrustLevel.TRUSTED]: 'block', [TrustLevel.PRIVILEGED]: 'redact' },
28
+ password: { [TrustLevel.UNTRUSTED]: 'block', [TrustLevel.VERIFIED]: 'block', [TrustLevel.ATTESTED]: 'block', [TrustLevel.TRUSTED]: 'block', [TrustLevel.PRIVILEGED]: 'block' },
29
+ email: { [TrustLevel.UNTRUSTED]: 'block', [TrustLevel.VERIFIED]: 'block', [TrustLevel.ATTESTED]: 'redact', [TrustLevel.TRUSTED]: 'hash', [TrustLevel.PRIVILEGED]: 'pass' },
30
+ phone: { [TrustLevel.UNTRUSTED]: 'block', [TrustLevel.VERIFIED]: 'block', [TrustLevel.ATTESTED]: 'redact', [TrustLevel.TRUSTED]: 'hash', [TrustLevel.PRIVILEGED]: 'pass' },
31
+ name: { [TrustLevel.UNTRUSTED]: 'block', [TrustLevel.VERIFIED]: 'block', [TrustLevel.ATTESTED]: 'redact', [TrustLevel.TRUSTED]: 'redact', [TrustLevel.PRIVILEGED]: 'pass' },
32
+ ip_address: { [TrustLevel.UNTRUSTED]: 'block', [TrustLevel.VERIFIED]: 'block', [TrustLevel.ATTESTED]: 'hash', [TrustLevel.TRUSTED]: 'hash', [TrustLevel.PRIVILEGED]: 'pass' },
33
+ jwt: { [TrustLevel.UNTRUSTED]: 'block', [TrustLevel.VERIFIED]: 'block', [TrustLevel.ATTESTED]: 'block', [TrustLevel.TRUSTED]: 'block', [TrustLevel.PRIVILEGED]: 'redact' },
34
+ aws_key: { [TrustLevel.UNTRUSTED]: 'block', [TrustLevel.VERIFIED]: 'block', [TrustLevel.ATTESTED]: 'block', [TrustLevel.TRUSTED]: 'block', [TrustLevel.PRIVILEGED]: 'block' },
35
+ private_key: { [TrustLevel.UNTRUSTED]: 'block', [TrustLevel.VERIFIED]: 'block', [TrustLevel.ATTESTED]: 'block', [TrustLevel.TRUSTED]: 'block', [TrustLevel.PRIVILEGED]: 'block' },
36
+ database_url: { [TrustLevel.UNTRUSTED]: 'block', [TrustLevel.VERIFIED]: 'block', [TrustLevel.ATTESTED]: 'block', [TrustLevel.TRUSTED]: 'block', [TrustLevel.PRIVILEGED]: 'redact' },
37
+ github_token: { [TrustLevel.UNTRUSTED]: 'block', [TrustLevel.VERIFIED]: 'block', [TrustLevel.ATTESTED]: 'block', [TrustLevel.TRUSTED]: 'block', [TrustLevel.PRIVILEGED]: 'redact' },
38
+ address: { [TrustLevel.UNTRUSTED]: 'block', [TrustLevel.VERIFIED]: 'block', [TrustLevel.ATTESTED]: 'redact', [TrustLevel.TRUSTED]: 'redact', [TrustLevel.PRIVILEGED]: 'pass' },
39
+ };
40
+ export class PIIPipelineService {
41
+ deps;
42
+ policy;
43
+ calibrations;
44
+ confidenceThresholds;
45
+ constructor(deps, policy, confidenceThresholds) {
46
+ this.deps = deps;
47
+ this.policy = {
48
+ defaultAction: policy?.defaultAction ?? 'redact',
49
+ overrides: policy?.overrides ?? {},
50
+ hashAlgorithm: policy?.hashAlgorithm ?? 'sha256',
51
+ hashSalt: policy?.hashSalt ?? '',
52
+ redactionPlaceholder: policy?.redactionPlaceholder ?? '[REDACTED:{type}]',
53
+ };
54
+ this.calibrations = new Map();
55
+ this.confidenceThresholds = { ...DEFAULT_CONFIDENCE_THRESHOLDS, ...confidenceThresholds };
56
+ }
57
+ detect(text) {
58
+ const detections = [];
59
+ for (const [type, pattern] of Object.entries(PII_PATTERNS)) {
60
+ const regex = new RegExp(pattern.source, pattern.flags);
61
+ let match;
62
+ while ((match = regex.exec(text)) !== null) {
63
+ const contextStart = Math.max(0, match.index - 20);
64
+ const contextEnd = Math.min(text.length, match.index + match[0].length + 20);
65
+ const confidence = this.computeConfidence(type, match[0], text);
66
+ detections.push({
67
+ type: type,
68
+ value: match[0],
69
+ confidence,
70
+ offset: match.index,
71
+ context: text.slice(contextStart, contextEnd),
72
+ });
73
+ }
74
+ }
75
+ return detections.sort((a, b) => b.offset - a.offset);
76
+ }
77
+ classify(detections) {
78
+ const classified = new Map();
79
+ for (const detection of detections) {
80
+ const existing = classified.get(detection.type) ?? [];
81
+ existing.push(detection);
82
+ classified.set(detection.type, existing);
83
+ }
84
+ return classified;
85
+ }
86
+ evaluate(detection, trustLevel) {
87
+ if (detection.confidence < this.getEffectiveThreshold(detection.type)) {
88
+ return 'pass';
89
+ }
90
+ const override = this.policy.overrides[detection.type];
91
+ if (override?.trustLevelOverride?.[trustLevel]) {
92
+ return override.trustLevelOverride[trustLevel];
93
+ }
94
+ const defaultMatrix = DEFAULT_POLICY_MATRIX[detection.type];
95
+ if (defaultMatrix) {
96
+ return defaultMatrix[trustLevel];
97
+ }
98
+ return this.policy.defaultAction;
99
+ }
100
+ transform(text, trustLevel) {
101
+ const detections = this.detect(text);
102
+ const actionsApplied = [];
103
+ let transformedText = text;
104
+ let blocked = false;
105
+ const sortedDetections = [...detections].sort((a, b) => b.offset - a.offset);
106
+ for (const detection of sortedDetections) {
107
+ const action = this.evaluate(detection, trustLevel);
108
+ actionsApplied.push({ type: detection.type, action });
109
+ switch (action) {
110
+ case 'block':
111
+ blocked = true;
112
+ break;
113
+ case 'redact': {
114
+ const placeholder = this.policy.redactionPlaceholder.replace('{type}', detection.type);
115
+ transformedText =
116
+ transformedText.slice(0, detection.offset) +
117
+ placeholder +
118
+ transformedText.slice(detection.offset + detection.value.length);
119
+ break;
120
+ }
121
+ case 'hash': {
122
+ const hashed = this.deps.hashFunction(detection.value, this.policy.hashSalt);
123
+ const hashPlaceholder = `[HASH:${detection.type}:${hashed.slice(0, 8)}]`;
124
+ transformedText =
125
+ transformedText.slice(0, detection.offset) +
126
+ hashPlaceholder +
127
+ transformedText.slice(detection.offset + detection.value.length);
128
+ break;
129
+ }
130
+ case 'pass':
131
+ break;
132
+ }
133
+ }
134
+ return {
135
+ originalText: text,
136
+ transformedText: blocked ? '' : transformedText,
137
+ detections,
138
+ actionsApplied,
139
+ blocked,
140
+ };
141
+ }
142
+ updateCalibration(type, calibration) {
143
+ this.calibrations.set(type, calibration);
144
+ }
145
+ getCalibration(type) {
146
+ return this.calibrations.get(type);
147
+ }
148
+ computeConfidence(type, value, _fullText) {
149
+ const calibration = this.calibrations.get(type);
150
+ let baseConfidence;
151
+ switch (type) {
152
+ case 'ssn':
153
+ case 'credit_card':
154
+ case 'aws_key':
155
+ case 'github_token':
156
+ baseConfidence = 0.95;
157
+ break;
158
+ case 'email':
159
+ case 'jwt':
160
+ case 'private_key':
161
+ case 'database_url':
162
+ baseConfidence = 0.9;
163
+ break;
164
+ case 'api_key':
165
+ case 'password':
166
+ baseConfidence = 0.85;
167
+ break;
168
+ case 'phone':
169
+ case 'ip_address':
170
+ baseConfidence = 0.8;
171
+ break;
172
+ case 'name':
173
+ case 'address':
174
+ baseConfidence = 0.7;
175
+ break;
176
+ default:
177
+ baseConfidence = 0.75;
178
+ }
179
+ if (value.length < 5) {
180
+ baseConfidence *= 0.8;
181
+ }
182
+ if (calibration && calibration.totalOverrides > 10) {
183
+ const fpAdjustment = calibration.falsePositiveRate * 0.1;
184
+ baseConfidence = Math.max(0.1, baseConfidence - fpAdjustment);
185
+ }
186
+ return Math.min(1.0, Math.max(0.0, baseConfidence));
187
+ }
188
+ getEffectiveThreshold(type) {
189
+ const calibration = this.calibrations.get(type);
190
+ if (calibration && calibration.totalOverrides > 10) {
191
+ return calibration.adjustedThreshold;
192
+ }
193
+ return this.confidenceThresholds.ignore;
194
+ }
195
+ static defaultPolicy() {
196
+ return {
197
+ defaultAction: 'redact',
198
+ overrides: {},
199
+ hashAlgorithm: 'sha256',
200
+ hashSalt: '',
201
+ redactionPlaceholder: '[REDACTED:{type}]',
202
+ };
203
+ }
204
+ static defaultPolicyMatrix() {
205
+ return { ...DEFAULT_POLICY_MATRIX };
206
+ }
207
+ }
208
+ //# sourceMappingURL=pii-pipeline-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pii-pipeline-service.js","sourceRoot":"","sources":["../../../src/domain/services/pii-pipeline-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import { FederationEnvelope, type FederationEnvelopeProps, type FederationMessageType } from '../entities/federation-envelope.js';
2
+ import { FederationSession } from '../entities/federation-session.js';
3
+ export type RoutingMode = 'direct' | 'broadcast' | 'consensus';
4
+ export interface RoutingResult {
5
+ readonly success: boolean;
6
+ readonly mode: RoutingMode;
7
+ readonly envelopeId: string;
8
+ readonly targetNodeIds: readonly string[];
9
+ readonly error?: string;
10
+ readonly latencyMs?: number;
11
+ }
12
+ export interface ConsensusProposal {
13
+ readonly proposalId: string;
14
+ readonly proposerNodeId: string;
15
+ readonly messageType: FederationMessageType;
16
+ readonly payload: unknown;
17
+ readonly quorumRequired: number;
18
+ readonly votes: Map<string, boolean>;
19
+ readonly createdAt: Date;
20
+ readonly expiresAt: Date;
21
+ }
22
+ export interface RoutingServiceDeps {
23
+ generateEnvelopeId: () => string;
24
+ generateNonce: () => string;
25
+ signEnvelope: (payload: string, sessionToken: string) => string;
26
+ verifyEnvelope: (payload: string, signature: string, sessionToken: string) => boolean;
27
+ scanPii: (text: string, trustLevel: number) => {
28
+ transformedText: string;
29
+ scanResult: FederationEnvelopeProps['piiScanResult'];
30
+ };
31
+ sendToNode: (nodeId: string, envelope: FederationEnvelope) => Promise<void>;
32
+ getActiveSessions: () => FederationSession[];
33
+ getLocalNodeId: () => string;
34
+ }
35
+ export declare class RoutingService {
36
+ private readonly deps;
37
+ private readonly pendingProposals;
38
+ constructor(deps: RoutingServiceDeps);
39
+ selectMode(messageType: FederationMessageType): RoutingMode;
40
+ send<T>(session: FederationSession, messageType: FederationMessageType, payload: T): Promise<RoutingResult>;
41
+ broadcast<T>(messageType: FederationMessageType, payload: T): Promise<RoutingResult[]>;
42
+ propose<T>(messageType: FederationMessageType, payload: T, quorumFraction?: number): Promise<ConsensusProposal>;
43
+ recordVote(proposalId: string, nodeId: string, vote: boolean): boolean;
44
+ isConsensusReached(proposalId: string): {
45
+ reached: boolean;
46
+ approved: boolean;
47
+ };
48
+ verifyInboundEnvelope(envelope: FederationEnvelope, sessionToken: string): boolean;
49
+ cleanExpiredProposals(): void;
50
+ }
51
+ //# sourceMappingURL=routing-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routing-service.d.ts","sourceRoot":"","sources":["../../../src/domain/services/routing-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,147 @@
1
+ import { FederationEnvelope, CONSENSUS_REQUIRED_TYPES, } from '../entities/federation-envelope.js';
2
+ export class RoutingService {
3
+ deps;
4
+ pendingProposals;
5
+ constructor(deps) {
6
+ this.deps = deps;
7
+ this.pendingProposals = new Map();
8
+ }
9
+ selectMode(messageType) {
10
+ if (CONSENSUS_REQUIRED_TYPES.has(messageType)) {
11
+ return 'consensus';
12
+ }
13
+ if (messageType === 'status-broadcast') {
14
+ return 'broadcast';
15
+ }
16
+ return 'direct';
17
+ }
18
+ async send(session, messageType, payload) {
19
+ const startTime = Date.now();
20
+ if (!session.active) {
21
+ return { success: false, mode: 'direct', envelopeId: '', targetNodeIds: [], error: 'Session is not active' };
22
+ }
23
+ if (session.isExpired()) {
24
+ return { success: false, mode: 'direct', envelopeId: '', targetNodeIds: [], error: 'Session has expired' };
25
+ }
26
+ const payloadStr = JSON.stringify(payload);
27
+ const { transformedText, scanResult } = this.deps.scanPii(payloadStr, session.trustLevel);
28
+ if (scanResult.piiFound && scanResult.actionsApplied.includes('block')) {
29
+ return { success: false, mode: 'direct', envelopeId: '', targetNodeIds: [session.remoteNodeId], error: 'Message blocked by PII policy' };
30
+ }
31
+ const envelopeId = this.deps.generateEnvelopeId();
32
+ const nonce = this.deps.generateNonce();
33
+ const timestamp = new Date();
34
+ const unsignedPayload = JSON.stringify({
35
+ envelopeId,
36
+ sourceNodeId: session.localNodeId,
37
+ targetNodeId: session.remoteNodeId,
38
+ sessionId: session.sessionId,
39
+ messageType,
40
+ payload: JSON.parse(transformedText),
41
+ timestamp: timestamp.toISOString(),
42
+ nonce,
43
+ });
44
+ const hmacSignature = this.deps.signEnvelope(unsignedPayload, session.sessionToken);
45
+ const envelope = new FederationEnvelope({
46
+ envelopeId,
47
+ sourceNodeId: session.localNodeId,
48
+ targetNodeId: session.remoteNodeId,
49
+ sessionId: session.sessionId,
50
+ messageType,
51
+ payload: JSON.parse(transformedText),
52
+ timestamp,
53
+ nonce,
54
+ hmacSignature,
55
+ piiScanResult: scanResult,
56
+ });
57
+ try {
58
+ await this.deps.sendToNode(session.remoteNodeId, envelope);
59
+ session.recordMessageSent();
60
+ if (scanResult.piiFound) {
61
+ session.recordPiiRedaction();
62
+ }
63
+ return {
64
+ success: true,
65
+ mode: 'direct',
66
+ envelopeId,
67
+ targetNodeIds: [session.remoteNodeId],
68
+ latencyMs: Date.now() - startTime,
69
+ };
70
+ }
71
+ catch (err) {
72
+ const errorMsg = err instanceof Error ? err.message : String(err);
73
+ return { success: false, mode: 'direct', envelopeId, targetNodeIds: [session.remoteNodeId], error: errorMsg };
74
+ }
75
+ }
76
+ async broadcast(messageType, payload) {
77
+ const sessions = this.deps.getActiveSessions().filter(s => s.active && !s.isExpired());
78
+ const results = [];
79
+ for (const session of sessions) {
80
+ const result = await this.send(session, messageType, payload);
81
+ results.push(result);
82
+ }
83
+ return results;
84
+ }
85
+ async propose(messageType, payload, quorumFraction = 2 / 3) {
86
+ const sessions = this.deps.getActiveSessions().filter(s => s.active && !s.isExpired());
87
+ const quorumRequired = Math.ceil(sessions.length * quorumFraction);
88
+ const proposal = {
89
+ proposalId: this.deps.generateEnvelopeId(),
90
+ proposerNodeId: this.deps.getLocalNodeId(),
91
+ messageType,
92
+ payload,
93
+ quorumRequired,
94
+ votes: new Map(),
95
+ createdAt: new Date(),
96
+ expiresAt: new Date(Date.now() + 30_000),
97
+ };
98
+ this.pendingProposals.set(proposal.proposalId, proposal);
99
+ await this.broadcast(messageType, {
100
+ type: 'consensus-proposal',
101
+ proposalId: proposal.proposalId,
102
+ messageType,
103
+ payload,
104
+ quorumRequired,
105
+ });
106
+ return proposal;
107
+ }
108
+ recordVote(proposalId, nodeId, vote) {
109
+ const proposal = this.pendingProposals.get(proposalId);
110
+ if (!proposal)
111
+ return false;
112
+ if (new Date() > proposal.expiresAt) {
113
+ this.pendingProposals.delete(proposalId);
114
+ return false;
115
+ }
116
+ proposal.votes.set(nodeId, vote);
117
+ return true;
118
+ }
119
+ isConsensusReached(proposalId) {
120
+ const proposal = this.pendingProposals.get(proposalId);
121
+ if (!proposal)
122
+ return { reached: false, approved: false };
123
+ const approvals = Array.from(proposal.votes.values()).filter(v => v).length;
124
+ if (approvals >= proposal.quorumRequired) {
125
+ return { reached: true, approved: true };
126
+ }
127
+ const rejections = Array.from(proposal.votes.values()).filter(v => !v).length;
128
+ const totalVoters = this.deps.getActiveSessions().length;
129
+ if (rejections > totalVoters - proposal.quorumRequired) {
130
+ return { reached: true, approved: false };
131
+ }
132
+ return { reached: false, approved: false };
133
+ }
134
+ verifyInboundEnvelope(envelope, sessionToken) {
135
+ const signablePayload = envelope.toSignablePayload();
136
+ return this.deps.verifyEnvelope(signablePayload, envelope.hmacSignature, sessionToken);
137
+ }
138
+ cleanExpiredProposals() {
139
+ const now = new Date();
140
+ for (const [id, proposal] of this.pendingProposals) {
141
+ if (now > proposal.expiresAt) {
142
+ this.pendingProposals.delete(id);
143
+ }
144
+ }
145
+ }
146
+ }
147
+ //# sourceMappingURL=routing-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routing-service.js","sourceRoot":"","sources":["../../../src/domain/services/routing-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Federation budget + hop counter (ADR-097 Phase 1).
3
+ *
4
+ * Carried in {@link FederationEnvelope} alongside the existing
5
+ * sourceNodeId/targetNodeId/payload. Sender supplies the original limits;
6
+ * each outbound hop increments hopCount and decrements remaining budget.
7
+ *
8
+ * Phase 1 enforces at the *send* side because there is no inbound
9
+ * dispatcher today (sendToNode is a stub — see researcher report).
10
+ * Phase 2 will move the decrement to receive once the inbound path lands.
11
+ *
12
+ * Security invariants pinned by the reviewer (audit_1776853149979 follow-up):
13
+ *
14
+ * 1. validateBudget rejects NaN, ±Infinity, negative numbers, and
15
+ * non-integer hop counts. Returns a discriminated result so callers
16
+ * cannot accidentally use a bad budget unchecked.
17
+ * 2. enforceBudget runs check-then-decrement in a single synchronous
18
+ * function with no awaits inside — two concurrent send calls cannot
19
+ * both pass the pre-check.
20
+ * 3. Errors return constant strings ("HOP_LIMIT_EXCEEDED" /
21
+ * "BUDGET_EXCEEDED") with no remaining-budget echo so a caller can't
22
+ * use the error response as an oracle for the threshold.
23
+ */
24
+ /** Maximum hops a federation message may travel before the breaker opens. */
25
+ export declare const DEFAULT_MAX_HOPS = 8;
26
+ /**
27
+ * Caller-supplied budget. All fields are optional; omitted fields are
28
+ * treated as Infinity for the corresponding axis. Created via validateBudget;
29
+ * never construct directly.
30
+ */
31
+ export interface Budget {
32
+ readonly maxHops: number;
33
+ readonly maxTokens: number;
34
+ readonly maxUsd: number;
35
+ }
36
+ /** Discriminated result of validating raw user input into a Budget. */
37
+ export type BudgetValidationResult = {
38
+ ok: true;
39
+ budget: Budget;
40
+ } | {
41
+ ok: false;
42
+ error: string;
43
+ };
44
+ /**
45
+ * Validate a raw budget object. Pure, no side effects. Caller obtains either
46
+ * a guaranteed-safe Budget or a structured error suitable for logging.
47
+ *
48
+ * Accepts undefined/null and returns a default unbounded budget (maxHops =
49
+ * DEFAULT_MAX_HOPS, tokens/usd = Infinity). This preserves backward
50
+ * compatibility for callers that don't pass a budget at all.
51
+ */
52
+ export declare function validateBudget(raw: unknown, overrideMaxHops?: unknown): BudgetValidationResult;
53
+ /**
54
+ * Enforcement decision returned by enforceBudget. Discriminated so the
55
+ * caller can map directly to a constant-string error — no remaining-budget
56
+ * echo on the failure side (anti-oracle).
57
+ */
58
+ export type BudgetEnforcement = {
59
+ ok: true;
60
+ nextHopCount: number;
61
+ remaining: Budget;
62
+ } | {
63
+ ok: false;
64
+ reason: 'HOP_LIMIT_EXCEEDED' | 'BUDGET_EXCEEDED';
65
+ };
66
+ /**
67
+ * Atomic (single synchronous function, no internal awaits) hop check.
68
+ *
69
+ * Returns the hopCount value the OUTBOUND envelope should carry plus the
70
+ * remaining budget that downstream peers will see. Callers must use the
71
+ * returned values; mutating the input Budget is forbidden (it's readonly).
72
+ *
73
+ * Contract:
74
+ * - hopCount represents how many hops the message has already taken.
75
+ * - The next outbound hop increments it: nextHopCount = hopCount + 1.
76
+ * - The check fires AFTER increment: nextHopCount must be <= maxHops.
77
+ * - This means maxHops=0 refuses to forward at all, which matches the
78
+ * ADR's "no remote delegation allowed" semantic.
79
+ *
80
+ * tokensSpent / usdSpent are caller-reported actuals from the immediately
81
+ * preceding leg (or 0 on the originator). The check fires on the
82
+ * *post-spend* totals so a leg that overshoots is caught before the next
83
+ * outbound dispatch.
84
+ */
85
+ export declare function enforceBudget(budget: Budget, hopCount: number, spent?: {
86
+ tokens: number;
87
+ usd: number;
88
+ }): BudgetEnforcement;
89
+ //# sourceMappingURL=federation-budget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"federation-budget.d.ts","sourceRoot":"","sources":["../../../src/domain/value-objects/federation-budget.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,6EAA6E;AAC7E,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAQlC;;;;GAIG;AACH,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,uEAAuE;AACvE,MAAM,MAAM,sBAAsB,GAC9B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC5B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjC;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,OAAO,EACZ,eAAe,CAAC,EAAE,OAAO,GACxB,sBAAsB,CA6DxB;AAkCD;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GACzB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,oBAAoB,GAAG,iBAAiB,CAAA;CAAE,CAAC;AAEpE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,KAAK,GAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAA0B,GAC7D,iBAAiB,CAuBnB"}