settld 0.1.5 → 0.2.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 +32 -0
- package/SETTLD_VERSION +1 -1
- package/bin/settld.js +58 -0
- package/docs/CIRCLE_SANDBOX_E2E.md +12 -0
- package/docs/QUICKSTART_MCP.md +41 -1
- package/docs/QUICKSTART_MCP_HOSTS.md +156 -89
- package/docs/QUICKSTART_POLICY_PACKS.md +65 -0
- package/docs/QUICKSTART_PROFILES.md +198 -0
- package/docs/README.md +18 -0
- package/docs/RELEASE_CHECKLIST.md +26 -0
- package/docs/RELEASING.md +1 -0
- package/docs/SLO.md +62 -1
- package/docs/SUMMARY.md +1 -0
- package/docs/gitbook/README.md +13 -1
- package/docs/gitbook/quickstart.md +57 -58
- package/docs/integrations/README.md +1 -0
- package/docs/integrations/openclaw/PUBLIC_QUICKSTART.md +95 -0
- package/docs/ops/DISPUTE_FINANCE_RECONCILIATION_PACKET.md +56 -0
- package/docs/ops/KERNEL_V0_SHIP_GATE.md +3 -1
- package/docs/ops/MCP_COMPATIBILITY_MATRIX.md +8 -6
- package/docs/ops/PRODUCTION_DEPLOYMENT_CHECKLIST.md +46 -9
- package/docs/ops/TRUST_CONFIG_WIZARD.md +37 -24
- package/docs/plans/2026-02-20-trust-os-v1-jira-backlog.md +348 -0
- package/docs/plans/2026-02-21-agent-economic-actor-operating-model.md +169 -0
- package/docs/plans/2026-02-21-trust-os-v1-strategy.md +241 -0
- package/docs/research/2026-02-21-agent-spend-host-landscape.md +57 -0
- package/docs/spec/ArbitrationOutcomeMapping.v1.md +62 -0
- package/docs/spec/DisputeCaseLifecycle.v1.md +51 -0
- package/docs/spec/OperatorAction.v1.md +90 -0
- package/docs/spec/PolicyDecision.v1.md +83 -0
- package/docs/spec/README.md +5 -0
- package/docs/spec/SettlementDecisionRecord.v2.md +2 -0
- package/docs/spec/schemas/OperatorAction.v1.schema.json +113 -0
- package/docs/spec/schemas/PolicyDecision.v1.schema.json +74 -0
- package/docs/spec/schemas/SettlementDecisionRecord.v2.schema.json +1 -0
- package/docs/spec/x402-error-codes.v1.txt +14 -0
- package/package.json +14 -1
- package/scripts/ci/build-launch-cutover-packet.mjs +177 -21
- package/scripts/ci/run-10x-throughput-drill.mjs +76 -4
- package/scripts/ci/run-10x-throughput-incident-rehearsal.mjs +49 -6
- package/scripts/ci/run-mcp-host-cert-matrix.mjs +201 -0
- package/scripts/ci/run-mcp-host-smoke.mjs +203 -5
- package/scripts/ci/run-offline-verification-parity-gate.mjs +762 -0
- package/scripts/ci/run-onboarding-host-success-gate.mjs +516 -0
- package/scripts/ci/run-onboarding-policy-slo-gate.mjs +537 -0
- package/scripts/ci/run-production-cutover-gate.mjs +540 -0
- package/scripts/ci/run-public-openclaw-npx-smoke.mjs +148 -0
- package/scripts/ci/run-release-promotion-guard.mjs +756 -0
- package/scripts/doctor/mcp-host.mjs +120 -0
- package/scripts/mcp/settld-mcp-server.mjs +330 -20
- package/scripts/ops/dispute-finance-reconciliation-packet.mjs +313 -0
- package/scripts/ops/hosted-baseline-evidence.mjs +286 -77
- package/scripts/ops/run-x402-hitl-smoke.mjs +607 -0
- package/scripts/policy/cli.mjs +600 -0
- package/scripts/profile/cli.mjs +1324 -0
- package/scripts/register-entity-secret.mjs +102 -0
- package/scripts/setup/circle-bootstrap.mjs +310 -0
- package/scripts/setup/host-config.mjs +617 -0
- package/scripts/setup/onboard.mjs +1337 -0
- package/scripts/setup/openclaw-onboard.mjs +423 -0
- package/scripts/setup/wizard.mjs +986 -0
- package/scripts/slo/check.mjs +123 -62
- package/scripts/spec/generate-protocol-vectors.mjs +88 -0
- package/scripts/test/run.sh +23 -9
- package/services/x402-gateway/src/server.js +147 -36
- package/src/api/app.js +2345 -267
- package/src/api/middleware/trust-kernel.js +114 -0
- package/src/api/openapi.js +598 -3
- package/src/api/persistence.js +184 -0
- package/src/api/store.js +277 -0
- package/src/core/agent-wallets.js +134 -0
- package/src/core/event-policy.js +21 -2
- package/src/core/operator-action.js +303 -0
- package/src/core/policy-decision.js +322 -0
- package/src/core/policy-packs.js +207 -0
- package/src/core/profile-fingerprint.js +27 -0
- package/src/core/profile-simulation-reasons.js +84 -0
- package/src/core/profile-templates.js +242 -0
- package/src/core/settlement-kernel.js +27 -1
- package/src/core/wallet-assignment-resolver.js +129 -0
- package/src/core/wallet-provider-bootstrap.js +365 -0
- package/src/db/store-pg.js +631 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { authorize } from "./authz.js";
|
|
2
|
+
|
|
3
|
+
const HIGH_RISK_WRITE_ROUTES = Object.freeze([
|
|
4
|
+
{ id: "x402_wallet_authorize", method: "POST", path: /^\/x402\/wallets\/[^/]+\/authorize$/, requiredScopes: ["FINANCE_WRITE"] },
|
|
5
|
+
{ id: "x402_gate_create", method: "POST", path: /^\/x402\/gate\/create$/, requiredScopes: ["FINANCE_WRITE"] },
|
|
6
|
+
{ id: "x402_gate_quote", method: "POST", path: /^\/x402\/gate\/quote$/, requiredScopes: ["FINANCE_WRITE"] },
|
|
7
|
+
{ id: "x402_gate_authorize_payment", method: "POST", path: /^\/x402\/gate\/authorize-payment$/, requiredScopes: ["FINANCE_WRITE"] },
|
|
8
|
+
{ id: "x402_gate_verify", method: "POST", path: /^\/x402\/gate\/verify$/, requiredScopes: ["FINANCE_WRITE"] },
|
|
9
|
+
{ id: "x402_gate_reversal", method: "POST", path: /^\/x402\/gate\/reversal$/, requiredScopes: ["FINANCE_WRITE"] },
|
|
10
|
+
{
|
|
11
|
+
id: "x402_gate_escalation_resolve",
|
|
12
|
+
method: "POST",
|
|
13
|
+
path: /^\/x402\/gate\/escalations\/[^/]+\/resolve$/,
|
|
14
|
+
requiredScopes: ["FINANCE_WRITE"]
|
|
15
|
+
},
|
|
16
|
+
{ id: "x402_gate_wind_down", method: "POST", path: /^\/x402\/gate\/agents\/[^/]+\/wind-down$/, requiredScopes: ["OPS_WRITE"] }
|
|
17
|
+
]);
|
|
18
|
+
|
|
19
|
+
function normalizeMethod(value) {
|
|
20
|
+
return typeof value === "string" ? value.trim().toUpperCase() : "";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function normalizePath(value) {
|
|
24
|
+
return typeof value === "string" ? value.trim() : "";
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function normalizeSha256(value) {
|
|
28
|
+
const text = typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
29
|
+
return /^[0-9a-f]{64}$/.test(text) ? text : null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function fail({ code, message, details = null, statusCode = 409 } = {}) {
|
|
33
|
+
return { ok: false, code, message, details, statusCode };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function resolveTrustKernelHighRiskWriteRoute({ method, path } = {}) {
|
|
37
|
+
const normalizedMethod = normalizeMethod(method);
|
|
38
|
+
const normalizedPath = normalizePath(path);
|
|
39
|
+
for (const route of HIGH_RISK_WRITE_ROUTES) {
|
|
40
|
+
if (route.method !== normalizedMethod) continue;
|
|
41
|
+
if (!route.path.test(normalizedPath)) continue;
|
|
42
|
+
return route;
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function guardHighRiskTrustKernelWrite({ method, path, auth, opsScopes } = {}) {
|
|
48
|
+
const route = resolveTrustKernelHighRiskWriteRoute({ method, path });
|
|
49
|
+
if (!route) return { ok: true, routeId: null };
|
|
50
|
+
if (!auth || auth.ok !== true) {
|
|
51
|
+
return fail({ statusCode: 403, code: "FORBIDDEN", message: "forbidden", details: { routeId: route.id } });
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const requiredScopes = [];
|
|
55
|
+
for (const scopeName of route.requiredScopes) {
|
|
56
|
+
const scopeValue = opsScopes && typeof opsScopes === "object" ? opsScopes[scopeName] : null;
|
|
57
|
+
if (typeof scopeValue === "string" && scopeValue.trim() !== "") requiredScopes.push(scopeValue.trim());
|
|
58
|
+
}
|
|
59
|
+
if (!requiredScopes.length) {
|
|
60
|
+
return fail({ statusCode: 403, code: "FORBIDDEN", message: "forbidden", details: { routeId: route.id } });
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const allowed = authorize({ scopes: auth.scopes, requiredScopes, mode: "any" });
|
|
64
|
+
if (!allowed) {
|
|
65
|
+
return fail({ statusCode: 403, code: "FORBIDDEN", message: "forbidden", details: { routeId: route.id } });
|
|
66
|
+
}
|
|
67
|
+
return { ok: true, routeId: route.id };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function guardExecutionIntentRequestBindingConsistency({
|
|
71
|
+
executionIntent,
|
|
72
|
+
requestBindingMode,
|
|
73
|
+
requestBindingSha256
|
|
74
|
+
} = {}) {
|
|
75
|
+
if (!executionIntent || typeof executionIntent !== "object" || Array.isArray(executionIntent)) {
|
|
76
|
+
return { ok: true, expectedRequestSha256: null };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const intentRequestSha256 = normalizeSha256(executionIntent?.requestFingerprint?.requestSha256);
|
|
80
|
+
if (!intentRequestSha256) {
|
|
81
|
+
return fail({
|
|
82
|
+
code: "X402_EXECUTION_INTENT_REQUEST_MISMATCH",
|
|
83
|
+
message: "execution intent request fingerprint does not match request binding",
|
|
84
|
+
details: { expectedRequestSha256: null, requestBindingSha256: normalizeSha256(requestBindingSha256) }
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const mode = typeof requestBindingMode === "string" ? requestBindingMode.trim().toLowerCase() : null;
|
|
89
|
+
if (mode !== "strict") {
|
|
90
|
+
return fail({
|
|
91
|
+
code: "X402_EXECUTION_INTENT_REQUEST_BINDING_REQUIRED",
|
|
92
|
+
message: "execution intent requires strict request binding",
|
|
93
|
+
details: { expectedRequestSha256: intentRequestSha256, requestBindingMode: mode }
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const normalizedBindingSha256 = normalizeSha256(requestBindingSha256);
|
|
98
|
+
if (!normalizedBindingSha256) {
|
|
99
|
+
return fail({
|
|
100
|
+
code: "X402_EXECUTION_INTENT_REQUEST_BINDING_REQUIRED",
|
|
101
|
+
message: "execution intent requires strict request binding",
|
|
102
|
+
details: { expectedRequestSha256: intentRequestSha256, requestBindingMode: mode, requestBindingSha256: null }
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
if (intentRequestSha256 !== normalizedBindingSha256) {
|
|
106
|
+
return fail({
|
|
107
|
+
code: "X402_EXECUTION_INTENT_REQUEST_MISMATCH",
|
|
108
|
+
message: "execution intent request fingerprint does not match request binding",
|
|
109
|
+
details: { expectedRequestSha256: intentRequestSha256, requestBindingSha256: normalizedBindingSha256 }
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return { ok: true, expectedRequestSha256: intentRequestSha256 };
|
|
114
|
+
}
|