@claude-flow/plugin-agent-federation 1.0.0-alpha.9 → 1.0.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.
- package/README.md +4 -0
- package/dist/a2a/agent-card.d.ts +130 -0
- package/dist/a2a/agent-card.d.ts.map +1 -0
- package/dist/a2a/agent-card.js +239 -0
- package/dist/a2a/agent-card.js.map +1 -0
- package/dist/a2a/consume.d.ts +34 -0
- package/dist/a2a/consume.d.ts.map +1 -0
- package/dist/a2a/consume.js +69 -0
- package/dist/a2a/consume.js.map +1 -0
- package/dist/a2a/planner-descriptor.d.ts +40 -0
- package/dist/a2a/planner-descriptor.d.ts.map +1 -0
- package/dist/a2a/planner-descriptor.js +100 -0
- package/dist/a2a/planner-descriptor.js.map +1 -0
- package/dist/a2a/well-known.d.ts +46 -0
- package/dist/a2a/well-known.d.ts.map +1 -0
- package/dist/a2a/well-known.js +84 -0
- package/dist/a2a/well-known.js.map +1 -0
- package/dist/application/claim-checker.d.ts +27 -0
- package/dist/application/claim-checker.d.ts.map +1 -0
- package/dist/application/claim-checker.js +46 -0
- package/dist/application/claim-checker.js.map +1 -0
- package/dist/application/federation-breaker-service.d.ts +11 -1
- package/dist/application/federation-breaker-service.d.ts.map +1 -1
- package/dist/application/federation-breaker-service.js +12 -10
- package/dist/application/federation-breaker-service.js.map +1 -1
- package/dist/application/federation-coordinator.d.ts +48 -3
- package/dist/application/federation-coordinator.d.ts.map +1 -1
- package/dist/application/federation-coordinator.js +111 -22
- package/dist/application/federation-coordinator.js.map +1 -1
- package/dist/application/inbound-dispatcher.d.ts +114 -0
- package/dist/application/inbound-dispatcher.d.ts.map +1 -0
- package/dist/application/inbound-dispatcher.js +356 -0
- package/dist/application/inbound-dispatcher.js.map +1 -0
- package/dist/application/spend-reporter.d.ts +77 -0
- package/dist/application/spend-reporter.d.ts.map +1 -1
- package/dist/application/spend-reporter.js +76 -0
- package/dist/application/spend-reporter.js.map +1 -1
- package/dist/application/trust-evaluator.d.ts +32 -0
- package/dist/application/trust-evaluator.d.ts.map +1 -1
- package/dist/application/trust-evaluator.js +47 -0
- package/dist/application/trust-evaluator.js.map +1 -1
- package/dist/bin.d.ts +1 -1
- package/dist/bin.js +2 -2
- package/dist/bin.js.map +1 -1
- package/dist/cli-commands.d.ts.map +1 -1
- package/dist/cli-commands.js +125 -6
- package/dist/cli-commands.js.map +1 -1
- package/dist/domain/services/discovery-service.d.ts +18 -1
- package/dist/domain/services/discovery-service.d.ts.map +1 -1
- package/dist/domain/services/discovery-service.js +21 -0
- package/dist/domain/services/discovery-service.js.map +1 -1
- package/dist/domain/services/handshake-service.d.ts +10 -0
- package/dist/domain/services/handshake-service.d.ts.map +1 -1
- package/dist/domain/services/handshake-service.js +28 -0
- package/dist/domain/services/handshake-service.js.map +1 -1
- package/dist/domain/services/wg-firewall-service.d.ts +71 -0
- package/dist/domain/services/wg-firewall-service.d.ts.map +1 -0
- package/dist/domain/services/wg-firewall-service.js +194 -0
- package/dist/domain/services/wg-firewall-service.js.map +1 -0
- package/dist/domain/services/wg-mesh-service.d.ts +156 -0
- package/dist/domain/services/wg-mesh-service.d.ts.map +1 -0
- package/dist/domain/services/wg-mesh-service.js +292 -0
- package/dist/domain/services/wg-mesh-service.js.map +1 -0
- package/dist/domain/services/wg-witness-service.d.ts +98 -0
- package/dist/domain/services/wg-witness-service.d.ts.map +1 -0
- package/dist/domain/services/wg-witness-service.js +122 -0
- package/dist/domain/services/wg-witness-service.js.map +1 -0
- package/dist/domain/value-objects/wg-config.d.ts +70 -0
- package/dist/domain/value-objects/wg-config.d.ts.map +1 -0
- package/dist/domain/value-objects/wg-config.js +104 -0
- package/dist/domain/value-objects/wg-config.js.map +1 -0
- package/dist/index.d.ts +8 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp-tools.d.ts +3 -1
- package/dist/mcp-tools.d.ts.map +1 -1
- package/dist/mcp-tools.js +114 -18
- package/dist/mcp-tools.js.map +1 -1
- package/dist/plugin.d.ts +2 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +173 -15
- package/dist/plugin.js.map +1 -1
- package/dist/transport/midstream-aware-loader.d.ts +72 -0
- package/dist/transport/midstream-aware-loader.d.ts.map +1 -0
- package/dist/transport/midstream-aware-loader.js +269 -0
- package/dist/transport/midstream-aware-loader.js.map +1 -0
- package/dist/version.d.ts +3 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/package.json +21 -5
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { validateAgentCard } from './agent-card.js';
|
|
2
|
+
const CAPABILITY_ID_RE = /^[A-Za-z0-9](?:[A-Za-z0-9._:/-]{0,126}[A-Za-z0-9])?$/;
|
|
3
|
+
const FORBIDDEN_CONTROLS_RE = /[\u0000-\u001f\u007f-\u009f\u200b-\u200f\u202a-\u202e\u2060\u2066-\u2069\ufeff]/u;
|
|
4
|
+
const MAX_REMOTE_SKILLS = 256;
|
|
5
|
+
const MAX_CAPABILITIES = 32;
|
|
6
|
+
const MAX_FIELD_CHARS = 2_048;
|
|
7
|
+
const MAX_CONSTRAINTS = 16;
|
|
8
|
+
const MAX_CONSTRAINT_CHARS = 512;
|
|
9
|
+
/**
|
|
10
|
+
* Project a third-party A2A Agent Card into planner-visible metadata.
|
|
11
|
+
*
|
|
12
|
+
* Security boundary: card descriptions, skill descriptions, examples, tags,
|
|
13
|
+
* provider text, documentation URLs, extension parameters, and all other
|
|
14
|
+
* remote prose are deliberately absent from the return type. Only a bounded
|
|
15
|
+
* canonical skill identifier may cross the registration boundary, and its
|
|
16
|
+
* planner semantics come from a host-controlled resolver.
|
|
17
|
+
*/
|
|
18
|
+
export function projectPlannerSafeAgentCard(card, policy) {
|
|
19
|
+
const validation = validateAgentCard(card);
|
|
20
|
+
if (!validation.valid) {
|
|
21
|
+
throw new Error('A2A Agent Card is structurally invalid');
|
|
22
|
+
}
|
|
23
|
+
if (card.skills.length > MAX_REMOTE_SKILLS) {
|
|
24
|
+
throw new Error('A2A Agent Card exceeds the remote skill limit');
|
|
25
|
+
}
|
|
26
|
+
const maximumCapabilities = policy.maximumCapabilities ?? MAX_CAPABILITIES;
|
|
27
|
+
if (!Number.isSafeInteger(maximumCapabilities) || maximumCapabilities < 1 || maximumCapabilities > MAX_CAPABILITIES) {
|
|
28
|
+
throw new Error('Planner capability limit is invalid');
|
|
29
|
+
}
|
|
30
|
+
const capabilities = [];
|
|
31
|
+
const seen = new Set();
|
|
32
|
+
let rejectedSkillCount = 0;
|
|
33
|
+
let duplicateSkillCount = 0;
|
|
34
|
+
for (const skill of card.skills) {
|
|
35
|
+
const id = canonicalCapabilityId(skill.id);
|
|
36
|
+
if (id === undefined) {
|
|
37
|
+
rejectedSkillCount += 1;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (seen.has(id)) {
|
|
41
|
+
duplicateSkillCount += 1;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
seen.add(id);
|
|
45
|
+
const resolved = policy.resolveCapability(id);
|
|
46
|
+
if (resolved === undefined) {
|
|
47
|
+
rejectedSkillCount += 1;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
capabilities.push(validateResolvedCapability(id, resolved));
|
|
51
|
+
if (capabilities.length >= maximumCapabilities)
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
descriptor: {
|
|
56
|
+
schema: 'ruflo/planner-safe-agent-descriptor/v1',
|
|
57
|
+
source: 'a2a-agent-card',
|
|
58
|
+
capabilities,
|
|
59
|
+
authority: 'none',
|
|
60
|
+
},
|
|
61
|
+
rejectedSkillCount,
|
|
62
|
+
duplicateSkillCount,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function canonicalCapabilityId(value) {
|
|
66
|
+
if (typeof value !== 'string')
|
|
67
|
+
return undefined;
|
|
68
|
+
const normalized = value.normalize('NFKC');
|
|
69
|
+
if (FORBIDDEN_CONTROLS_RE.test(normalized))
|
|
70
|
+
return undefined;
|
|
71
|
+
if (!CAPABILITY_ID_RE.test(normalized))
|
|
72
|
+
return undefined;
|
|
73
|
+
return normalized;
|
|
74
|
+
}
|
|
75
|
+
function validateResolvedCapability(expectedId, definition) {
|
|
76
|
+
const id = canonicalCapabilityId(definition.id);
|
|
77
|
+
if (id === undefined || id !== expectedId) {
|
|
78
|
+
throw new Error('Resolved planner capability identifier does not match registration identifier');
|
|
79
|
+
}
|
|
80
|
+
if (!Array.isArray(definition.usageConstraints) || definition.usageConstraints.length > MAX_CONSTRAINTS) {
|
|
81
|
+
throw new Error('Resolved planner capability constraints are invalid');
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
id,
|
|
85
|
+
functionality: canonicalPlannerText(definition.functionality, MAX_FIELD_CHARS, 'functionality'),
|
|
86
|
+
inputSpecification: canonicalPlannerText(definition.inputSpecification, MAX_FIELD_CHARS, 'input specification'),
|
|
87
|
+
outputSpecification: canonicalPlannerText(definition.outputSpecification, MAX_FIELD_CHARS, 'output specification'),
|
|
88
|
+
usageConstraints: definition.usageConstraints.map((constraint) => canonicalPlannerText(constraint, MAX_CONSTRAINT_CHARS, 'usage constraint')),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function canonicalPlannerText(value, maximumChars, field) {
|
|
92
|
+
if (typeof value !== 'string')
|
|
93
|
+
throw new Error(`Resolved planner ${field} must be text`);
|
|
94
|
+
const normalized = value.normalize('NFKC').trim();
|
|
95
|
+
if (normalized.length < 1 || normalized.length > maximumChars || FORBIDDEN_CONTROLS_RE.test(normalized)) {
|
|
96
|
+
throw new Error(`Resolved planner ${field} is invalid`);
|
|
97
|
+
}
|
|
98
|
+
return normalized;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=planner-descriptor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planner-descriptor.js","sourceRoot":"","sources":["../../src/a2a/planner-descriptor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A2A well-known Agent Card endpoint (A2A 1.0 §8.2 discovery + §8.6 caching).
|
|
3
|
+
*
|
|
4
|
+
* Serves `GET /.well-known/agent-card.json` from a minimal `node:http`
|
|
5
|
+
* server. Security posture follows ADR-166 (mcp-bridge unauthenticated-RCE
|
|
6
|
+
* remediation): binds 127.0.0.1 by default and REFUSES a non-loopback bind
|
|
7
|
+
* unless the caller passes `allowNonLoopback: true` explicitly. The endpoint
|
|
8
|
+
* is read-only (GET/HEAD on one exact path), exposes only the public card,
|
|
9
|
+
* and is entirely opt-in — nothing here weakens the federation transport's
|
|
10
|
+
* existing bind or auth behavior.
|
|
11
|
+
*/
|
|
12
|
+
import { type A2AAgentCard } from './agent-card.js';
|
|
13
|
+
export interface AgentCardServerOptions {
|
|
14
|
+
/** Card supplier — re-invoked per request so a late-published manifest is picked up. */
|
|
15
|
+
readonly getCard: () => A2AAgentCard | null;
|
|
16
|
+
readonly port: number;
|
|
17
|
+
/** Bind host. Default 127.0.0.1 (ADR-166 posture). */
|
|
18
|
+
readonly host?: string;
|
|
19
|
+
/** Serve path. Default A2A_WELL_KNOWN_PATH. */
|
|
20
|
+
readonly path?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Explicit opt-in required to bind anything other than loopback. Without
|
|
23
|
+
* it a non-loopback host is rejected at start (fail-closed).
|
|
24
|
+
*/
|
|
25
|
+
readonly allowNonLoopback?: boolean;
|
|
26
|
+
/** Cache-Control max-age seconds (spec §8.6.1). Default 300. */
|
|
27
|
+
readonly cacheMaxAgeSeconds?: number;
|
|
28
|
+
}
|
|
29
|
+
export interface AgentCardServerHandle {
|
|
30
|
+
readonly url: string;
|
|
31
|
+
readonly host: string;
|
|
32
|
+
readonly port: number;
|
|
33
|
+
close(): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
export declare function isLoopbackHost(host: string): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Start the well-known Agent Card HTTP endpoint.
|
|
38
|
+
*
|
|
39
|
+
* Responses:
|
|
40
|
+
* GET/HEAD <path> → 200 application/json (+ Cache-Control, ETag per §8.6)
|
|
41
|
+
* or 503 when no card is available yet
|
|
42
|
+
* other method → 405
|
|
43
|
+
* other path → 404
|
|
44
|
+
*/
|
|
45
|
+
export declare function startAgentCardServer(options: AgentCardServerOptions): Promise<AgentCardServerHandle>;
|
|
46
|
+
//# sourceMappingURL=well-known.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"well-known.d.ts","sourceRoot":"","sources":["../../src/a2a/well-known.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEzE,MAAM,WAAW,sBAAsB;IACrC,wFAAwF;IACxF,QAAQ,CAAC,OAAO,EAAE,MAAM,YAAY,GAAG,IAAI,CAAC;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sDAAsD;IACtD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,+CAA+C;IAC/C,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IACpC,gEAAgE;IAChE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CACtC;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAID,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,qBAAqB,CAAC,CA6DhC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A2A well-known Agent Card endpoint (A2A 1.0 §8.2 discovery + §8.6 caching).
|
|
3
|
+
*
|
|
4
|
+
* Serves `GET /.well-known/agent-card.json` from a minimal `node:http`
|
|
5
|
+
* server. Security posture follows ADR-166 (mcp-bridge unauthenticated-RCE
|
|
6
|
+
* remediation): binds 127.0.0.1 by default and REFUSES a non-loopback bind
|
|
7
|
+
* unless the caller passes `allowNonLoopback: true` explicitly. The endpoint
|
|
8
|
+
* is read-only (GET/HEAD on one exact path), exposes only the public card,
|
|
9
|
+
* and is entirely opt-in — nothing here weakens the federation transport's
|
|
10
|
+
* existing bind or auth behavior.
|
|
11
|
+
*/
|
|
12
|
+
import { createServer } from 'node:http';
|
|
13
|
+
import { createHash } from 'node:crypto';
|
|
14
|
+
import { A2A_WELL_KNOWN_PATH } from './agent-card.js';
|
|
15
|
+
const LOOPBACK_HOSTS = new Set(['127.0.0.1', '::1', 'localhost']);
|
|
16
|
+
export function isLoopbackHost(host) {
|
|
17
|
+
return LOOPBACK_HOSTS.has(host) || host.startsWith('127.');
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Start the well-known Agent Card HTTP endpoint.
|
|
21
|
+
*
|
|
22
|
+
* Responses:
|
|
23
|
+
* GET/HEAD <path> → 200 application/json (+ Cache-Control, ETag per §8.6)
|
|
24
|
+
* or 503 when no card is available yet
|
|
25
|
+
* other method → 405
|
|
26
|
+
* other path → 404
|
|
27
|
+
*/
|
|
28
|
+
export function startAgentCardServer(options) {
|
|
29
|
+
const host = options.host ?? '127.0.0.1';
|
|
30
|
+
const path = options.path ?? A2A_WELL_KNOWN_PATH;
|
|
31
|
+
const maxAge = options.cacheMaxAgeSeconds ?? 300;
|
|
32
|
+
if (!isLoopbackHost(host) && options.allowNonLoopback !== true) {
|
|
33
|
+
return Promise.reject(new Error(`A2A agent-card server: refusing non-loopback bind ${host} without allowNonLoopback: true (ADR-166)`));
|
|
34
|
+
}
|
|
35
|
+
const server = createServer((req, res) => {
|
|
36
|
+
const reqPath = (req.url ?? '').split('?')[0];
|
|
37
|
+
if (reqPath !== path) {
|
|
38
|
+
res.writeHead(404, { 'content-type': 'application/json' });
|
|
39
|
+
res.end(JSON.stringify({ error: 'not_found', agentCardPath: path }));
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (req.method !== 'GET' && req.method !== 'HEAD') {
|
|
43
|
+
res.writeHead(405, { allow: 'GET, HEAD', 'content-type': 'application/json' });
|
|
44
|
+
res.end(JSON.stringify({ error: 'method_not_allowed' }));
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const card = options.getCard();
|
|
48
|
+
if (!card) {
|
|
49
|
+
res.writeHead(503, { 'content-type': 'application/json', 'retry-after': '5' });
|
|
50
|
+
res.end(JSON.stringify({ error: 'agent_card_not_ready' }));
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const body = JSON.stringify(card, null, 2);
|
|
54
|
+
const etag = `"${createHash('sha256').update(body).digest('hex').slice(0, 32)}"`;
|
|
55
|
+
if (req.headers['if-none-match'] === etag) {
|
|
56
|
+
res.writeHead(304, { etag });
|
|
57
|
+
res.end();
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
res.writeHead(200, {
|
|
61
|
+
'content-type': 'application/json',
|
|
62
|
+
'cache-control': `public, max-age=${maxAge}`,
|
|
63
|
+
etag,
|
|
64
|
+
});
|
|
65
|
+
res.end(req.method === 'HEAD' ? undefined : body);
|
|
66
|
+
});
|
|
67
|
+
return new Promise((resolvePromise, rejectPromise) => {
|
|
68
|
+
server.once('error', rejectPromise);
|
|
69
|
+
server.listen(options.port, host, () => {
|
|
70
|
+
server.removeListener('error', rejectPromise);
|
|
71
|
+
const addr = server.address();
|
|
72
|
+
const boundPort = typeof addr === 'object' && addr !== null ? addr.port : options.port;
|
|
73
|
+
resolvePromise({
|
|
74
|
+
url: `http://${host}:${boundPort}${path}`,
|
|
75
|
+
host,
|
|
76
|
+
port: boundPort,
|
|
77
|
+
close: () => new Promise((res2, rej2) => {
|
|
78
|
+
server.close((err) => (err ? rej2(err) : res2()));
|
|
79
|
+
}),
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=well-known.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"well-known.js","sourceRoot":"","sources":["../../src/a2a/well-known.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { FederationClaimType, PolicyEngineDeps } from './policy-engine.js';
|
|
2
|
+
export type FederationAuthorizationMode = 'legacy' | 'observe' | 'enforce';
|
|
3
|
+
export interface FederationClaimCheckerConfig {
|
|
4
|
+
mode?: FederationAuthorizationMode;
|
|
5
|
+
grantedClaims?: readonly string[];
|
|
6
|
+
onObservation?: (claim: FederationClaimType, granted: boolean) => void;
|
|
7
|
+
}
|
|
8
|
+
export interface FederationClaimChecker {
|
|
9
|
+
mode: FederationAuthorizationMode;
|
|
10
|
+
grantedClaims: ReadonlySet<FederationClaimType>;
|
|
11
|
+
checkClaim: PolicyEngineDeps['checkClaim'];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Compatibility bridge for the legacy federation policy engine.
|
|
15
|
+
*
|
|
16
|
+
* This removes the anonymous `() => true` production stub and makes
|
|
17
|
+
* compatibility behavior explicit:
|
|
18
|
+
* - legacy: preserve pre-ADR-325 behavior;
|
|
19
|
+
* - observe: calculate and report missing grants without blocking;
|
|
20
|
+
* - enforce: default deny unless the exact claim is configured.
|
|
21
|
+
*
|
|
22
|
+
* ADR-324 policy adapters can supply the `grantedClaims` set after evaluating
|
|
23
|
+
* the request; ownership-changing federation messages remain disabled in the
|
|
24
|
+
* default message policy until the full ingress PEP is composed.
|
|
25
|
+
*/
|
|
26
|
+
export declare function createFederationClaimChecker(config?: FederationClaimCheckerConfig): FederationClaimChecker;
|
|
27
|
+
//# sourceMappingURL=claim-checker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claim-checker.d.ts","sourceRoot":"","sources":["../../src/application/claim-checker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEhF,MAAM,MAAM,2BAA2B,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;AAY3E,MAAM,WAAW,4BAA4B;IAC3C,IAAI,CAAC,EAAE,2BAA2B,CAAC;IACnC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,mBAAmB,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CACxE;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,2BAA2B,CAAC;IAClC,aAAa,EAAE,WAAW,CAAC,mBAAmB,CAAC,CAAC;IAChD,UAAU,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;CAC5C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,GAAE,4BAAiC,GACxC,sBAAsB,CAuBxB"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const FEDERATION_CLAIMS = new Set([
|
|
2
|
+
'federation:discover',
|
|
3
|
+
'federation:connect',
|
|
4
|
+
'federation:read',
|
|
5
|
+
'federation:write',
|
|
6
|
+
'federation:admin',
|
|
7
|
+
'federation:memory',
|
|
8
|
+
'federation:spawn',
|
|
9
|
+
]);
|
|
10
|
+
/**
|
|
11
|
+
* Compatibility bridge for the legacy federation policy engine.
|
|
12
|
+
*
|
|
13
|
+
* This removes the anonymous `() => true` production stub and makes
|
|
14
|
+
* compatibility behavior explicit:
|
|
15
|
+
* - legacy: preserve pre-ADR-325 behavior;
|
|
16
|
+
* - observe: calculate and report missing grants without blocking;
|
|
17
|
+
* - enforce: default deny unless the exact claim is configured.
|
|
18
|
+
*
|
|
19
|
+
* ADR-324 policy adapters can supply the `grantedClaims` set after evaluating
|
|
20
|
+
* the request; ownership-changing federation messages remain disabled in the
|
|
21
|
+
* default message policy until the full ingress PEP is composed.
|
|
22
|
+
*/
|
|
23
|
+
export function createFederationClaimChecker(config = {}) {
|
|
24
|
+
const mode = config.mode ?? 'legacy';
|
|
25
|
+
if (mode !== 'legacy' && mode !== 'observe' && mode !== 'enforce') {
|
|
26
|
+
throw new TypeError(`Unsupported federation authorization mode: ${String(mode)}`);
|
|
27
|
+
}
|
|
28
|
+
const grantedClaims = new Set();
|
|
29
|
+
for (const claim of config.grantedClaims ?? []) {
|
|
30
|
+
if (!FEDERATION_CLAIMS.has(claim)) {
|
|
31
|
+
throw new TypeError(`Unknown federation claim: ${claim}`);
|
|
32
|
+
}
|
|
33
|
+
grantedClaims.add(claim);
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
mode,
|
|
37
|
+
grantedClaims,
|
|
38
|
+
checkClaim: (claim) => {
|
|
39
|
+
const granted = grantedClaims.has(claim);
|
|
40
|
+
if (mode === 'observe')
|
|
41
|
+
config.onObservation?.(claim, granted);
|
|
42
|
+
return mode !== 'enforce' || granted;
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=claim-checker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claim-checker.js","sourceRoot":"","sources":["../../src/application/claim-checker.ts"],"names":[],"mappings":"AAIA,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAsB;IACrD,qBAAqB;IACrB,oBAAoB;IACpB,iBAAiB;IACjB,kBAAkB;IAClB,kBAAkB;IAClB,mBAAmB;IACnB,kBAAkB;CACnB,CAAC,CAAC;AAcH;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,4BAA4B,CAC1C,SAAuC,EAAE;IAEzC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,QAAQ,CAAC;IACrC,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QAClE,MAAM,IAAI,SAAS,CAAC,8CAA8C,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACpF,CAAC;IAED,MAAM,aAAa,GAAG,IAAI,GAAG,EAAuB,CAAC;IACrD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,aAAa,IAAI,EAAE,EAAE,CAAC;QAC/C,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAA4B,CAAC,EAAE,CAAC;YACzD,MAAM,IAAI,SAAS,CAAC,6BAA6B,KAAK,EAAE,CAAC,CAAC;QAC5D,CAAC;QACD,aAAa,CAAC,GAAG,CAAC,KAA4B,CAAC,CAAC;IAClD,CAAC;IAED,OAAO;QACL,IAAI;QACJ,aAAa;QACb,UAAU,EAAE,CAAC,KAAK,EAAE,EAAE;YACpB,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACzC,IAAI,IAAI,KAAK,SAAS;gBAAE,MAAM,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAC/D,OAAO,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC;QACvC,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -132,11 +132,21 @@ export declare function evaluatePolicy(samples: readonly NormalizedSample[], nod
|
|
|
132
132
|
* Construct once per federation coordinator. Inject the policy if you need
|
|
133
133
|
* non-default thresholds (Phase 4 doctor surface will let users tune them).
|
|
134
134
|
*/
|
|
135
|
+
/**
|
|
136
|
+
* ADR-111 Phase 3 — callback invoked after the breaker applies a successful
|
|
137
|
+
* state transition. Used by the coordinator to propagate suspends to the
|
|
138
|
+
* WG mesh layer (clearing AllowedIPs). Not invoked for `apply=false` dry runs
|
|
139
|
+
* or `NONE` / `REACTIVATE_ELIGIBLE` decisions. Errors thrown from the callback
|
|
140
|
+
* are swallowed at the breaker — the entity transition has already happened,
|
|
141
|
+
* and side-effect failures shouldn't unwind the breaker's internal state.
|
|
142
|
+
*/
|
|
143
|
+
export type BreakerTransitionListener = (node: FederationNode, decision: BreakerDecision) => void | Promise<void>;
|
|
135
144
|
export declare class FederationBreakerService {
|
|
136
145
|
private readonly policy;
|
|
137
146
|
private readonly samples;
|
|
138
147
|
private readonly maxSamplesPerPeer;
|
|
139
|
-
|
|
148
|
+
private readonly onTransition?;
|
|
149
|
+
constructor(policy?: BreakerPolicy, maxSamplesPerPeer?: number, onTransition?: BreakerTransitionListener);
|
|
140
150
|
/** Read the active policy (handy for tests + doctor surface). */
|
|
141
151
|
getPolicy(): BreakerPolicy;
|
|
142
152
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"federation-breaker-service.d.ts","sourceRoot":"","sources":["../../src/application/federation-breaker-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AACvE,OAAO,EAEL,gBAAgB,EAMjB,MAAM,kDAAkD,CAAC;AAE1D,yDAAyD;AACzD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,qEAAqE;IACrE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,+DAA+D;IAC/D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,sFAAsF;IACtF,QAAQ,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC;CACpB;AAED,sEAAsE;AACtE,MAAM,WAAW,aAAa;IAC5B,6CAA6C;IAC7C,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,4CAA4C;IAC5C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,+DAA+D;IAC/D,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC,wDAAwD;IACxD,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,wFAAwF;IACxF,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,sEAAsE;IACtE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,gEAAgE;IAChE,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;CACpC;AAED,eAAO,MAAM,sBAAsB,EAAE,aAQnC,CAAC;AAEH,wDAAwD;AACxD,eAAO,MAAM,4BAA4B,SAAU,CAAC;AAEpD,6EAA6E;AAC7E,UAAU,gBAAgB;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;CACnB;AAED;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACpD;IACE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;CACnC,GACD;IACE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;CACnC,GACD;IACE,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,CAAC;AAEN;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,SAAS,gBAAgB,EAAE,EACpC,IAAI,EAAE,cAAc,EACpB,MAAM,EAAE,aAAa,EACrB,GAAG,EAAE,IAAI,GACR,eAAe,CAqDjB;AAED;;;;;;GAMG;AACH,qBAAa,wBAAwB;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAC1D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;
|
|
1
|
+
{"version":3,"file":"federation-breaker-service.d.ts","sourceRoot":"","sources":["../../src/application/federation-breaker-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -128,21 +128,16 @@ export function evaluatePolicy(samples, node, policy, now) {
|
|
|
128
128
|
}
|
|
129
129
|
return { action: 'NONE', nodeId: node.nodeId };
|
|
130
130
|
}
|
|
131
|
-
/**
|
|
132
|
-
* Stateful service: owns the per-peer sample buffer, applies decisions to
|
|
133
|
-
* entities, and exposes the breaker control surface to the coordinator.
|
|
134
|
-
*
|
|
135
|
-
* Construct once per federation coordinator. Inject the policy if you need
|
|
136
|
-
* non-default thresholds (Phase 4 doctor surface will let users tune them).
|
|
137
|
-
*/
|
|
138
131
|
export class FederationBreakerService {
|
|
139
132
|
policy;
|
|
140
133
|
samples;
|
|
141
134
|
maxSamplesPerPeer;
|
|
142
|
-
|
|
135
|
+
onTransition;
|
|
136
|
+
constructor(policy = DEFAULT_BREAKER_POLICY, maxSamplesPerPeer = DEFAULT_MAX_SAMPLES_PER_PEER, onTransition) {
|
|
143
137
|
this.policy = policy;
|
|
144
138
|
this.samples = new Map();
|
|
145
139
|
this.maxSamplesPerPeer = maxSamplesPerPeer;
|
|
140
|
+
this.onTransition = onTransition;
|
|
146
141
|
}
|
|
147
142
|
/** Read the active policy (handy for tests + doctor surface). */
|
|
148
143
|
getPolicy() {
|
|
@@ -187,15 +182,16 @@ export class FederationBreakerService {
|
|
|
187
182
|
const decision = evaluatePolicy(buf, node, this.policy, now);
|
|
188
183
|
if (!apply)
|
|
189
184
|
return decision;
|
|
185
|
+
let transitioned = false;
|
|
190
186
|
switch (decision.action) {
|
|
191
187
|
case 'SUSPEND': {
|
|
192
188
|
const reason = { reason: decision.reason };
|
|
193
|
-
node.suspend(reason, now);
|
|
189
|
+
transitioned = node.suspend(reason, now);
|
|
194
190
|
break;
|
|
195
191
|
}
|
|
196
192
|
case 'EVICT': {
|
|
197
193
|
const reason = { reason: decision.reason };
|
|
198
|
-
node.evict(reason, now);
|
|
194
|
+
transitioned = node.evict(reason, now);
|
|
199
195
|
break;
|
|
200
196
|
}
|
|
201
197
|
case 'REACTIVATE_ELIGIBLE':
|
|
@@ -206,6 +202,12 @@ export class FederationBreakerService {
|
|
|
206
202
|
case 'NONE':
|
|
207
203
|
break;
|
|
208
204
|
}
|
|
205
|
+
if (transitioned && this.onTransition) {
|
|
206
|
+
// Side-effect listener (ADR-111 Phase 3). Errors are swallowed so a
|
|
207
|
+
// failing WG propagation can't unwind the entity transition that
|
|
208
|
+
// already succeeded — coordinator should log via its own audit trail.
|
|
209
|
+
Promise.resolve(this.onTransition(node, decision)).catch(() => { });
|
|
210
|
+
}
|
|
209
211
|
return decision;
|
|
210
212
|
}
|
|
211
213
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"federation-breaker-service.js","sourceRoot":"","sources":["../../src/application/federation-breaker-service.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"federation-breaker-service.js","sourceRoot":"","sources":["../../src/application/federation-breaker-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type FederationNodeStateRecord } from '../domain/entities/federation-node.js';
|
|
1
|
+
import { FederationNode, type FederationNodeStateRecord } from '../domain/entities/federation-node.js';
|
|
2
2
|
import { FederationSession } from '../domain/entities/federation-session.js';
|
|
3
3
|
import { type FederationMessageType } from '../domain/entities/federation-envelope.js';
|
|
4
4
|
import { TrustLevel } from '../domain/entities/trust-level.js';
|
|
@@ -8,11 +8,12 @@ import { HandshakeService } from '../domain/services/handshake-service.js';
|
|
|
8
8
|
import { RoutingService, type RoutingResult } from '../domain/services/routing-service.js';
|
|
9
9
|
import { AuditService } from '../domain/services/audit-service.js';
|
|
10
10
|
import { PIIPipelineService } from '../domain/services/pii-pipeline-service.js';
|
|
11
|
-
import { TrustEvaluator } from './trust-evaluator.js';
|
|
11
|
+
import { TrustEvaluator, type BootstrapElevationAuditEntry } from './trust-evaluator.js';
|
|
12
12
|
import { PolicyEngine } from './policy-engine.js';
|
|
13
13
|
import { enforceBudget, validateBudget } from '../domain/value-objects/federation-budget.js';
|
|
14
14
|
import type { FederationBreakerService } from './federation-breaker-service.js';
|
|
15
15
|
import type { SpendReporter } from './spend-reporter.js';
|
|
16
|
+
import type { WgMeshService, WgCommand } from '../domain/services/wg-mesh-service.js';
|
|
16
17
|
/**
|
|
17
18
|
* Optional per-call budget controls (ADR-097 Phase 1). All fields are
|
|
18
19
|
* optional; omitted means "no limit on that axis" (the default unbounded
|
|
@@ -42,6 +43,9 @@ export interface FederationCoordinatorConfig {
|
|
|
42
43
|
readonly publicKey: string;
|
|
43
44
|
readonly endpoint: string;
|
|
44
45
|
readonly capabilities: readonly string[];
|
|
46
|
+
/** Wire protocols this runtime is prepared to advertise and negotiate. */
|
|
47
|
+
readonly supportedProtocols?: readonly string[];
|
|
48
|
+
readonly version?: string;
|
|
45
49
|
}
|
|
46
50
|
export interface FederationStatus {
|
|
47
51
|
readonly nodeId: string;
|
|
@@ -64,6 +68,20 @@ export interface FederationStatus {
|
|
|
64
68
|
export interface FederationCoordinatorIntegrations {
|
|
65
69
|
readonly spendReporter?: SpendReporter;
|
|
66
70
|
readonly breakerService?: FederationBreakerService;
|
|
71
|
+
/**
|
|
72
|
+
* ADR-111 Phase 3 — optional WG mesh service. When present, peer state
|
|
73
|
+
* transitions (evict/reactivate/breaker-suspend) emit `wg set` commands
|
|
74
|
+
* to a sink supplied by `wgCommandSink`. No-op for peers without a `wg`
|
|
75
|
+
* manifest block, so wiring the service is safe even in mixed deployments.
|
|
76
|
+
*/
|
|
77
|
+
readonly wgMesh?: WgMeshService;
|
|
78
|
+
/**
|
|
79
|
+
* Where emitted WG commands go. Defaults to the audit log only. Integrators
|
|
80
|
+
* can plug in a shell executor here (after operator approval — bringing up
|
|
81
|
+
* a network interface is destructive). Commands include shell-ready
|
|
82
|
+
* `wg set <iface> ...` strings; the sink should still validate before exec.
|
|
83
|
+
*/
|
|
84
|
+
readonly wgCommandSink?: (cmd: WgCommand) => void | Promise<void>;
|
|
67
85
|
}
|
|
68
86
|
export declare class FederationCoordinator {
|
|
69
87
|
private readonly config;
|
|
@@ -78,10 +96,19 @@ export declare class FederationCoordinator {
|
|
|
78
96
|
private initialized;
|
|
79
97
|
private readonly spendReporter?;
|
|
80
98
|
private readonly breakerService?;
|
|
99
|
+
private readonly wgMesh?;
|
|
100
|
+
private readonly wgCommandSink?;
|
|
81
101
|
constructor(config: FederationCoordinatorConfig, discovery: DiscoveryService, handshake: HandshakeService, routing: RoutingService, audit: AuditService, piiPipeline: PIIPipelineService, trustEvaluator: TrustEvaluator, policyEngine: PolicyEngine, integrations?: FederationCoordinatorIntegrations);
|
|
102
|
+
/**
|
|
103
|
+
* ADR-111 Phase 3 — emit a WG command for an audited peer transition.
|
|
104
|
+
* No-op if no wgMesh is configured or the peer lacks a `wg` manifest
|
|
105
|
+
* block. Commands flow to `wgCommandSink` (if any) and always to the
|
|
106
|
+
* audit log so reactivation is fully traceable.
|
|
107
|
+
*/
|
|
108
|
+
private emitWgCommand;
|
|
82
109
|
initialize(manifest: Omit<FederationManifest, 'signature'>): Promise<void>;
|
|
83
110
|
shutdown(): Promise<void>;
|
|
84
|
-
joinPeer(endpoint: string): Promise<FederationSession>;
|
|
111
|
+
joinPeer(endpoint: string, manifest?: FederationManifest): Promise<FederationSession>;
|
|
85
112
|
leavePeer(nodeId: string): Promise<void>;
|
|
86
113
|
sendMessage<T>(targetNodeId: string, messageType: FederationMessageType, payload: T, options?: SendOptions): Promise<RoutingResult>;
|
|
87
114
|
/**
|
|
@@ -108,6 +135,13 @@ export declare class FederationCoordinator {
|
|
|
108
135
|
getPeerStates(): readonly (FederationNodeStateRecord & {
|
|
109
136
|
readonly nodeId: string;
|
|
110
137
|
})[];
|
|
138
|
+
/**
|
|
139
|
+
* ADR-111 Phase 6: public read of the discovery peer list. Used by
|
|
140
|
+
* federation_wg_status MCP tool + WG firewall projection. Returns the
|
|
141
|
+
* full known-peer set (active + suspended + evicted) — filter via
|
|
142
|
+
* .isActive / state if you only want the live mesh members.
|
|
143
|
+
*/
|
|
144
|
+
listPeers(): readonly FederationNode[];
|
|
111
145
|
/**
|
|
112
146
|
* Aggregated counts for the doctor surface — `{ active: N, suspended: M,
|
|
113
147
|
* evicted: K }`. Cheap O(peers) sweep; safe to call from a status line.
|
|
@@ -151,6 +185,17 @@ export declare class FederationCoordinator {
|
|
|
151
185
|
readonly success: boolean;
|
|
152
186
|
readonly ts?: string;
|
|
153
187
|
}): Promise<void>;
|
|
188
|
+
/**
|
|
189
|
+
* Founder-bootstrap trust elevation (ADR-164 §3.5.4 — operator escape hatch
|
|
190
|
+
* used in the autopilot Day-1 scenario where a freshly-joined BBS peer
|
|
191
|
+
* needs TRUSTED before organic minInteractions thresholds can accrue).
|
|
192
|
+
*
|
|
193
|
+
* Refuses if the target node is not a registered federation peer (returns
|
|
194
|
+
* null). On success, writes a `trust_level_changed` audit entry tagged
|
|
195
|
+
* `bootstrap_elevation` with the operator-supplied reason, and returns
|
|
196
|
+
* the audit entry so the CLI / caller can print it to stdout.
|
|
197
|
+
*/
|
|
198
|
+
bootstrapElevatePeer(nodeId: string, newLevel: TrustLevel, reason: string): Promise<BootstrapElevationAuditEntry | null>;
|
|
154
199
|
/**
|
|
155
200
|
* Operator-initiated reactivate. Used after an integrator-supplied
|
|
156
201
|
* health probe confirms a SUSPENDED peer is healthy, OR as an
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"federation-coordinator.d.ts","sourceRoot":"","sources":["../../src/application/federation-coordinator.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"federation-coordinator.d.ts","sourceRoot":"","sources":["../../src/application/federation-coordinator.ts"],"names":[],"mappings":"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"}
|