@tenova/swt3-mcp 0.1.0 → 0.5.2
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 +162 -33
- package/dist/bin/swt3-mcp.js +3 -2
- package/dist/bin/swt3-mcp.js.map +1 -1
- package/dist/chain-verifier.d.ts +46 -0
- package/dist/chain-verifier.d.ts.map +1 -0
- package/dist/chain-verifier.js +210 -0
- package/dist/chain-verifier.js.map +1 -0
- package/dist/client.d.ts +4 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +56 -6
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +151 -14
- package/dist/config.js.map +1 -1
- package/dist/density-policy.d.ts +55 -0
- package/dist/density-policy.d.ts.map +1 -0
- package/dist/density-policy.js +128 -0
- package/dist/density-policy.js.map +1 -0
- package/dist/redis-reader.d.ts +57 -0
- package/dist/redis-reader.d.ts.map +1 -0
- package/dist/redis-reader.js +254 -0
- package/dist/redis-reader.js.map +1 -0
- package/dist/server.d.ts +2 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +555 -1
- package/dist/server.js.map +1 -1
- package/dist/state.d.ts +29 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +20 -0
- package/dist/state.js.map +1 -0
- package/dist/tools/audit.d.ts +20 -0
- package/dist/tools/audit.d.ts.map +1 -0
- package/dist/tools/audit.js +102 -0
- package/dist/tools/audit.js.map +1 -0
- package/dist/tools/authorize.d.ts +19 -0
- package/dist/tools/authorize.d.ts.map +1 -0
- package/dist/tools/authorize.js +96 -0
- package/dist/tools/authorize.js.map +1 -0
- package/dist/tools/chain.d.ts +24 -0
- package/dist/tools/chain.d.ts.map +1 -0
- package/dist/tools/chain.js +114 -0
- package/dist/tools/chain.js.map +1 -0
- package/dist/tools/model.d.ts +33 -0
- package/dist/tools/model.d.ts.map +1 -0
- package/dist/tools/model.js +162 -0
- package/dist/tools/model.js.map +1 -0
- package/dist/tools/signup.d.ts +2 -2
- package/dist/tools/signup.d.ts.map +1 -1
- package/dist/tools/signup.js +10 -3
- package/dist/tools/signup.js.map +1 -1
- package/dist/tools/skill.d.ts +33 -0
- package/dist/tools/skill.d.ts.map +1 -0
- package/dist/tools/skill.js +168 -0
- package/dist/tools/skill.js.map +1 -0
- package/dist/tools/suggest.d.ts +15 -0
- package/dist/tools/suggest.d.ts.map +1 -0
- package/dist/tools/suggest.js +174 -0
- package/dist/tools/suggest.js.map +1 -0
- package/dist/tools/trust.d.ts +33 -0
- package/dist/tools/trust.d.ts.map +1 -0
- package/dist/tools/trust.js +213 -0
- package/dist/tools/trust.js.map +1 -0
- package/dist/tools/violation.d.ts +20 -0
- package/dist/tools/violation.d.ts.map +1 -0
- package/dist/tools/violation.js +97 -0
- package/dist/tools/violation.js.map +1 -0
- package/dist/tools/witness.d.ts +6 -1
- package/dist/tools/witness.d.ts.map +1 -1
- package/dist/tools/witness.js +19 -5
- package/dist/tools/witness.js.map +1 -1
- package/package.json +33 -3
package/dist/config.js
CHANGED
|
@@ -1,21 +1,149 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* SWT3 MCP Server
|
|
2
|
+
* SWT3 MCP Server -- Configuration.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* Priority: env vars > YAML file > defaults
|
|
5
|
+
*
|
|
6
|
+
* Four modes:
|
|
7
|
+
* 1. Demo mode (no env vars, no YAML) -- local-only anchors, no account needed
|
|
8
|
+
* 2. YAML config (SWT3_CONFIG_FILE) -- one file governs MCP + SDK
|
|
9
|
+
* 3. API key only -- tenant auto-resolved from first API call
|
|
10
|
+
* 4. Full config -- API key + explicit tenant ID
|
|
11
|
+
*/
|
|
12
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
13
|
+
function parseYaml(content) {
|
|
14
|
+
try {
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
16
|
+
const yamlMod = require("yaml");
|
|
17
|
+
return yamlMod.parse(content);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
throw new Error("The 'yaml' package is required for YAML config. Install it with: npm install yaml");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Load config from YAML file + env var overrides.
|
|
25
|
+
* Returns the full bundle: McpConfig + DensityPolicy + TrustMesh.
|
|
26
|
+
*/
|
|
27
|
+
function loadFromYaml(yamlPath) {
|
|
28
|
+
if (!existsSync(yamlPath)) {
|
|
29
|
+
throw new Error(`SWT3 config file not found: ${yamlPath}`);
|
|
30
|
+
}
|
|
31
|
+
const content = readFileSync(yamlPath, "utf-8");
|
|
32
|
+
const { createHash } = require("node:crypto");
|
|
33
|
+
const configHash = createHash("sha256").update(content, "utf-8").digest("hex");
|
|
34
|
+
const raw = parseYaml(content);
|
|
35
|
+
if (!raw || typeof raw !== "object") {
|
|
36
|
+
throw new Error("Invalid config file: expected a YAML mapping");
|
|
37
|
+
}
|
|
38
|
+
// Resolve _env fields
|
|
39
|
+
let apiKey = raw.api_key || "";
|
|
40
|
+
if (raw.api_key_env) {
|
|
41
|
+
apiKey = process.env[raw.api_key_env] || "";
|
|
42
|
+
}
|
|
43
|
+
let signingKey = raw.signing_key || undefined;
|
|
44
|
+
if (raw.signing_key_env) {
|
|
45
|
+
signingKey = process.env[raw.signing_key_env] || undefined;
|
|
46
|
+
}
|
|
47
|
+
// Extract sections
|
|
48
|
+
const trustMeshRaw = raw.trust_mesh;
|
|
49
|
+
const densityRaw = raw.density_policy;
|
|
50
|
+
const mcpPolicyRaw = raw.mcp_policy;
|
|
51
|
+
// Build McpConfig (env vars override YAML)
|
|
52
|
+
const endpoint = process.env.SWT3_ENDPOINT || raw.endpoint || "https://sovereign.tenova.io";
|
|
53
|
+
apiKey = process.env.SWT3_API_KEY || apiKey;
|
|
54
|
+
const tenantId = process.env.SWT3_TENANT_ID || raw.tenant_id || "";
|
|
55
|
+
const agentId = process.env.SWT3_AGENT_ID || raw.agent_id || undefined;
|
|
56
|
+
signingKey = process.env.SWT3_SIGNING_KEY || signingKey;
|
|
57
|
+
const demo = !apiKey;
|
|
58
|
+
if (apiKey && !apiKey.startsWith("axm_")) {
|
|
59
|
+
throw new Error("API key must start with 'axm_'");
|
|
60
|
+
}
|
|
61
|
+
const rawLevel = process.env.SWT3_CLEARING_LEVEL ?? String(raw.clearing_level ?? 1);
|
|
62
|
+
let clearingLevel = 1;
|
|
63
|
+
const parsed = parseInt(rawLevel, 10);
|
|
64
|
+
if ([0, 1, 2, 3].includes(parsed)) {
|
|
65
|
+
clearingLevel = parsed;
|
|
66
|
+
}
|
|
67
|
+
// Chain verify: env > trust_mesh.mode === "strict" > false
|
|
68
|
+
const chainVerifyEnv = process.env.SWT3_CHAIN_VERIFY;
|
|
69
|
+
const meshMode = trustMeshRaw?.mode;
|
|
70
|
+
const chainVerify = chainVerifyEnv
|
|
71
|
+
? chainVerifyEnv === "true"
|
|
72
|
+
: meshMode === "strict";
|
|
73
|
+
const maxChainGapSeconds = parseInt(process.env.SWT3_MAX_CHAIN_GAP
|
|
74
|
+
|| String(densityRaw?.max_chain_gap_seconds ?? trustMeshRaw?.freshness_window ?? 60), 10);
|
|
75
|
+
const config = {
|
|
76
|
+
endpoint: endpoint.replace(/\/+$/, ""),
|
|
77
|
+
apiKey: demo ? "axm_demo_local" : apiKey,
|
|
78
|
+
tenantId: demo ? "DEMO_LOCAL" : tenantId,
|
|
79
|
+
clearingLevel,
|
|
80
|
+
agentId,
|
|
81
|
+
signingKey,
|
|
82
|
+
demo,
|
|
83
|
+
chainVerify: demo ? false : chainVerify,
|
|
84
|
+
redisUrl: process.env.SWT3_REDIS_URL || "redis://localhost:6379",
|
|
85
|
+
redisStream: process.env.SWT3_REDIS_STREAM || "swt3:anchors",
|
|
86
|
+
maxChainGapSeconds,
|
|
87
|
+
configHash,
|
|
88
|
+
};
|
|
89
|
+
// Density policy from YAML
|
|
90
|
+
let densityPolicy = null;
|
|
91
|
+
if (densityRaw) {
|
|
92
|
+
densityPolicy = {
|
|
93
|
+
min_anchors_per_1000_tokens: densityRaw.min_anchors_per_1000_tokens ?? 1,
|
|
94
|
+
required_providers: densityRaw.required_providers ?? [],
|
|
95
|
+
max_chain_gap_seconds: densityRaw.max_chain_gap_seconds ?? 60,
|
|
96
|
+
require_signing_key: densityRaw.require_signing_key ?? false,
|
|
97
|
+
min_trust_level: densityRaw.min_trust_level ?? 1,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
// Trust mesh from YAML
|
|
101
|
+
let trustMesh = null;
|
|
102
|
+
if (trustMeshRaw) {
|
|
103
|
+
trustMesh = {
|
|
104
|
+
trustedTenants: trustMeshRaw.trusted_tenants ?? [],
|
|
105
|
+
deniedAgents: trustMeshRaw.deny_agents ?? [],
|
|
106
|
+
deniedTenants: trustMeshRaw.deny_tenants ?? [],
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
// MCP policy from YAML
|
|
110
|
+
let mcpPolicy = null;
|
|
111
|
+
if (mcpPolicyRaw) {
|
|
112
|
+
mcpPolicy = {
|
|
113
|
+
witnessedTools: mcpPolicyRaw.witnessed_tools ?? [],
|
|
114
|
+
exemptTools: mcpPolicyRaw.exempt_tools ?? [],
|
|
115
|
+
requireTrustLevel: mcpPolicyRaw.require_trust_level ?? 0,
|
|
116
|
+
autoWitness: mcpPolicyRaw.auto_witness ?? true,
|
|
117
|
+
blockOnFailure: mcpPolicyRaw.block_on_failure ?? false,
|
|
118
|
+
maxVelocity: mcpPolicyRaw.max_velocity,
|
|
119
|
+
maxChainDepth: mcpPolicyRaw.max_chain_depth,
|
|
120
|
+
toolAllowlist: mcpPolicyRaw.tool_allowlist ?? [],
|
|
121
|
+
toolBlocklist: mcpPolicyRaw.tool_blocklist ?? [],
|
|
122
|
+
failSecure: mcpPolicyRaw.fail_secure ?? true,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
return { config, densityPolicy, trustMesh, mcpPolicy };
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Load configuration. Checks SWT3_CONFIG_FILE first, falls back to env vars.
|
|
8
129
|
*/
|
|
9
130
|
export function loadConfig() {
|
|
131
|
+
const yamlPath = process.env.SWT3_CONFIG_FILE;
|
|
132
|
+
if (yamlPath) {
|
|
133
|
+
return loadFromYaml(yamlPath);
|
|
134
|
+
}
|
|
135
|
+
// Legacy env-var-only path
|
|
10
136
|
const endpoint = process.env.SWT3_ENDPOINT || "https://sovereign.tenova.io";
|
|
11
137
|
const apiKey = process.env.SWT3_API_KEY || "";
|
|
12
138
|
const tenantId = process.env.SWT3_TENANT_ID || "";
|
|
13
139
|
const rawLevel = process.env.SWT3_CLEARING_LEVEL;
|
|
14
140
|
const agentId = process.env.SWT3_AGENT_ID || undefined;
|
|
15
141
|
const signingKey = process.env.SWT3_SIGNING_KEY || undefined;
|
|
16
|
-
|
|
142
|
+
const chainVerify = process.env.SWT3_CHAIN_VERIFY === "true";
|
|
143
|
+
const redisUrl = process.env.SWT3_REDIS_URL || "redis://localhost:6379";
|
|
144
|
+
const redisStream = process.env.SWT3_REDIS_STREAM || "swt3:anchors";
|
|
145
|
+
const maxChainGapSeconds = parseInt(process.env.SWT3_MAX_CHAIN_GAP || "60", 10);
|
|
17
146
|
const demo = !apiKey;
|
|
18
|
-
// Validate API key format if provided
|
|
19
147
|
if (apiKey && !apiKey.startsWith("axm_")) {
|
|
20
148
|
throw new Error("SWT3_API_KEY must start with 'axm_'");
|
|
21
149
|
}
|
|
@@ -28,13 +156,22 @@ export function loadConfig() {
|
|
|
28
156
|
clearingLevel = parsed;
|
|
29
157
|
}
|
|
30
158
|
return {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
159
|
+
config: {
|
|
160
|
+
endpoint: endpoint.replace(/\/+$/, ""),
|
|
161
|
+
apiKey: demo ? "axm_demo_local" : apiKey,
|
|
162
|
+
tenantId: demo ? "DEMO_LOCAL" : tenantId,
|
|
163
|
+
clearingLevel,
|
|
164
|
+
agentId,
|
|
165
|
+
signingKey,
|
|
166
|
+
demo,
|
|
167
|
+
chainVerify: demo ? false : chainVerify,
|
|
168
|
+
redisUrl,
|
|
169
|
+
redisStream,
|
|
170
|
+
maxChainGapSeconds,
|
|
171
|
+
},
|
|
172
|
+
densityPolicy: null,
|
|
173
|
+
trustMesh: null,
|
|
174
|
+
mcpPolicy: null,
|
|
38
175
|
};
|
|
39
176
|
}
|
|
40
177
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SWT3 MCP Server: Anchor Density Policy Engine.
|
|
3
|
+
*
|
|
4
|
+
* Configurable rules that enforce minimum anchor frequency, provider
|
|
5
|
+
* requirements, chain gap limits, and signing enforcement. Agents that
|
|
6
|
+
* fail policy checks are denied tool execution by the chain verifier.
|
|
7
|
+
*
|
|
8
|
+
* Patent pending.
|
|
9
|
+
*/
|
|
10
|
+
export interface DensityPolicy {
|
|
11
|
+
/** Minimum anchors per 1,000 tokens generated. Default: 1 */
|
|
12
|
+
min_anchors_per_1000_tokens: number;
|
|
13
|
+
/** Required anchor providers (e.g. ["vllm-native", "nvidia-triton"]). Default: [] */
|
|
14
|
+
required_providers: string[];
|
|
15
|
+
/** Maximum seconds between consecutive anchors in a chain. Default: 60 */
|
|
16
|
+
max_chain_gap_seconds: number;
|
|
17
|
+
/** Require all anchors to have payload_signature. Default: false */
|
|
18
|
+
require_signing_key: boolean;
|
|
19
|
+
/** Minimum trust level for the presenting agent. Default: 1 */
|
|
20
|
+
min_trust_level: number;
|
|
21
|
+
}
|
|
22
|
+
export interface PolicyViolation {
|
|
23
|
+
rule: string;
|
|
24
|
+
message: string;
|
|
25
|
+
actual?: number | string;
|
|
26
|
+
required?: number | string;
|
|
27
|
+
}
|
|
28
|
+
export interface PolicyResult {
|
|
29
|
+
compliant: boolean;
|
|
30
|
+
violations: PolicyViolation[];
|
|
31
|
+
}
|
|
32
|
+
/** Minimal anchor shape needed for policy evaluation. */
|
|
33
|
+
export interface ChainAnchor {
|
|
34
|
+
anchor_epoch: number;
|
|
35
|
+
provider?: string;
|
|
36
|
+
payload_signature?: string;
|
|
37
|
+
ai_input_tokens?: number;
|
|
38
|
+
ai_output_tokens?: number;
|
|
39
|
+
trust_level?: number;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Load density policy from environment.
|
|
43
|
+
* Priority: SWT3_DENSITY_POLICY (inline JSON) > SWT3_DENSITY_POLICY_FILE (path) > defaults
|
|
44
|
+
*/
|
|
45
|
+
export declare function loadDensityPolicy(yamlPolicy?: DensityPolicy): DensityPolicy;
|
|
46
|
+
/**
|
|
47
|
+
* Evaluate an anchor chain against the density policy.
|
|
48
|
+
*
|
|
49
|
+
* @param policy - The active density policy
|
|
50
|
+
* @param anchors - Chain anchors sorted by epoch ascending
|
|
51
|
+
* @param agentTokenCount - Total tokens produced by the agent (optional, skips density check if absent)
|
|
52
|
+
* @param agentTrustLevel - Trust level of the presenting agent (from verify_agent_trust)
|
|
53
|
+
*/
|
|
54
|
+
export declare function evaluatePolicy(policy: DensityPolicy, anchors: ChainAnchor[], agentTokenCount?: number, agentTrustLevel?: number): PolicyResult;
|
|
55
|
+
//# sourceMappingURL=density-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"density-policy.d.ts","sourceRoot":"","sources":["../src/density-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,WAAW,aAAa;IAC5B,6DAA6D;IAC7D,2BAA2B,EAAE,MAAM,CAAC;IACpC,qFAAqF;IACrF,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,0EAA0E;IAC1E,qBAAqB,EAAE,MAAM,CAAC;IAC9B,oEAAoE;IACpE,mBAAmB,EAAE,OAAO,CAAC;IAC7B,+DAA+D;IAC/D,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,eAAe,EAAE,CAAC;CAC/B;AAED,yDAAyD;AACzD,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAcD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,CAAC,EAAE,aAAa,GAAG,aAAa,CAyB3E;AAID;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,WAAW,EAAE,EACtB,eAAe,CAAC,EAAE,MAAM,EACxB,eAAe,CAAC,EAAE,MAAM,GACvB,YAAY,CA0Ed"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SWT3 MCP Server: Anchor Density Policy Engine.
|
|
3
|
+
*
|
|
4
|
+
* Configurable rules that enforce minimum anchor frequency, provider
|
|
5
|
+
* requirements, chain gap limits, and signing enforcement. Agents that
|
|
6
|
+
* fail policy checks are denied tool execution by the chain verifier.
|
|
7
|
+
*
|
|
8
|
+
* Patent pending.
|
|
9
|
+
*/
|
|
10
|
+
import { readFileSync } from "node:fs";
|
|
11
|
+
// ── Defaults ──────────────────────────────────────────────────────────
|
|
12
|
+
const DEFAULT_POLICY = {
|
|
13
|
+
min_anchors_per_1000_tokens: 1,
|
|
14
|
+
required_providers: [],
|
|
15
|
+
max_chain_gap_seconds: 60,
|
|
16
|
+
require_signing_key: false,
|
|
17
|
+
min_trust_level: 1,
|
|
18
|
+
};
|
|
19
|
+
// ── Load Policy ───────────────────────────────────────────────────────
|
|
20
|
+
/**
|
|
21
|
+
* Load density policy from environment.
|
|
22
|
+
* Priority: SWT3_DENSITY_POLICY (inline JSON) > SWT3_DENSITY_POLICY_FILE (path) > defaults
|
|
23
|
+
*/
|
|
24
|
+
export function loadDensityPolicy(yamlPolicy) {
|
|
25
|
+
// YAML-provided policy has second priority (after inline env var)
|
|
26
|
+
if (yamlPolicy && !process.env.SWT3_DENSITY_POLICY) {
|
|
27
|
+
return { ...DEFAULT_POLICY, ...yamlPolicy };
|
|
28
|
+
}
|
|
29
|
+
const inline = process.env.SWT3_DENSITY_POLICY;
|
|
30
|
+
if (inline) {
|
|
31
|
+
try {
|
|
32
|
+
return { ...DEFAULT_POLICY, ...JSON.parse(inline) };
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// Fall through to file or defaults
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const filePath = process.env.SWT3_DENSITY_POLICY_FILE;
|
|
39
|
+
if (filePath) {
|
|
40
|
+
try {
|
|
41
|
+
const raw = readFileSync(filePath, "utf8");
|
|
42
|
+
return { ...DEFAULT_POLICY, ...JSON.parse(raw) };
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// Fall through to defaults
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return { ...DEFAULT_POLICY };
|
|
49
|
+
}
|
|
50
|
+
// ── Evaluate Policy ───────────────────────────────────────────────────
|
|
51
|
+
/**
|
|
52
|
+
* Evaluate an anchor chain against the density policy.
|
|
53
|
+
*
|
|
54
|
+
* @param policy - The active density policy
|
|
55
|
+
* @param anchors - Chain anchors sorted by epoch ascending
|
|
56
|
+
* @param agentTokenCount - Total tokens produced by the agent (optional, skips density check if absent)
|
|
57
|
+
* @param agentTrustLevel - Trust level of the presenting agent (from verify_agent_trust)
|
|
58
|
+
*/
|
|
59
|
+
export function evaluatePolicy(policy, anchors, agentTokenCount, agentTrustLevel) {
|
|
60
|
+
const violations = [];
|
|
61
|
+
// Rule 1: Anchor density (anchors per 1,000 tokens)
|
|
62
|
+
if (agentTokenCount != null && agentTokenCount > 0 && policy.min_anchors_per_1000_tokens > 0) {
|
|
63
|
+
const expectedAnchors = (agentTokenCount / 1000) * policy.min_anchors_per_1000_tokens;
|
|
64
|
+
if (anchors.length < expectedAnchors) {
|
|
65
|
+
violations.push({
|
|
66
|
+
rule: "anchor_density",
|
|
67
|
+
message: `Insufficient anchor density: ${anchors.length} anchors for ${agentTokenCount} tokens (need ${Math.ceil(expectedAnchors)})`,
|
|
68
|
+
actual: anchors.length,
|
|
69
|
+
required: Math.ceil(expectedAnchors),
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Rule 2: Required providers
|
|
74
|
+
if (policy.required_providers.length > 0) {
|
|
75
|
+
const presentProviders = new Set(anchors.map((a) => a.provider).filter(Boolean));
|
|
76
|
+
for (const required of policy.required_providers) {
|
|
77
|
+
if (!presentProviders.has(required)) {
|
|
78
|
+
violations.push({
|
|
79
|
+
rule: "required_provider",
|
|
80
|
+
message: `Missing required provider: ${required}`,
|
|
81
|
+
actual: [...presentProviders].join(", ") || "none",
|
|
82
|
+
required,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Rule 3: Max chain gap
|
|
88
|
+
if (policy.max_chain_gap_seconds > 0 && anchors.length >= 2) {
|
|
89
|
+
for (let i = 1; i < anchors.length; i++) {
|
|
90
|
+
const gap = anchors[i].anchor_epoch - anchors[i - 1].anchor_epoch;
|
|
91
|
+
if (gap > policy.max_chain_gap_seconds) {
|
|
92
|
+
violations.push({
|
|
93
|
+
rule: "chain_gap",
|
|
94
|
+
message: `Chain gap of ${gap}s exceeds maximum ${policy.max_chain_gap_seconds}s (between anchors ${i - 1} and ${i})`,
|
|
95
|
+
actual: gap,
|
|
96
|
+
required: policy.max_chain_gap_seconds,
|
|
97
|
+
});
|
|
98
|
+
break; // Report first gap only
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Rule 4: Signing requirement
|
|
103
|
+
if (policy.require_signing_key) {
|
|
104
|
+
const unsigned = anchors.filter((a) => !a.payload_signature);
|
|
105
|
+
if (unsigned.length > 0) {
|
|
106
|
+
violations.push({
|
|
107
|
+
rule: "signing_required",
|
|
108
|
+
message: `${unsigned.length} of ${anchors.length} anchors missing payload_signature`,
|
|
109
|
+
actual: anchors.length - unsigned.length,
|
|
110
|
+
required: anchors.length,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Rule 5: Minimum trust level
|
|
115
|
+
if (agentTrustLevel != null && agentTrustLevel < policy.min_trust_level) {
|
|
116
|
+
violations.push({
|
|
117
|
+
rule: "trust_level",
|
|
118
|
+
message: `Agent trust level ${agentTrustLevel} below minimum ${policy.min_trust_level}`,
|
|
119
|
+
actual: agentTrustLevel,
|
|
120
|
+
required: policy.min_trust_level,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
compliant: violations.length === 0,
|
|
125
|
+
violations,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=density-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"density-policy.js","sourceRoot":"","sources":["../src/density-policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SWT3 MCP Server: Redis Stream Reader for real-time anchor freshness.
|
|
3
|
+
*
|
|
4
|
+
* Subscribes to the swt3:anchors Redis stream as a separate consumer group
|
|
5
|
+
* (swt3-mcp-verifiers) and maintains an in-memory index for 0ms lookups.
|
|
6
|
+
* The chain verifier queries this index before falling back to Supabase.
|
|
7
|
+
*
|
|
8
|
+
* Architecture:
|
|
9
|
+
* - Consumer group: swt3-mcp-verifiers (separate from swt3-processors)
|
|
10
|
+
* - XREADGROUP with BLOCK for backpressure-friendly consumption
|
|
11
|
+
* - In-memory index keyed by agent_id and cycle_id
|
|
12
|
+
* - TTL eviction (1 hour) + max entries (10,000 LRU)
|
|
13
|
+
*
|
|
14
|
+
* Patent pending.
|
|
15
|
+
*/
|
|
16
|
+
export interface AnchorEntry {
|
|
17
|
+
messageId: string;
|
|
18
|
+
procedure_id: string;
|
|
19
|
+
anchor_fingerprint: string;
|
|
20
|
+
anchor_epoch: number;
|
|
21
|
+
agent_id?: string;
|
|
22
|
+
cycle_id?: string;
|
|
23
|
+
provider?: string;
|
|
24
|
+
payload_signature?: string;
|
|
25
|
+
verdict?: string;
|
|
26
|
+
ai_input_tokens?: number;
|
|
27
|
+
ai_output_tokens?: number;
|
|
28
|
+
clearing_level?: number;
|
|
29
|
+
receivedAt: number;
|
|
30
|
+
}
|
|
31
|
+
export interface RedisReaderState {
|
|
32
|
+
running: boolean;
|
|
33
|
+
connected: boolean;
|
|
34
|
+
entriesCount: number;
|
|
35
|
+
lastMessageId: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Start the Redis stream reader. No-op if already running or ioredis unavailable.
|
|
39
|
+
*/
|
|
40
|
+
export declare function startRedisReader(opts: {
|
|
41
|
+
redisUrl?: string;
|
|
42
|
+
streamName?: string;
|
|
43
|
+
}): Promise<boolean>;
|
|
44
|
+
/**
|
|
45
|
+
* Stop the Redis reader gracefully.
|
|
46
|
+
*/
|
|
47
|
+
export declare function stopRedisReader(): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Query cached anchors by agent_id and/or cycle_id.
|
|
50
|
+
* Returns empty array if Redis reader not running.
|
|
51
|
+
*/
|
|
52
|
+
export declare function queryAnchors(agentId?: string, cycleId?: string): AnchorEntry[];
|
|
53
|
+
/**
|
|
54
|
+
* Get reader state for health/diagnostics.
|
|
55
|
+
*/
|
|
56
|
+
export declare function getReaderState(): RedisReaderState | null;
|
|
57
|
+
//# sourceMappingURL=redis-reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis-reader.d.ts","sourceRoot":"","sources":["../src/redis-reader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB;AAmCD;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAAC,OAAO,CAAC,CAoDnB;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAwBrD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,WAAW,EAAE,CAc9E;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,gBAAgB,GAAG,IAAI,CAQxD"}
|