@nomosprotocol/sdk 1.1.0 → 1.2.1
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 +118 -0
- package/dist/index.cjs +106 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +142 -13
- package/dist/index.d.ts +142 -13
- package/dist/index.js +103 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# @nomosprotocol/sdk
|
|
2
|
+
|
|
3
|
+
Official TypeScript SDK for [NOMOS](https://www.nomosprotocol.com) — ask a public authority a question from your code and get back a deterministic, cryptographically verifiable verdict.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install @nomosprotocol/sdk
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## `nomos.can()` — the keyless primitive
|
|
10
|
+
|
|
11
|
+
Every public authority on the [NOMOS Exchange](https://www.nomosprotocol.com/exchange) is queryable with one call. No API key, no setup — this is the front door.
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { nomos } from "@nomosprotocol/sdk";
|
|
15
|
+
|
|
16
|
+
const verdict = await nomos.can({
|
|
17
|
+
authority: "eu-ai-act.nomos",
|
|
18
|
+
ai_categorises_biometric_data_for_sensitive_attributes: true,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
if (!verdict.allowed) {
|
|
22
|
+
console.log(verdict.verdict); // "DENIED"
|
|
23
|
+
console.log(verdict.reason); // why
|
|
24
|
+
console.log(verdict.query_id); // permanent transcript id
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Facts can be spread flat alongside `authority` (as above), or passed explicitly:
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
const verdict = await nomos.can({
|
|
32
|
+
authority: "eu-ai-act.nomos",
|
|
33
|
+
inputs: { ai_categorises_biometric_data_for_sensitive_attributes: true },
|
|
34
|
+
action: "screen a new feature before launch", // optional, recorded in the transcript
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### The verdict
|
|
39
|
+
|
|
40
|
+
`nomos.can()` always returns the authority's own verdict, verbatim — nothing invented, nothing paraphrased:
|
|
41
|
+
|
|
42
|
+
| Field | Type | Meaning |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| `allowed` | `boolean` | `true` only when `verdict === "AUTHORIZED"` |
|
|
45
|
+
| `verdict` | `"AUTHORIZED" \| "DENIED" \| "ESCALATED"` | The authority's own answer |
|
|
46
|
+
| `reason` | `string` | Human-readable explanation |
|
|
47
|
+
| `rule` | `string \| null` | The rule id that decided it, if any |
|
|
48
|
+
| `query_id` | `string` | Permanent, addressable transcript id |
|
|
49
|
+
| `url` | `string` | Path to the transcript's permalink page |
|
|
50
|
+
| `authority` | `{ id, title, standing }` | Which authority answered, and its standing |
|
|
51
|
+
| `missing_inputs` | `string[]` | Fields the authority needed but didn't get — present on `ESCALATED` |
|
|
52
|
+
|
|
53
|
+
`ESCALATED` means the authority needs more facts to decide — not a flat no. Check `missing_inputs` for what to supply.
|
|
54
|
+
|
|
55
|
+
Every call mints a permanent, cryptographically sealed transcript — open `query_id` any time at `nomosprotocol.com/queries/<query_id>` to replay exactly what was asked and answered, bound to the exact authority version that responded.
|
|
56
|
+
|
|
57
|
+
### Error handling
|
|
58
|
+
|
|
59
|
+
A failed call (unknown authority, network issue, upstream error) rejects with a typed `NomosError` subclass — never a bare `Error` — so you can branch on `instanceof` or the stable `.code` string:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import { nomos, NomosNotFoundError, NomosNetworkError } from "@nomosprotocol/sdk";
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
const verdict = await nomos.can({ authority: "eu-ai-act.nomos", ...facts });
|
|
66
|
+
} catch (err) {
|
|
67
|
+
if (err instanceof NomosNotFoundError) {
|
|
68
|
+
// authority slug/id doesn't exist — err.code === 'not_found'
|
|
69
|
+
} else if (err instanceof NomosNetworkError) {
|
|
70
|
+
// request timed out or the network failed
|
|
71
|
+
} else {
|
|
72
|
+
throw err;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Options
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
await nomos.can(
|
|
81
|
+
{ authority: "...", ...facts },
|
|
82
|
+
{
|
|
83
|
+
baseUrl: "https://www.nomosprotocol.com", // override for local/staging use
|
|
84
|
+
signal: abortController.signal, // cancel the request
|
|
85
|
+
},
|
|
86
|
+
);
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## `Nomos` — authenticated client
|
|
90
|
+
|
|
91
|
+
For private/custom artifacts, governance generation, and webhook verification, use the authenticated client:
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
import { Nomos } from "@nomosprotocol/sdk";
|
|
95
|
+
|
|
96
|
+
const client = new Nomos("nms_live_..."); // or "nms_test_..." for test mode
|
|
97
|
+
|
|
98
|
+
const result = await client.decisions.verify({
|
|
99
|
+
artifact_id: "your_artifact_id",
|
|
100
|
+
decision_context: { /* facts */ },
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
for await (const artifact of client.artifacts.listAutoPaging()) {
|
|
104
|
+
console.log(artifact.id);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const event = await client.webhooks.constructEvent(payload, signatureHeader, webhookSecret);
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
See [nomosprotocol.com/docs](https://www.nomosprotocol.com/docs) for full API reference, error types, and webhook event shapes.
|
|
111
|
+
|
|
112
|
+
## Requirements
|
|
113
|
+
|
|
114
|
+
Node.js 18+. Ships as dual ESM/CJS with full TypeScript types.
|
|
115
|
+
|
|
116
|
+
## License
|
|
117
|
+
|
|
118
|
+
MIT
|
package/dist/index.cjs
CHANGED
|
@@ -29,7 +29,9 @@ __export(index_exports, {
|
|
|
29
29
|
NomosNotFoundError: () => NomosNotFoundError,
|
|
30
30
|
NomosRateLimitError: () => NomosRateLimitError,
|
|
31
31
|
NomosValidationError: () => NomosValidationError,
|
|
32
|
-
NomosWebhookSignatureError: () => NomosWebhookSignatureError
|
|
32
|
+
NomosWebhookSignatureError: () => NomosWebhookSignatureError,
|
|
33
|
+
can: () => can,
|
|
34
|
+
nomos: () => nomos
|
|
33
35
|
});
|
|
34
36
|
module.exports = __toCommonJS(index_exports);
|
|
35
37
|
|
|
@@ -255,21 +257,28 @@ var Decisions = class {
|
|
|
255
257
|
} else {
|
|
256
258
|
httpResp = await this.http.post("/api/v1/verify-decision", {
|
|
257
259
|
artifact_id,
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
correlation_id: correlation_id ?? globalThis.crypto.randomUUID()
|
|
260
|
+
decision: proposed_decision ?? "evaluate",
|
|
261
|
+
inputs: decision_context,
|
|
262
|
+
caller: { correlation_id: correlation_id ?? globalThis.crypto.randomUUID() }
|
|
261
263
|
}, opts);
|
|
262
264
|
}
|
|
263
265
|
const raw = httpResp.data;
|
|
264
266
|
return {
|
|
267
|
+
id: raw.id ?? `req_${raw.execution_id ?? globalThis.crypto.randomUUID()}`,
|
|
268
|
+
object: raw.object ?? "decision",
|
|
269
|
+
artifact_id: raw.artifact_id ?? artifact_id,
|
|
270
|
+
artifact_name: raw.artifact_name ?? "",
|
|
265
271
|
allowed: raw.allowed ?? false,
|
|
266
|
-
verdict: raw.
|
|
272
|
+
verdict: raw.verdict ?? (raw.outcome === "auto_approved" ? "approved" : raw.outcome === "auto_rejected" ? "rejected" : "escalated"),
|
|
273
|
+
rule: raw.rule,
|
|
274
|
+
evaluation: raw.evaluation ?? { rules_evaluated: raw.rules_evaluated ?? 0, rules_matched: 0, rules_expired: 0, conflicts_resolved: 0 },
|
|
275
|
+
confidence: raw.confidence ?? { tier: raw.artifact_confidence ?? "DECLARED", score: 1, description: "" },
|
|
276
|
+
audit: raw.audit ?? { hash: raw.audit_hash ?? raw.audit_record ?? "", timestamp: raw.ts ?? (/* @__PURE__ */ new Date()).toISOString() },
|
|
277
|
+
performance: raw.performance ?? { latency_ms: raw.latency_ms ?? 0 },
|
|
278
|
+
schema_version: raw.schema_version ?? "1.0.0",
|
|
267
279
|
verdict_description: raw.verdict_description ?? "",
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
artifact_id: raw.artifact_id ?? artifact_id,
|
|
271
|
-
execution_id: raw.execution_id,
|
|
272
|
-
decided_at: raw.decided_at ?? raw.evaluated_at ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
280
|
+
incomplete_inputs: raw.incomplete_inputs,
|
|
281
|
+
paths_to_approval: raw.paths_to_approval,
|
|
273
282
|
lastResponse: httpResp.lastResponse
|
|
274
283
|
};
|
|
275
284
|
}
|
|
@@ -345,6 +354,27 @@ var Artifacts = class {
|
|
|
345
354
|
offset += page.data.length;
|
|
346
355
|
}
|
|
347
356
|
}
|
|
357
|
+
/**
|
|
358
|
+
* Retrieve the declared input schema for a sealed artifact.
|
|
359
|
+
*
|
|
360
|
+
* Returns every field the artifact's rules reference — name, type, whether it's
|
|
361
|
+
* required, and a ready-to-use example_inputs object. Use this to build forms,
|
|
362
|
+
* validate payloads, or generate API docs without reading the rules manually.
|
|
363
|
+
*
|
|
364
|
+
* Requires an API key (artifact schemas are not public).
|
|
365
|
+
*
|
|
366
|
+
* @example
|
|
367
|
+
* const schema = await nomos.artifacts.schema('art_abc123');
|
|
368
|
+
* console.log(schema.required_fields); // ['credit_score', 'loan_amount']
|
|
369
|
+
* console.log(schema.example_inputs); // { credit_score: 0, loan_amount: 0 }
|
|
370
|
+
*/
|
|
371
|
+
async schema(artifactId, opts) {
|
|
372
|
+
const { data, lastResponse } = await this.http.get(
|
|
373
|
+
`/api/v1/artifacts/${encodeURIComponent(artifactId)}/schema`,
|
|
374
|
+
opts
|
|
375
|
+
);
|
|
376
|
+
return { ...data, lastResponse };
|
|
377
|
+
}
|
|
348
378
|
};
|
|
349
379
|
|
|
350
380
|
// src/resources/governance.ts
|
|
@@ -523,6 +553,69 @@ var Nomos = class {
|
|
|
523
553
|
this.webhooks = new Webhooks();
|
|
524
554
|
}
|
|
525
555
|
};
|
|
556
|
+
|
|
557
|
+
// src/can.ts
|
|
558
|
+
var DEFAULT_EXCHANGE_BASE = "https://www.nomosprotocol.com";
|
|
559
|
+
async function can(params, opts) {
|
|
560
|
+
const { authority, action, inputs, ...flat } = params;
|
|
561
|
+
if (!authority || typeof authority !== "string") {
|
|
562
|
+
throw new Error("can(): `authority` (an Exchange artifact id or slug) is required.");
|
|
563
|
+
}
|
|
564
|
+
const facts = inputs && typeof inputs === "object" ? inputs : flat;
|
|
565
|
+
const base = (opts?.baseUrl ?? DEFAULT_EXCHANGE_BASE).replace(/\/$/, "");
|
|
566
|
+
const url = `${base}/api/exchange/artifacts/${encodeURIComponent(authority)}/query`;
|
|
567
|
+
let res;
|
|
568
|
+
try {
|
|
569
|
+
res = await fetch(url, {
|
|
570
|
+
method: "POST",
|
|
571
|
+
headers: { "Content-Type": "application/json" },
|
|
572
|
+
body: JSON.stringify({ inputs: facts, action }),
|
|
573
|
+
signal: opts?.signal
|
|
574
|
+
});
|
|
575
|
+
} catch (err) {
|
|
576
|
+
if (err?.name === "AbortError") throw new NomosNetworkError("Request aborted");
|
|
577
|
+
throw new NomosNetworkError(err?.message ?? "Network error");
|
|
578
|
+
}
|
|
579
|
+
const requestId = res.headers.get("x-request-id") ?? "";
|
|
580
|
+
const data = await res.json().catch(() => null);
|
|
581
|
+
if (!res.ok) {
|
|
582
|
+
const message = data?.error ?? data?.message ?? `NOMOS query failed (HTTP ${res.status})`;
|
|
583
|
+
switch (res.status) {
|
|
584
|
+
case 401:
|
|
585
|
+
throw new NomosAuthenticationError(message, requestId);
|
|
586
|
+
case 403:
|
|
587
|
+
throw new NomosAuthorizationError(message, requestId);
|
|
588
|
+
case 404:
|
|
589
|
+
throw new NomosNotFoundError(message, requestId);
|
|
590
|
+
case 422:
|
|
591
|
+
case 400:
|
|
592
|
+
throw new NomosValidationError(message, data?.details, requestId);
|
|
593
|
+
case 429:
|
|
594
|
+
throw new NomosRateLimitError(
|
|
595
|
+
message,
|
|
596
|
+
res.headers.get("retry-after") ? parseInt(res.headers.get("retry-after"), 10) : void 0,
|
|
597
|
+
requestId
|
|
598
|
+
);
|
|
599
|
+
default:
|
|
600
|
+
throw new NomosAPIError(message, res.status, requestId);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
return {
|
|
604
|
+
allowed: data.verdict === "AUTHORIZED",
|
|
605
|
+
verdict: data.verdict,
|
|
606
|
+
reason: data.verdict_description,
|
|
607
|
+
rule: data.matched_rule_id ?? null,
|
|
608
|
+
query_id: data.query_id,
|
|
609
|
+
url: data.url,
|
|
610
|
+
authority: {
|
|
611
|
+
id: data.artifact?.id ?? authority,
|
|
612
|
+
title: data.artifact?.title ?? "",
|
|
613
|
+
standing: data.artifact?.standing ?? ""
|
|
614
|
+
},
|
|
615
|
+
missing_inputs: data.missing_inputs ?? []
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
var nomos = { can };
|
|
526
619
|
// Annotate the CommonJS export names for ESM import in node:
|
|
527
620
|
0 && (module.exports = {
|
|
528
621
|
Nomos,
|
|
@@ -534,6 +627,8 @@ var Nomos = class {
|
|
|
534
627
|
NomosNotFoundError,
|
|
535
628
|
NomosRateLimitError,
|
|
536
629
|
NomosValidationError,
|
|
537
|
-
NomosWebhookSignatureError
|
|
630
|
+
NomosWebhookSignatureError,
|
|
631
|
+
can,
|
|
632
|
+
nomos
|
|
538
633
|
});
|
|
539
634
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/util.ts","../src/http-client.ts","../src/resources/decisions.ts","../src/resources/artifacts.ts","../src/resources/governance.ts","../src/resources/webhooks.ts","../src/nomos.ts"],"sourcesContent":["export { Nomos } from './nomos.js';\nexport * from './errors.js';\nexport type {\n NomosConfig,\n RequestOptions,\n NomosRawResponse,\n WithLastResponse,\n VerifyDecisionParams,\n VerifyDecisionResult,\n ListArtifactsParams,\n ArtifactList,\n Artifact,\n GenerateGovernanceParams,\n GenerateGovernanceResult,\n DetectContradictionsParams,\n DetectContradictionsResult,\n Contradiction,\n Verdict,\n NomosWebhookEvent,\n NomosWebhookEventType,\n} from './types.js';\n","export type NomosErrorCode =\n | 'authentication_error'\n | 'authorization_error'\n | 'rate_limit_error'\n | 'validation_error'\n | 'not_found'\n | 'api_error'\n | 'network_error'\n | 'webhook_signature_error';\n\nexport class NomosError extends Error {\n readonly code: NomosErrorCode;\n readonly status?: number;\n readonly requestId?: string;\n\n constructor(message: string, code: NomosErrorCode, status?: number, requestId?: string) {\n super(message);\n this.name = 'NomosError';\n this.code = code;\n this.status = status;\n this.requestId = requestId;\n }\n}\n\nexport class NomosAuthenticationError extends NomosError {\n constructor(message = 'Invalid API key', requestId?: string) {\n super(message, 'authentication_error', 401, requestId);\n this.name = 'NomosAuthenticationError';\n }\n}\n\nexport class NomosAuthorizationError extends NomosError {\n constructor(message = 'Access denied', requestId?: string) {\n super(message, 'authorization_error', 403, requestId);\n this.name = 'NomosAuthorizationError';\n }\n}\n\nexport class NomosRateLimitError extends NomosError {\n readonly retryAfter?: number;\n\n constructor(message = 'Rate limit exceeded', retryAfter?: number, requestId?: string) {\n super(message, 'rate_limit_error', 429, requestId);\n this.name = 'NomosRateLimitError';\n this.retryAfter = retryAfter;\n }\n}\n\nexport class NomosValidationError extends NomosError {\n readonly details?: unknown;\n\n constructor(message: string, details?: unknown, requestId?: string) {\n super(message, 'validation_error', 400, requestId);\n this.name = 'NomosValidationError';\n this.details = details;\n }\n}\n\nexport class NomosNotFoundError extends NomosError {\n constructor(message: string, requestId?: string) {\n super(message, 'not_found', 404, requestId);\n this.name = 'NomosNotFoundError';\n }\n}\n\nexport class NomosAPIError extends NomosError {\n constructor(message: string, status: number, requestId?: string) {\n super(message, 'api_error', status, requestId);\n this.name = 'NomosAPIError';\n }\n}\n\nexport class NomosNetworkError extends NomosError {\n constructor(message: string) {\n super(message, 'network_error');\n this.name = 'NomosNetworkError';\n }\n}\n\nexport class NomosWebhookSignatureError extends NomosError {\n constructor(message: string) {\n super(message, 'webhook_signature_error', 400);\n this.name = 'NomosWebhookSignatureError';\n }\n}\n","export async function sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nexport function jitteredBackoff(attempt: number, baseMs = 500): number {\n const exp = Math.min(baseMs * 2 ** attempt, 16000);\n return exp * (0.75 + Math.random() * 0.5); // ±25% jitter\n}\n\nexport function isRetryable(status: number): boolean {\n return status === 429 || status >= 500;\n}\n","import {\n NomosAuthenticationError,\n NomosAuthorizationError,\n NomosRateLimitError,\n NomosValidationError,\n NomosNotFoundError,\n NomosAPIError,\n NomosNetworkError,\n} from './errors.js';\nimport { sleep, jitteredBackoff, isRetryable } from './util.js';\nimport type { RequestOptions, NomosRawResponse } from './types.js';\n\nconst SDK_VERSION = '1.1.0';\n\nexport interface HttpClientOptions {\n apiKey: string;\n baseUrl: string;\n maxRetries: number;\n timeout: number;\n}\n\nexport interface HttpResponse<T> {\n data: T;\n lastResponse: NomosRawResponse;\n}\n\nexport class HttpClient {\n constructor(private readonly opts: HttpClientOptions) {}\n\n async get<T>(path: string, reqOpts?: RequestOptions): Promise<HttpResponse<T>> {\n return this.request<T>('GET', path, undefined, reqOpts);\n }\n\n async post<T>(path: string, body: unknown, reqOpts?: RequestOptions): Promise<HttpResponse<T>> {\n return this.request<T>('POST', path, body, reqOpts);\n }\n\n private async request<T>(\n method: string,\n path: string,\n body: unknown,\n reqOpts?: RequestOptions,\n attempt = 0,\n ): Promise<HttpResponse<T>> {\n const apiKey = reqOpts?.apiKey ?? this.opts.apiKey;\n const timeout = reqOpts?.timeout ?? this.opts.timeout;\n const maxRetries = reqOpts?.maxRetries ?? this.opts.maxRetries;\n\n const url = `${this.opts.baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeout);\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-Nomos-Api-Key': apiKey,\n 'User-Agent': `nomos-node/${SDK_VERSION}`,\n 'NOMOS-SDK-Version': SDK_VERSION,\n };\n if (reqOpts?.idempotencyKey) {\n headers['Idempotency-Key'] = reqOpts.idempotencyKey;\n }\n\n let res: Response;\n try {\n res = await fetch(url, {\n method,\n signal: controller.signal,\n headers,\n body: body != null ? JSON.stringify(body) : undefined,\n });\n } catch (err: any) {\n clearTimeout(timer);\n if (err.name === 'AbortError') {\n throw new NomosNetworkError(`Request timed out after ${timeout}ms`);\n }\n throw new NomosNetworkError(err.message ?? 'Network error');\n } finally {\n clearTimeout(timer);\n }\n\n const requestId = res.headers.get('x-request-id') ?? '';\n const rawHeaders: Record<string, string> = {};\n res.headers.forEach((value, key) => { rawHeaders[key] = value; });\n const lastResponse: NomosRawResponse = {\n requestId,\n statusCode: res.status,\n headers: rawHeaders,\n };\n\n if (res.ok) {\n const data = await res.json() as T;\n return { data, lastResponse };\n }\n\n // Retry on 429 / 5xx\n if (isRetryable(res.status) && attempt < maxRetries) {\n const retryAfter = res.headers.get('retry-after');\n const delay = retryAfter ? parseInt(retryAfter, 10) * 1000 : jitteredBackoff(attempt);\n await sleep(delay);\n return this.request<T>(method, path, body, reqOpts, attempt + 1);\n }\n\n let errBody: any = {};\n try { errBody = await res.json(); } catch {}\n const message: string = errBody?.error ?? errBody?.message ?? res.statusText;\n\n switch (res.status) {\n case 401: throw new NomosAuthenticationError(message, requestId);\n case 403: throw new NomosAuthorizationError(message, requestId);\n case 404: throw new NomosNotFoundError(message, requestId);\n case 422:\n case 400: throw new NomosValidationError(message, errBody?.details, requestId);\n case 429: throw new NomosRateLimitError(\n message,\n res.headers.get('retry-after') ? parseInt(res.headers.get('retry-after')!, 10) : undefined,\n requestId,\n );\n default: throw new NomosAPIError(message, res.status, requestId);\n }\n }\n}\n","import type { HttpClient } from '../http-client.js';\nimport type {\n VerifyDecisionParams,\n VerifyDecisionResult,\n RequestOptions,\n WithLastResponse,\n} from '../types.js';\n\nexport class Decisions {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Verify whether an AI decision is permitted under a governance artifact.\n *\n * Public demo artifacts (`pub_*`) work without an API key.\n * Custom artifacts require a valid API key.\n *\n * @example\n * const result = await nomos.decisions.verify({\n * artifact_id: 'pub_lending_v1',\n * decision_context: { credit_score: 720, loan_amount: 50000 },\n * });\n *\n * if (!result.allowed) {\n * throw new Error(`Blocked: ${result.verdict_description}`);\n * }\n *\n * // Debugging / tracing\n * console.log(result.lastResponse.requestId);\n *\n * @example\n * // Per-request options\n * const result = await nomos.decisions.verify(params, {\n * idempotencyKey: `verify-${transactionId}`,\n * timeout: 5000,\n * });\n */\n async verify(\n params: VerifyDecisionParams,\n opts?: RequestOptions,\n ): Promise<WithLastResponse<VerifyDecisionResult>> {\n const { artifact_id, decision_context, proposed_decision, correlation_id } = params;\n\n // Public artifacts (pub_*) use the open /verify endpoint — no API key required\n const isPublic = artifact_id.startsWith('pub_');\n let httpResp: Awaited<ReturnType<HttpClient['post']>>;\n\n if (isPublic) {\n httpResp = await this.http.post<any>('/api/v1/verify', {\n artifact_id,\n decision: proposed_decision ?? 'evaluate',\n inputs: decision_context,\n }, opts);\n } else {\n httpResp = await this.http.post<any>('/api/v1/verify-decision', {\n artifact_id,\n decision_context,\n proposed_decision,\n correlation_id: correlation_id ?? globalThis.crypto.randomUUID(),\n }, opts);\n }\n\n const raw: any = httpResp.data;\n\n return {\n allowed: raw.allowed ?? false,\n verdict: raw.outcome ?? raw.verdict ?? 'pending_human_review',\n verdict_description: raw.verdict_description ?? '',\n rule_reference: raw.rule_reference ?? raw.rule_applied,\n audit_record: raw.audit_record ?? raw.audit_hash,\n artifact_id: raw.artifact_id ?? artifact_id,\n execution_id: raw.execution_id,\n decided_at: raw.decided_at ?? raw.evaluated_at ?? new Date().toISOString(),\n lastResponse: httpResp.lastResponse,\n };\n }\n}\n","import type { HttpClient } from '../http-client.js';\nimport type {\n Artifact,\n ArtifactList,\n ListArtifactsParams,\n RequestOptions,\n WithLastResponse,\n} from '../types.js';\n\nexport class Artifacts {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Retrieve a single artifact by ID.\n *\n * @example\n * const artifact = await nomos.artifacts.retrieve('loan_approval_v1');\n * console.log(artifact.ari_score, artifact.autonomy_band);\n * console.log(artifact.lastResponse.requestId); // for support tickets\n */\n async retrieve(\n artifactId: string,\n opts?: RequestOptions,\n ): Promise<WithLastResponse<Artifact>> {\n const { data, lastResponse } = await this.http.get<Artifact>(\n `/api/exchange/artifacts/${encodeURIComponent(artifactId)}`,\n opts,\n );\n return { ...data, lastResponse };\n }\n\n /**\n * List published artifacts on the Exchange with optional filters.\n *\n * @example\n * const { data, total } = await nomos.artifacts.list({ band: 'autonomous', limit: 10 });\n *\n * @example\n * // With per-request options\n * const page = await nomos.artifacts.list({ limit: 20 }, { timeout: 5000 });\n */\n async list(\n params: ListArtifactsParams = {},\n opts?: RequestOptions,\n ): Promise<WithLastResponse<ArtifactList>> {\n const qs = new URLSearchParams();\n if (params.band) qs.set('band', params.band);\n if (params.domain) qs.set('domain', params.domain);\n if (params.jurisdiction) qs.set('jurisdiction', params.jurisdiction);\n if (params.sort) qs.set('sort', params.sort);\n if (params.limit != null) qs.set('limit', String(params.limit));\n if (params.offset != null) qs.set('offset', String(params.offset));\n const query = qs.toString();\n\n const { data: raw, lastResponse } = await this.http.get<any>(\n `/api/exchange/artifacts${query ? `?${query}` : ''}`,\n opts,\n );\n\n // API returns { artifacts: [], total: N } — normalise to { data: [], total: N }\n const normalized: ArtifactList = {\n data: Array.isArray(raw) ? raw : (raw.artifacts ?? raw.data ?? []),\n total: raw.total ?? (Array.isArray(raw) ? raw.length : 0),\n limit: params.limit ?? 20,\n offset: params.offset ?? 0,\n };\n\n return { ...normalized, lastResponse };\n }\n\n /**\n * Auto-paginating iterator — yields every artifact across all pages.\n * Stops automatically when the last page is reached.\n *\n * @example\n * for await (const artifact of nomos.artifacts.listAutoPaging({ band: 'autonomous' })) {\n * console.log(artifact.title, artifact.ari_score);\n * }\n */\n async *listAutoPaging(\n params: ListArtifactsParams = {},\n opts?: RequestOptions,\n ): AsyncGenerator<Artifact> {\n let offset = params.offset ?? 0;\n const limit = params.limit ?? 20;\n\n while (true) {\n const page = await this.list({ ...params, offset, limit }, opts);\n for (const item of page.data) yield item;\n if (page.data.length < limit || offset + page.data.length >= page.total) break;\n offset += page.data.length;\n }\n }\n}\n","import type { HttpClient } from '../http-client.js';\nimport type {\n GenerateGovernanceParams,\n GenerateGovernanceResult,\n DetectContradictionsParams,\n DetectContradictionsResult,\n RequestOptions,\n WithLastResponse,\n} from '../types.js';\n\nexport class Governance {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Generate a sealed .nomos governance artifact from policy documents\n * and optional historical decision logs.\n *\n * @example\n * const artifact = await nomos.governance.generate({\n * policies: [policyText],\n * decision_logs: historicalRows,\n * domain: 'loan_approval',\n * });\n * console.log(artifact.ari_score, artifact.seal_hash);\n */\n async generate(\n params: GenerateGovernanceParams,\n opts?: RequestOptions,\n ): Promise<WithLastResponse<GenerateGovernanceResult>> {\n const { data, lastResponse } = await this.http.post<GenerateGovernanceResult>(\n '/api/v1/generate-governance',\n params,\n opts,\n );\n return { ...data, lastResponse };\n }\n\n /**\n * Detect contradictions and conflicts in a rule set before sealing.\n *\n * @example\n * const report = await nomos.governance.detectContradictions({ rules });\n * if (!report.clean) {\n * console.log(report.contradictions);\n * }\n */\n async detectContradictions(\n params: DetectContradictionsParams,\n opts?: RequestOptions,\n ): Promise<WithLastResponse<DetectContradictionsResult>> {\n const { data, lastResponse } = await this.http.post<DetectContradictionsResult>(\n '/api/v1/detect-contradictions',\n params,\n opts,\n );\n return { ...data, lastResponse };\n }\n}\n","import { NomosWebhookSignatureError } from '../errors.js';\nimport type { NomosWebhookEvent } from '../types.js';\n\n// Hex string → Uint8Array (no Buffer dependency — works in Node and browsers)\nfunction hexToBytes(hex: string): Uint8Array {\n if (hex.length % 2 !== 0) throw new NomosWebhookSignatureError('Invalid hex encoding in signature');\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n const byte = parseInt(hex.slice(i, i + 2), 16);\n if (isNaN(byte)) throw new NomosWebhookSignatureError('Invalid hex encoding in signature');\n bytes[i / 2] = byte;\n }\n return bytes;\n}\n\n// Constant-time comparison (prevents timing attacks)\nfunction safeEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];\n return diff === 0;\n}\n\nexport class Webhooks {\n /**\n * Verify a NOMOS webhook signature and return the parsed event.\n *\n * Signature header format: `t=<unix_ts>,v1=<hmac_sha256_hex>`\n * Signed payload: `<timestamp>.<raw_body>`\n *\n * @example\n * // Express\n * app.post('/webhooks/nomos', express.raw({ type: 'application/json' }), async (req, res) => {\n * const event = await nomos.webhooks.constructEvent(\n * req.body,\n * req.headers['nomos-signature'] as string,\n * process.env.NOMOS_WEBHOOK_SECRET!,\n * );\n * console.log(event.type, event.data);\n * res.sendStatus(200);\n * });\n *\n * @throws {NomosWebhookSignatureError} if signature is invalid, expired, or malformed\n */\n async constructEvent(\n payload: string | Uint8Array,\n signature: string,\n secret: string,\n toleranceSeconds = 300,\n ): Promise<NomosWebhookEvent> {\n const body = typeof payload === 'string'\n ? payload\n : new TextDecoder().decode(payload);\n\n // Parse \"t=<ts>,v1=<hex>\" header\n const parts: Record<string, string> = {};\n for (const part of signature.split(',')) {\n const eq = part.indexOf('=');\n if (eq > -1) parts[part.slice(0, eq).trim()] = part.slice(eq + 1).trim();\n }\n\n if (!parts['t'] || !parts['v1']) {\n throw new NomosWebhookSignatureError(\n 'Invalid signature format — expected \"t=<timestamp>,v1=<hmac>\"',\n );\n }\n\n const timestamp = parseInt(parts['t'], 10);\n if (isNaN(timestamp)) {\n throw new NomosWebhookSignatureError('Invalid timestamp in webhook signature');\n }\n\n const ageSecs = Math.abs(Date.now() / 1000 - timestamp);\n if (toleranceSeconds > 0 && ageSecs > toleranceSeconds) {\n throw new NomosWebhookSignatureError(\n `Webhook timestamp too old (${Math.round(ageSecs)}s > ${toleranceSeconds}s tolerance). ` +\n 'Ensure your server clock is synced and the event is not being replayed.',\n );\n }\n\n // HMAC-SHA256 via Web Crypto API (Node 18+ / modern browsers — no dependencies)\n const enc = new TextEncoder();\n const keyMaterial = await globalThis.crypto.subtle.importKey(\n 'raw',\n enc.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n );\n const signedPayload = `${parts['t']}.${body}`;\n const expectedBuf = await globalThis.crypto.subtle.sign(\n 'HMAC',\n keyMaterial,\n enc.encode(signedPayload),\n );\n const expected = new Uint8Array(expectedBuf);\n const received = hexToBytes(parts['v1']);\n\n if (!safeEqual(expected, received)) {\n throw new NomosWebhookSignatureError(\n 'Webhook signature mismatch — verify your NOMOS_WEBHOOK_SECRET matches the one in Studio.',\n );\n }\n\n try {\n return JSON.parse(body) as NomosWebhookEvent;\n } catch {\n throw new NomosWebhookSignatureError('Webhook payload is not valid JSON');\n }\n }\n\n /**\n * Verify a webhook signature without parsing the event.\n * Returns `true` if valid, `false` if not (never throws).\n *\n * @example\n * const valid = await nomos.webhooks.verifySignature(rawBody, sig, secret);\n * if (!valid) return res.sendStatus(400);\n */\n async verifySignature(\n payload: string | Uint8Array,\n signature: string,\n secret: string,\n toleranceSeconds = 300,\n ): Promise<boolean> {\n try {\n await this.constructEvent(payload, signature, secret, toleranceSeconds);\n return true;\n } catch {\n return false;\n }\n }\n}\n","import { HttpClient } from './http-client.js';\nimport { Decisions } from './resources/decisions.js';\nimport { Artifacts } from './resources/artifacts.js';\nimport { Governance } from './resources/governance.js';\nimport { Webhooks } from './resources/webhooks.js';\nimport * as errors from './errors.js';\nimport type { NomosConfig } from './types.js';\n\nconst DEFAULT_BASE_URL = 'https://nomos.ai';\nconst DEFAULT_MAX_RETRIES = 3;\nconst DEFAULT_TIMEOUT = 30_000;\n\nexport class Nomos {\n readonly decisions: Decisions;\n readonly artifacts: Artifacts;\n readonly governance: Governance;\n readonly webhooks: Webhooks;\n\n /** Whether this instance is using a live or test API key. */\n readonly mode: 'live' | 'test';\n\n static readonly errors = errors;\n\n constructor(apiKey: string, config: NomosConfig = {}) {\n if (!apiKey || typeof apiKey !== 'string') {\n throw new errors.NomosAuthenticationError(\n 'A valid API key is required. Pass it as the first argument: new Nomos(\"nms_live_...\")',\n );\n }\n\n this.mode = apiKey.startsWith('nms_test_') ? 'test' : 'live';\n\n const http = new HttpClient({\n apiKey,\n baseUrl: (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, ''),\n maxRetries: config.maxRetries ?? DEFAULT_MAX_RETRIES,\n timeout: config.timeout ?? DEFAULT_TIMEOUT,\n });\n\n this.decisions = new Decisions(http);\n this.artifacts = new Artifacts(http);\n this.governance = new Governance(http);\n this.webhooks = new Webhooks();\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/util.ts","../src/http-client.ts","../src/resources/decisions.ts","../src/resources/artifacts.ts","../src/resources/governance.ts","../src/resources/webhooks.ts","../src/nomos.ts","../src/can.ts"],"sourcesContent":["export { Nomos } from './nomos.js';\n// The keyless public Exchange primitive — `import { nomos } from '@nomosprotocol/sdk'`\n// then `await nomos.can({ authority, ...facts })`. Separate from the authenticated Nomos\n// class; needs no API key and answers only public Exchange artifacts.\nexport { can, nomos } from './can.js';\nexport * from './errors.js';\nexport type {\n CanParams,\n CanOptions,\n CanResult,\n CanVerdict,\n NomosConfig,\n RequestOptions,\n NomosRawResponse,\n WithLastResponse,\n VerifyDecisionParams,\n VerifyDecisionResult,\n ListArtifactsParams,\n ArtifactList,\n Artifact,\n ArtifactSchema,\n ArtifactSchemaField,\n GenerateGovernanceParams,\n GenerateGovernanceResult,\n DetectContradictionsParams,\n DetectContradictionsResult,\n Contradiction,\n Verdict,\n NomosWebhookEvent,\n NomosWebhookEventType,\n} from './types.js';\n","export type NomosErrorCode =\n | 'authentication_error'\n | 'authorization_error'\n | 'rate_limit_error'\n | 'validation_error'\n | 'not_found'\n | 'api_error'\n | 'network_error'\n | 'webhook_signature_error';\n\nexport class NomosError extends Error {\n readonly code: NomosErrorCode;\n readonly status?: number;\n readonly requestId?: string;\n\n constructor(message: string, code: NomosErrorCode, status?: number, requestId?: string) {\n super(message);\n this.name = 'NomosError';\n this.code = code;\n this.status = status;\n this.requestId = requestId;\n }\n}\n\nexport class NomosAuthenticationError extends NomosError {\n constructor(message = 'Invalid API key', requestId?: string) {\n super(message, 'authentication_error', 401, requestId);\n this.name = 'NomosAuthenticationError';\n }\n}\n\nexport class NomosAuthorizationError extends NomosError {\n constructor(message = 'Access denied', requestId?: string) {\n super(message, 'authorization_error', 403, requestId);\n this.name = 'NomosAuthorizationError';\n }\n}\n\nexport class NomosRateLimitError extends NomosError {\n readonly retryAfter?: number;\n\n constructor(message = 'Rate limit exceeded', retryAfter?: number, requestId?: string) {\n super(message, 'rate_limit_error', 429, requestId);\n this.name = 'NomosRateLimitError';\n this.retryAfter = retryAfter;\n }\n}\n\nexport class NomosValidationError extends NomosError {\n readonly details?: unknown;\n\n constructor(message: string, details?: unknown, requestId?: string) {\n super(message, 'validation_error', 400, requestId);\n this.name = 'NomosValidationError';\n this.details = details;\n }\n}\n\nexport class NomosNotFoundError extends NomosError {\n constructor(message: string, requestId?: string) {\n super(message, 'not_found', 404, requestId);\n this.name = 'NomosNotFoundError';\n }\n}\n\nexport class NomosAPIError extends NomosError {\n constructor(message: string, status: number, requestId?: string) {\n super(message, 'api_error', status, requestId);\n this.name = 'NomosAPIError';\n }\n}\n\nexport class NomosNetworkError extends NomosError {\n constructor(message: string) {\n super(message, 'network_error');\n this.name = 'NomosNetworkError';\n }\n}\n\nexport class NomosWebhookSignatureError extends NomosError {\n constructor(message: string) {\n super(message, 'webhook_signature_error', 400);\n this.name = 'NomosWebhookSignatureError';\n }\n}\n","export async function sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nexport function jitteredBackoff(attempt: number, baseMs = 500): number {\n const exp = Math.min(baseMs * 2 ** attempt, 16000);\n return exp * (0.75 + Math.random() * 0.5); // ±25% jitter\n}\n\nexport function isRetryable(status: number): boolean {\n return status === 429 || status >= 500;\n}\n","import {\n NomosAuthenticationError,\n NomosAuthorizationError,\n NomosRateLimitError,\n NomosValidationError,\n NomosNotFoundError,\n NomosAPIError,\n NomosNetworkError,\n} from './errors.js';\nimport { sleep, jitteredBackoff, isRetryable } from './util.js';\nimport type { RequestOptions, NomosRawResponse } from './types.js';\n\nconst SDK_VERSION = '1.1.0';\n\nexport interface HttpClientOptions {\n apiKey: string;\n baseUrl: string;\n maxRetries: number;\n timeout: number;\n}\n\nexport interface HttpResponse<T> {\n data: T;\n lastResponse: NomosRawResponse;\n}\n\nexport class HttpClient {\n constructor(private readonly opts: HttpClientOptions) {}\n\n async get<T>(path: string, reqOpts?: RequestOptions): Promise<HttpResponse<T>> {\n return this.request<T>('GET', path, undefined, reqOpts);\n }\n\n async post<T>(path: string, body: unknown, reqOpts?: RequestOptions): Promise<HttpResponse<T>> {\n return this.request<T>('POST', path, body, reqOpts);\n }\n\n private async request<T>(\n method: string,\n path: string,\n body: unknown,\n reqOpts?: RequestOptions,\n attempt = 0,\n ): Promise<HttpResponse<T>> {\n const apiKey = reqOpts?.apiKey ?? this.opts.apiKey;\n const timeout = reqOpts?.timeout ?? this.opts.timeout;\n const maxRetries = reqOpts?.maxRetries ?? this.opts.maxRetries;\n\n const url = `${this.opts.baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeout);\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-Nomos-Api-Key': apiKey,\n 'User-Agent': `nomos-node/${SDK_VERSION}`,\n 'NOMOS-SDK-Version': SDK_VERSION,\n };\n if (reqOpts?.idempotencyKey) {\n headers['Idempotency-Key'] = reqOpts.idempotencyKey;\n }\n\n let res: Response;\n try {\n res = await fetch(url, {\n method,\n signal: controller.signal,\n headers,\n body: body != null ? JSON.stringify(body) : undefined,\n });\n } catch (err: any) {\n clearTimeout(timer);\n if (err.name === 'AbortError') {\n throw new NomosNetworkError(`Request timed out after ${timeout}ms`);\n }\n throw new NomosNetworkError(err.message ?? 'Network error');\n } finally {\n clearTimeout(timer);\n }\n\n const requestId = res.headers.get('x-request-id') ?? '';\n const rawHeaders: Record<string, string> = {};\n res.headers.forEach((value, key) => { rawHeaders[key] = value; });\n const lastResponse: NomosRawResponse = {\n requestId,\n statusCode: res.status,\n headers: rawHeaders,\n };\n\n if (res.ok) {\n const data = await res.json() as T;\n return { data, lastResponse };\n }\n\n // Retry on 429 / 5xx\n if (isRetryable(res.status) && attempt < maxRetries) {\n const retryAfter = res.headers.get('retry-after');\n const delay = retryAfter ? parseInt(retryAfter, 10) * 1000 : jitteredBackoff(attempt);\n await sleep(delay);\n return this.request<T>(method, path, body, reqOpts, attempt + 1);\n }\n\n let errBody: any = {};\n try { errBody = await res.json(); } catch {}\n const message: string = errBody?.error ?? errBody?.message ?? res.statusText;\n\n switch (res.status) {\n case 401: throw new NomosAuthenticationError(message, requestId);\n case 403: throw new NomosAuthorizationError(message, requestId);\n case 404: throw new NomosNotFoundError(message, requestId);\n case 422:\n case 400: throw new NomosValidationError(message, errBody?.details, requestId);\n case 429: throw new NomosRateLimitError(\n message,\n res.headers.get('retry-after') ? parseInt(res.headers.get('retry-after')!, 10) : undefined,\n requestId,\n );\n default: throw new NomosAPIError(message, res.status, requestId);\n }\n }\n}\n","import type { HttpClient } from '../http-client.js';\nimport type {\n VerifyDecisionParams,\n VerifyDecisionResult,\n RequestOptions,\n WithLastResponse,\n} from '../types.js';\n\nexport class Decisions {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Verify whether an AI decision is permitted under a governance artifact.\n *\n * Public demo artifacts (`pub_*`) work without an API key.\n * Custom artifacts require a valid API key.\n *\n * @example\n * const result = await nomos.decisions.verify({\n * artifact_id: 'pub_lending_v1',\n * decision_context: { credit_score: 720, loan_amount: 50000 },\n * });\n *\n * if (!result.allowed) {\n * throw new Error(`Blocked: ${result.verdict_description}`);\n * }\n *\n * // Debugging / tracing\n * console.log(result.lastResponse.requestId);\n *\n * @example\n * // Per-request options\n * const result = await nomos.decisions.verify(params, {\n * idempotencyKey: `verify-${transactionId}`,\n * timeout: 5000,\n * });\n */\n async verify(\n params: VerifyDecisionParams,\n opts?: RequestOptions,\n ): Promise<WithLastResponse<VerifyDecisionResult>> {\n const { artifact_id, decision_context, proposed_decision, correlation_id } = params;\n\n // Public artifacts (pub_*) use the open /verify endpoint — no API key required\n const isPublic = artifact_id.startsWith('pub_');\n let httpResp: Awaited<ReturnType<HttpClient['post']>>;\n\n if (isPublic) {\n httpResp = await this.http.post<any>('/api/v1/verify', {\n artifact_id,\n decision: proposed_decision ?? 'evaluate',\n inputs: decision_context,\n }, opts);\n } else {\n // /verify-decision expects: { artifact_id, decision, inputs, caller? }\n // NOT decision_context / proposed_decision at the top level.\n httpResp = await this.http.post<any>('/api/v1/verify-decision', {\n artifact_id,\n decision: proposed_decision ?? 'evaluate',\n inputs: decision_context,\n caller: { correlation_id: correlation_id ?? globalThis.crypto.randomUUID() },\n }, opts);\n }\n\n const raw: any = httpResp.data;\n\n return {\n id: raw.id ?? `req_${raw.execution_id ?? globalThis.crypto.randomUUID()}`,\n object: raw.object ?? 'decision',\n artifact_id: raw.artifact_id ?? artifact_id,\n artifact_name: raw.artifact_name ?? '',\n allowed: raw.allowed ?? false,\n verdict: raw.verdict ?? (raw.outcome === 'auto_approved' ? 'approved' : raw.outcome === 'auto_rejected' ? 'rejected' : 'escalated'),\n rule: raw.rule,\n evaluation: raw.evaluation ?? { rules_evaluated: raw.rules_evaluated ?? 0, rules_matched: 0, rules_expired: 0, conflicts_resolved: 0 },\n confidence: raw.confidence ?? { tier: raw.artifact_confidence ?? 'DECLARED', score: 1, description: '' },\n audit: raw.audit ?? { hash: raw.audit_hash ?? raw.audit_record ?? '', timestamp: raw.ts ?? new Date().toISOString() },\n performance: raw.performance ?? { latency_ms: raw.latency_ms ?? 0 },\n schema_version: raw.schema_version ?? '1.0.0',\n verdict_description: raw.verdict_description ?? '',\n incomplete_inputs: raw.incomplete_inputs,\n paths_to_approval: raw.paths_to_approval,\n lastResponse: httpResp.lastResponse,\n };\n }\n}\n","import type { HttpClient } from '../http-client.js';\nimport type {\n Artifact,\n ArtifactList,\n ArtifactSchema,\n ListArtifactsParams,\n RequestOptions,\n WithLastResponse,\n} from '../types.js';\n\nexport class Artifacts {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Retrieve a single artifact by ID.\n *\n * @example\n * const artifact = await nomos.artifacts.retrieve('loan_approval_v1');\n * console.log(artifact.ari_score, artifact.autonomy_band);\n * console.log(artifact.lastResponse.requestId); // for support tickets\n */\n async retrieve(\n artifactId: string,\n opts?: RequestOptions,\n ): Promise<WithLastResponse<Artifact>> {\n const { data, lastResponse } = await this.http.get<Artifact>(\n `/api/exchange/artifacts/${encodeURIComponent(artifactId)}`,\n opts,\n );\n return { ...data, lastResponse };\n }\n\n /**\n * List published artifacts on the Exchange with optional filters.\n *\n * @example\n * const { data, total } = await nomos.artifacts.list({ band: 'autonomous', limit: 10 });\n *\n * @example\n * // With per-request options\n * const page = await nomos.artifacts.list({ limit: 20 }, { timeout: 5000 });\n */\n async list(\n params: ListArtifactsParams = {},\n opts?: RequestOptions,\n ): Promise<WithLastResponse<ArtifactList>> {\n const qs = new URLSearchParams();\n if (params.band) qs.set('band', params.band);\n if (params.domain) qs.set('domain', params.domain);\n if (params.jurisdiction) qs.set('jurisdiction', params.jurisdiction);\n if (params.sort) qs.set('sort', params.sort);\n if (params.limit != null) qs.set('limit', String(params.limit));\n if (params.offset != null) qs.set('offset', String(params.offset));\n const query = qs.toString();\n\n const { data: raw, lastResponse } = await this.http.get<any>(\n `/api/exchange/artifacts${query ? `?${query}` : ''}`,\n opts,\n );\n\n // API returns { artifacts: [], total: N } — normalise to { data: [], total: N }\n const normalized: ArtifactList = {\n data: Array.isArray(raw) ? raw : (raw.artifacts ?? raw.data ?? []),\n total: raw.total ?? (Array.isArray(raw) ? raw.length : 0),\n limit: params.limit ?? 20,\n offset: params.offset ?? 0,\n };\n\n return { ...normalized, lastResponse };\n }\n\n /**\n * Auto-paginating iterator — yields every artifact across all pages.\n * Stops automatically when the last page is reached.\n *\n * @example\n * for await (const artifact of nomos.artifacts.listAutoPaging({ band: 'autonomous' })) {\n * console.log(artifact.title, artifact.ari_score);\n * }\n */\n async *listAutoPaging(\n params: ListArtifactsParams = {},\n opts?: RequestOptions,\n ): AsyncGenerator<Artifact> {\n let offset = params.offset ?? 0;\n const limit = params.limit ?? 20;\n\n while (true) {\n const page = await this.list({ ...params, offset, limit }, opts);\n for (const item of page.data) yield item;\n if (page.data.length < limit || offset + page.data.length >= page.total) break;\n offset += page.data.length;\n }\n }\n\n /**\n * Retrieve the declared input schema for a sealed artifact.\n *\n * Returns every field the artifact's rules reference — name, type, whether it's\n * required, and a ready-to-use example_inputs object. Use this to build forms,\n * validate payloads, or generate API docs without reading the rules manually.\n *\n * Requires an API key (artifact schemas are not public).\n *\n * @example\n * const schema = await nomos.artifacts.schema('art_abc123');\n * console.log(schema.required_fields); // ['credit_score', 'loan_amount']\n * console.log(schema.example_inputs); // { credit_score: 0, loan_amount: 0 }\n */\n async schema(\n artifactId: string,\n opts?: RequestOptions,\n ): Promise<WithLastResponse<ArtifactSchema>> {\n const { data, lastResponse } = await this.http.get<ArtifactSchema>(\n `/api/v1/artifacts/${encodeURIComponent(artifactId)}/schema`,\n opts,\n );\n return { ...data, lastResponse };\n }\n}\n","import type { HttpClient } from '../http-client.js';\nimport type {\n GenerateGovernanceParams,\n GenerateGovernanceResult,\n DetectContradictionsParams,\n DetectContradictionsResult,\n RequestOptions,\n WithLastResponse,\n} from '../types.js';\n\nexport class Governance {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Generate a sealed .nomos governance artifact from policy documents\n * and optional historical decision logs.\n *\n * @example\n * const artifact = await nomos.governance.generate({\n * policies: [policyText],\n * decision_logs: historicalRows,\n * domain: 'loan_approval',\n * });\n * console.log(artifact.ari_score, artifact.seal_hash);\n */\n async generate(\n params: GenerateGovernanceParams,\n opts?: RequestOptions,\n ): Promise<WithLastResponse<GenerateGovernanceResult>> {\n const { data, lastResponse } = await this.http.post<GenerateGovernanceResult>(\n '/api/v1/generate-governance',\n params,\n opts,\n );\n return { ...data, lastResponse };\n }\n\n /**\n * Detect contradictions and conflicts in a rule set before sealing.\n *\n * @example\n * const report = await nomos.governance.detectContradictions({ rules });\n * if (!report.clean) {\n * console.log(report.contradictions);\n * }\n */\n async detectContradictions(\n params: DetectContradictionsParams,\n opts?: RequestOptions,\n ): Promise<WithLastResponse<DetectContradictionsResult>> {\n const { data, lastResponse } = await this.http.post<DetectContradictionsResult>(\n '/api/v1/detect-contradictions',\n params,\n opts,\n );\n return { ...data, lastResponse };\n }\n}\n","import { NomosWebhookSignatureError } from '../errors.js';\nimport type { NomosWebhookEvent } from '../types.js';\n\n// Hex string → Uint8Array (no Buffer dependency — works in Node and browsers)\nfunction hexToBytes(hex: string): Uint8Array {\n if (hex.length % 2 !== 0) throw new NomosWebhookSignatureError('Invalid hex encoding in signature');\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n const byte = parseInt(hex.slice(i, i + 2), 16);\n if (isNaN(byte)) throw new NomosWebhookSignatureError('Invalid hex encoding in signature');\n bytes[i / 2] = byte;\n }\n return bytes;\n}\n\n// Constant-time comparison (prevents timing attacks)\nfunction safeEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];\n return diff === 0;\n}\n\nexport class Webhooks {\n /**\n * Verify a NOMOS webhook signature and return the parsed event.\n *\n * Signature header format: `t=<unix_ts>,v1=<hmac_sha256_hex>`\n * Signed payload: `<timestamp>.<raw_body>`\n *\n * @example\n * // Express\n * app.post('/webhooks/nomos', express.raw({ type: 'application/json' }), async (req, res) => {\n * const event = await nomos.webhooks.constructEvent(\n * req.body,\n * req.headers['nomos-signature'] as string,\n * process.env.NOMOS_WEBHOOK_SECRET!,\n * );\n * console.log(event.type, event.data);\n * res.sendStatus(200);\n * });\n *\n * @throws {NomosWebhookSignatureError} if signature is invalid, expired, or malformed\n */\n async constructEvent(\n payload: string | Uint8Array,\n signature: string,\n secret: string,\n toleranceSeconds = 300,\n ): Promise<NomosWebhookEvent> {\n const body = typeof payload === 'string'\n ? payload\n : new TextDecoder().decode(payload);\n\n // Parse \"t=<ts>,v1=<hex>\" header\n const parts: Record<string, string> = {};\n for (const part of signature.split(',')) {\n const eq = part.indexOf('=');\n if (eq > -1) parts[part.slice(0, eq).trim()] = part.slice(eq + 1).trim();\n }\n\n if (!parts['t'] || !parts['v1']) {\n throw new NomosWebhookSignatureError(\n 'Invalid signature format — expected \"t=<timestamp>,v1=<hmac>\"',\n );\n }\n\n const timestamp = parseInt(parts['t'], 10);\n if (isNaN(timestamp)) {\n throw new NomosWebhookSignatureError('Invalid timestamp in webhook signature');\n }\n\n const ageSecs = Math.abs(Date.now() / 1000 - timestamp);\n if (toleranceSeconds > 0 && ageSecs > toleranceSeconds) {\n throw new NomosWebhookSignatureError(\n `Webhook timestamp too old (${Math.round(ageSecs)}s > ${toleranceSeconds}s tolerance). ` +\n 'Ensure your server clock is synced and the event is not being replayed.',\n );\n }\n\n // HMAC-SHA256 via Web Crypto API (Node 18+ / modern browsers — no dependencies)\n const enc = new TextEncoder();\n const keyMaterial = await globalThis.crypto.subtle.importKey(\n 'raw',\n enc.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n );\n const signedPayload = `${parts['t']}.${body}`;\n const expectedBuf = await globalThis.crypto.subtle.sign(\n 'HMAC',\n keyMaterial,\n enc.encode(signedPayload),\n );\n const expected = new Uint8Array(expectedBuf);\n const received = hexToBytes(parts['v1']);\n\n if (!safeEqual(expected, received)) {\n throw new NomosWebhookSignatureError(\n 'Webhook signature mismatch — verify your NOMOS_WEBHOOK_SECRET matches the one in Studio.',\n );\n }\n\n try {\n return JSON.parse(body) as NomosWebhookEvent;\n } catch {\n throw new NomosWebhookSignatureError('Webhook payload is not valid JSON');\n }\n }\n\n /**\n * Verify a webhook signature without parsing the event.\n * Returns `true` if valid, `false` if not (never throws).\n *\n * @example\n * const valid = await nomos.webhooks.verifySignature(rawBody, sig, secret);\n * if (!valid) return res.sendStatus(400);\n */\n async verifySignature(\n payload: string | Uint8Array,\n signature: string,\n secret: string,\n toleranceSeconds = 300,\n ): Promise<boolean> {\n try {\n await this.constructEvent(payload, signature, secret, toleranceSeconds);\n return true;\n } catch {\n return false;\n }\n }\n}\n","import { HttpClient } from './http-client.js';\nimport { Decisions } from './resources/decisions.js';\nimport { Artifacts } from './resources/artifacts.js';\nimport { Governance } from './resources/governance.js';\nimport { Webhooks } from './resources/webhooks.js';\nimport * as errors from './errors.js';\nimport type { NomosConfig } from './types.js';\n\nconst DEFAULT_BASE_URL = 'https://nomos.ai';\nconst DEFAULT_MAX_RETRIES = 3;\nconst DEFAULT_TIMEOUT = 30_000;\n\nexport class Nomos {\n readonly decisions: Decisions;\n readonly artifacts: Artifacts;\n readonly governance: Governance;\n readonly webhooks: Webhooks;\n\n /** Whether this instance is using a live or test API key. */\n readonly mode: 'live' | 'test';\n\n static readonly errors = errors;\n\n constructor(apiKey: string, config: NomosConfig = {}) {\n if (!apiKey || typeof apiKey !== 'string') {\n throw new errors.NomosAuthenticationError(\n 'A valid API key is required. Pass it as the first argument: new Nomos(\"nms_live_...\")',\n );\n }\n\n this.mode = apiKey.startsWith('nms_test_') ? 'test' : 'live';\n\n const http = new HttpClient({\n apiKey,\n baseUrl: (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, ''),\n maxRetries: config.maxRetries ?? DEFAULT_MAX_RETRIES,\n timeout: config.timeout ?? DEFAULT_TIMEOUT,\n });\n\n this.decisions = new Decisions(http);\n this.artifacts = new Artifacts(http);\n this.governance = new Governance(http);\n this.webhooks = new Webhooks();\n }\n}\n","import type { CanParams, CanResult, CanOptions } from './types.js';\nimport {\n NomosAuthenticationError,\n NomosAuthorizationError,\n NomosRateLimitError,\n NomosValidationError,\n NomosNotFoundError,\n NomosAPIError,\n NomosNetworkError,\n} from './errors.js';\n\n/**\n * The whole product in one verb: \"Can I do this?\"\n *\n * Ask a public Exchange authority a question and get back a deterministic, verifiable\n * verdict — no API key, no SDK setup, no reading a policy PDF. This is a thin, faithful\n * wrapper over the public Exchange query endpoint (the same call the exchange.nomosprotocol.com\n * \"Ask Authority\" box makes), so every answer is a real, addressable transcript you can open\n * at its `url` / `query_id`.\n *\n * Verdicts are exactly what the authority returns — AUTHORIZED / DENIED / ESCALATED — never\n * an invented shape. `allowed` is simply `verdict === 'AUTHORIZED'`; an ESCALATED result means\n * the authority needs more facts to decide (see `missing_inputs`), not a flat \"no\".\n *\n * @example\n * import { nomos } from '@nomosprotocol/sdk';\n *\n * const verdict = await nomos.can({\n * authority: 'eu-ai-act.nomos',\n * ai_system_circumvents_refugee_convention: true,\n * });\n * // → { allowed: false, verdict: 'DENIED', reason: 'Rule \"Prohibition…\" triggered…',\n * // query_id: 'qry_…', url: '/queries/qry_…', … }\n */\nconst DEFAULT_EXCHANGE_BASE = 'https://www.nomosprotocol.com';\n\nexport async function can(params: CanParams, opts?: CanOptions): Promise<CanResult> {\n const { authority, action, inputs, ...flat } = params;\n if (!authority || typeof authority !== 'string') {\n throw new Error('can(): `authority` (an Exchange artifact id or slug) is required.');\n }\n // Two equally valid shapes: an explicit `inputs` object, or the facts spread flat\n // alongside `authority`/`action`. Explicit `inputs` wins when both are present.\n const facts: Record<string, unknown> =\n inputs && typeof inputs === 'object' ? inputs : (flat as Record<string, unknown>);\n\n const base = (opts?.baseUrl ?? DEFAULT_EXCHANGE_BASE).replace(/\\/$/, '');\n const url = `${base}/api/exchange/artifacts/${encodeURIComponent(authority)}/query`;\n\n let res: Response;\n try {\n res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ inputs: facts, action }),\n signal: opts?.signal,\n });\n } catch (err: any) {\n if (err?.name === 'AbortError') throw new NomosNetworkError('Request aborted');\n throw new NomosNetworkError(err?.message ?? 'Network error');\n }\n\n const requestId = res.headers.get('x-request-id') ?? '';\n const data: any = await res.json().catch(() => null);\n if (!res.ok) {\n // Same status-code -> error-class mapping HttpClient uses for every other SDK call,\n // so `instanceof NomosNotFoundError` etc. works consistently everywhere — can() used to\n // throw a plain Error here, bypassing the SDK's own error hierarchy entirely.\n const message: string = data?.error ?? data?.message ?? `NOMOS query failed (HTTP ${res.status})`;\n switch (res.status) {\n case 401: throw new NomosAuthenticationError(message, requestId);\n case 403: throw new NomosAuthorizationError(message, requestId);\n case 404: throw new NomosNotFoundError(message, requestId);\n case 422:\n case 400: throw new NomosValidationError(message, data?.details, requestId);\n case 429: throw new NomosRateLimitError(\n message,\n res.headers.get('retry-after') ? parseInt(res.headers.get('retry-after')!, 10) : undefined,\n requestId,\n );\n default: throw new NomosAPIError(message, res.status, requestId);\n }\n }\n\n return {\n allowed: data.verdict === 'AUTHORIZED',\n verdict: data.verdict,\n reason: data.verdict_description,\n rule: data.matched_rule_id ?? null,\n query_id: data.query_id,\n url: data.url,\n authority: {\n id: data.artifact?.id ?? authority,\n title: data.artifact?.title ?? '',\n standing: data.artifact?.standing ?? '',\n },\n missing_inputs: data.missing_inputs ?? [],\n };\n}\n\n/**\n * Ready-to-use, keyless entry point matching the canonical `nomos.can(...)` form.\n * For authenticated, key-scoped operations use the `Nomos` class instead.\n */\nexport const nomos = { can };\n"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -41,24 +41,111 @@ interface DetectContradictionsParams {
|
|
|
41
41
|
priority?: number;
|
|
42
42
|
}>;
|
|
43
43
|
}
|
|
44
|
-
type Verdict = '
|
|
44
|
+
type Verdict = 'approved' | 'rejected' | 'escalated';
|
|
45
|
+
type CanVerdict = 'AUTHORIZED' | 'DENIED' | 'ESCALATED';
|
|
46
|
+
interface CanParams {
|
|
47
|
+
/** Exchange artifact's standard name — slug (optionally ".nomos"-suffixed) or raw id, e.g. "eu-ai-act.nomos" */
|
|
48
|
+
authority: string;
|
|
49
|
+
/** Optional human-readable label for what's being asked (recorded in the transcript) */
|
|
50
|
+
action?: string;
|
|
51
|
+
/** The facts to evaluate. Either pass this explicitly, or spread the facts flat alongside
|
|
52
|
+
* `authority`/`action` — both shapes are accepted (explicit `inputs` wins if both given). */
|
|
53
|
+
inputs?: Record<string, unknown>;
|
|
54
|
+
/** Flat-facts convenience: any extra keys are treated as inputs when `inputs` is omitted. */
|
|
55
|
+
[key: string]: unknown;
|
|
56
|
+
}
|
|
57
|
+
interface CanOptions {
|
|
58
|
+
/** Override the API host (defaults to the public NOMOS Exchange). */
|
|
59
|
+
baseUrl?: string;
|
|
60
|
+
/** AbortSignal to cancel the request. */
|
|
61
|
+
signal?: AbortSignal;
|
|
62
|
+
}
|
|
63
|
+
interface CanResult {
|
|
64
|
+
/** True only for an AUTHORIZED verdict. DENIED and ESCALATED are both `false`. */
|
|
65
|
+
allowed: boolean;
|
|
66
|
+
/** The authority's own verdict, verbatim. */
|
|
67
|
+
verdict: CanVerdict;
|
|
68
|
+
/** Human-readable explanation of the verdict. */
|
|
69
|
+
reason: string;
|
|
70
|
+
/** The rule id that decided it, if any. */
|
|
71
|
+
rule: string | null;
|
|
72
|
+
/** Permanent, addressable transcript id — open it any time. */
|
|
73
|
+
query_id: string;
|
|
74
|
+
/** Relative URL of the transcript. */
|
|
75
|
+
url: string;
|
|
76
|
+
/** Which authority answered, and its standing. */
|
|
77
|
+
authority: {
|
|
78
|
+
id: string;
|
|
79
|
+
title: string;
|
|
80
|
+
standing: string;
|
|
81
|
+
};
|
|
82
|
+
/** On ESCALATED: the facts the authority still needs to reach a verdict. */
|
|
83
|
+
missing_inputs: string[];
|
|
84
|
+
}
|
|
45
85
|
interface VerifyDecisionResult {
|
|
86
|
+
/** Unique request ID — include in support tickets */
|
|
87
|
+
id: string;
|
|
88
|
+
/** Always "decision" */
|
|
89
|
+
object: 'decision';
|
|
90
|
+
/** The artifact that governed this decision */
|
|
91
|
+
artifact_id: string;
|
|
92
|
+
/** Artifact name */
|
|
93
|
+
artifact_name: string;
|
|
46
94
|
/** Whether the decision is permitted under current governance */
|
|
47
95
|
allowed: boolean;
|
|
48
|
-
/**
|
|
96
|
+
/** Human-readable verdict */
|
|
49
97
|
verdict: Verdict;
|
|
98
|
+
/** The rule that triggered this verdict, if any */
|
|
99
|
+
rule?: {
|
|
100
|
+
id: string;
|
|
101
|
+
description: string | null;
|
|
102
|
+
action: 'allow' | 'deny' | 'escalate';
|
|
103
|
+
};
|
|
104
|
+
/** Evaluation metrics */
|
|
105
|
+
evaluation: {
|
|
106
|
+
rules_evaluated: number;
|
|
107
|
+
rules_matched: number;
|
|
108
|
+
rules_expired: number;
|
|
109
|
+
conflicts_resolved: number;
|
|
110
|
+
};
|
|
111
|
+
/** Confidence in the verdict */
|
|
112
|
+
confidence: {
|
|
113
|
+
/** Artifact verification tier */
|
|
114
|
+
tier: string;
|
|
115
|
+
/** 0–1 confidence score */
|
|
116
|
+
score: number;
|
|
117
|
+
/** Human-readable explanation of the tier */
|
|
118
|
+
description: string;
|
|
119
|
+
};
|
|
120
|
+
/** Audit record — store the hash for compliance */
|
|
121
|
+
audit: {
|
|
122
|
+
hash: string;
|
|
123
|
+
timestamp: string;
|
|
124
|
+
};
|
|
125
|
+
/** Performance metrics */
|
|
126
|
+
performance: {
|
|
127
|
+
latency_ms: number;
|
|
128
|
+
};
|
|
129
|
+
/** API schema version */
|
|
130
|
+
schema_version: string;
|
|
50
131
|
/** Human-readable explanation */
|
|
51
132
|
verdict_description: string;
|
|
52
|
-
/**
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
133
|
+
/** Missing input fields, if any rule-referenced fields were absent */
|
|
134
|
+
incomplete_inputs?: {
|
|
135
|
+
fields: string[];
|
|
136
|
+
count: number;
|
|
137
|
+
warning: string;
|
|
138
|
+
};
|
|
139
|
+
/** How to satisfy an approval rule when current verdict is not approved */
|
|
140
|
+
paths_to_approval?: Array<{
|
|
141
|
+
rule_id: string | null;
|
|
142
|
+
rule_name: string | null;
|
|
143
|
+
required_changes: Array<{
|
|
144
|
+
field: string;
|
|
145
|
+
current: unknown;
|
|
146
|
+
must_satisfy: string;
|
|
147
|
+
}>;
|
|
148
|
+
}>;
|
|
62
149
|
}
|
|
63
150
|
interface Artifact {
|
|
64
151
|
id: string;
|
|
@@ -85,6 +172,24 @@ interface ArtifactList {
|
|
|
85
172
|
limit: number;
|
|
86
173
|
offset: number;
|
|
87
174
|
}
|
|
175
|
+
interface ArtifactSchemaField {
|
|
176
|
+
name: string;
|
|
177
|
+
type: 'string' | 'number' | 'integer' | 'boolean' | 'date' | 'datetime' | 'enum' | 'array';
|
|
178
|
+
required: boolean;
|
|
179
|
+
description?: string;
|
|
180
|
+
enum?: string[];
|
|
181
|
+
min?: number;
|
|
182
|
+
max?: number;
|
|
183
|
+
format?: string;
|
|
184
|
+
}
|
|
185
|
+
interface ArtifactSchema {
|
|
186
|
+
artifact_id: string;
|
|
187
|
+
name: string;
|
|
188
|
+
fields: ArtifactSchemaField[];
|
|
189
|
+
required_fields: string[];
|
|
190
|
+
example_inputs: Record<string, unknown>;
|
|
191
|
+
field_count: number;
|
|
192
|
+
}
|
|
88
193
|
interface Contradiction {
|
|
89
194
|
type: 'threshold_conflict' | 'role_conflict' | 'ghost_term' | 'rule_collision' | 'layer_divergence';
|
|
90
195
|
severity: 'critical' | 'warning' | 'info';
|
|
@@ -226,6 +331,21 @@ declare class Artifacts {
|
|
|
226
331
|
* }
|
|
227
332
|
*/
|
|
228
333
|
listAutoPaging(params?: ListArtifactsParams, opts?: RequestOptions): AsyncGenerator<Artifact>;
|
|
334
|
+
/**
|
|
335
|
+
* Retrieve the declared input schema for a sealed artifact.
|
|
336
|
+
*
|
|
337
|
+
* Returns every field the artifact's rules reference — name, type, whether it's
|
|
338
|
+
* required, and a ready-to-use example_inputs object. Use this to build forms,
|
|
339
|
+
* validate payloads, or generate API docs without reading the rules manually.
|
|
340
|
+
*
|
|
341
|
+
* Requires an API key (artifact schemas are not public).
|
|
342
|
+
*
|
|
343
|
+
* @example
|
|
344
|
+
* const schema = await nomos.artifacts.schema('art_abc123');
|
|
345
|
+
* console.log(schema.required_fields); // ['credit_score', 'loan_amount']
|
|
346
|
+
* console.log(schema.example_inputs); // { credit_score: 0, loan_amount: 0 }
|
|
347
|
+
*/
|
|
348
|
+
schema(artifactId: string, opts?: RequestOptions): Promise<WithLastResponse<ArtifactSchema>>;
|
|
229
349
|
}
|
|
230
350
|
|
|
231
351
|
declare class Governance {
|
|
@@ -357,4 +477,13 @@ declare class Nomos {
|
|
|
357
477
|
constructor(apiKey: string, config?: NomosConfig);
|
|
358
478
|
}
|
|
359
479
|
|
|
360
|
-
|
|
480
|
+
declare function can(params: CanParams, opts?: CanOptions): Promise<CanResult>;
|
|
481
|
+
/**
|
|
482
|
+
* Ready-to-use, keyless entry point matching the canonical `nomos.can(...)` form.
|
|
483
|
+
* For authenticated, key-scoped operations use the `Nomos` class instead.
|
|
484
|
+
*/
|
|
485
|
+
declare const nomos: {
|
|
486
|
+
can: typeof can;
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
export { type Artifact, type ArtifactList, type ArtifactSchema, type ArtifactSchemaField, type CanOptions, type CanParams, type CanResult, type CanVerdict, type Contradiction, type DetectContradictionsParams, type DetectContradictionsResult, type GenerateGovernanceParams, type GenerateGovernanceResult, type ListArtifactsParams, Nomos, NomosAPIError, NomosAuthenticationError, NomosAuthorizationError, type NomosConfig, NomosError, type NomosErrorCode, NomosNetworkError, NomosNotFoundError, NomosRateLimitError, type NomosRawResponse, NomosValidationError, type NomosWebhookEvent, type NomosWebhookEventType, NomosWebhookSignatureError, type RequestOptions, type Verdict, type VerifyDecisionParams, type VerifyDecisionResult, type WithLastResponse, can, nomos };
|
package/dist/index.d.ts
CHANGED
|
@@ -41,24 +41,111 @@ interface DetectContradictionsParams {
|
|
|
41
41
|
priority?: number;
|
|
42
42
|
}>;
|
|
43
43
|
}
|
|
44
|
-
type Verdict = '
|
|
44
|
+
type Verdict = 'approved' | 'rejected' | 'escalated';
|
|
45
|
+
type CanVerdict = 'AUTHORIZED' | 'DENIED' | 'ESCALATED';
|
|
46
|
+
interface CanParams {
|
|
47
|
+
/** Exchange artifact's standard name — slug (optionally ".nomos"-suffixed) or raw id, e.g. "eu-ai-act.nomos" */
|
|
48
|
+
authority: string;
|
|
49
|
+
/** Optional human-readable label for what's being asked (recorded in the transcript) */
|
|
50
|
+
action?: string;
|
|
51
|
+
/** The facts to evaluate. Either pass this explicitly, or spread the facts flat alongside
|
|
52
|
+
* `authority`/`action` — both shapes are accepted (explicit `inputs` wins if both given). */
|
|
53
|
+
inputs?: Record<string, unknown>;
|
|
54
|
+
/** Flat-facts convenience: any extra keys are treated as inputs when `inputs` is omitted. */
|
|
55
|
+
[key: string]: unknown;
|
|
56
|
+
}
|
|
57
|
+
interface CanOptions {
|
|
58
|
+
/** Override the API host (defaults to the public NOMOS Exchange). */
|
|
59
|
+
baseUrl?: string;
|
|
60
|
+
/** AbortSignal to cancel the request. */
|
|
61
|
+
signal?: AbortSignal;
|
|
62
|
+
}
|
|
63
|
+
interface CanResult {
|
|
64
|
+
/** True only for an AUTHORIZED verdict. DENIED and ESCALATED are both `false`. */
|
|
65
|
+
allowed: boolean;
|
|
66
|
+
/** The authority's own verdict, verbatim. */
|
|
67
|
+
verdict: CanVerdict;
|
|
68
|
+
/** Human-readable explanation of the verdict. */
|
|
69
|
+
reason: string;
|
|
70
|
+
/** The rule id that decided it, if any. */
|
|
71
|
+
rule: string | null;
|
|
72
|
+
/** Permanent, addressable transcript id — open it any time. */
|
|
73
|
+
query_id: string;
|
|
74
|
+
/** Relative URL of the transcript. */
|
|
75
|
+
url: string;
|
|
76
|
+
/** Which authority answered, and its standing. */
|
|
77
|
+
authority: {
|
|
78
|
+
id: string;
|
|
79
|
+
title: string;
|
|
80
|
+
standing: string;
|
|
81
|
+
};
|
|
82
|
+
/** On ESCALATED: the facts the authority still needs to reach a verdict. */
|
|
83
|
+
missing_inputs: string[];
|
|
84
|
+
}
|
|
45
85
|
interface VerifyDecisionResult {
|
|
86
|
+
/** Unique request ID — include in support tickets */
|
|
87
|
+
id: string;
|
|
88
|
+
/** Always "decision" */
|
|
89
|
+
object: 'decision';
|
|
90
|
+
/** The artifact that governed this decision */
|
|
91
|
+
artifact_id: string;
|
|
92
|
+
/** Artifact name */
|
|
93
|
+
artifact_name: string;
|
|
46
94
|
/** Whether the decision is permitted under current governance */
|
|
47
95
|
allowed: boolean;
|
|
48
|
-
/**
|
|
96
|
+
/** Human-readable verdict */
|
|
49
97
|
verdict: Verdict;
|
|
98
|
+
/** The rule that triggered this verdict, if any */
|
|
99
|
+
rule?: {
|
|
100
|
+
id: string;
|
|
101
|
+
description: string | null;
|
|
102
|
+
action: 'allow' | 'deny' | 'escalate';
|
|
103
|
+
};
|
|
104
|
+
/** Evaluation metrics */
|
|
105
|
+
evaluation: {
|
|
106
|
+
rules_evaluated: number;
|
|
107
|
+
rules_matched: number;
|
|
108
|
+
rules_expired: number;
|
|
109
|
+
conflicts_resolved: number;
|
|
110
|
+
};
|
|
111
|
+
/** Confidence in the verdict */
|
|
112
|
+
confidence: {
|
|
113
|
+
/** Artifact verification tier */
|
|
114
|
+
tier: string;
|
|
115
|
+
/** 0–1 confidence score */
|
|
116
|
+
score: number;
|
|
117
|
+
/** Human-readable explanation of the tier */
|
|
118
|
+
description: string;
|
|
119
|
+
};
|
|
120
|
+
/** Audit record — store the hash for compliance */
|
|
121
|
+
audit: {
|
|
122
|
+
hash: string;
|
|
123
|
+
timestamp: string;
|
|
124
|
+
};
|
|
125
|
+
/** Performance metrics */
|
|
126
|
+
performance: {
|
|
127
|
+
latency_ms: number;
|
|
128
|
+
};
|
|
129
|
+
/** API schema version */
|
|
130
|
+
schema_version: string;
|
|
50
131
|
/** Human-readable explanation */
|
|
51
132
|
verdict_description: string;
|
|
52
|
-
/**
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
133
|
+
/** Missing input fields, if any rule-referenced fields were absent */
|
|
134
|
+
incomplete_inputs?: {
|
|
135
|
+
fields: string[];
|
|
136
|
+
count: number;
|
|
137
|
+
warning: string;
|
|
138
|
+
};
|
|
139
|
+
/** How to satisfy an approval rule when current verdict is not approved */
|
|
140
|
+
paths_to_approval?: Array<{
|
|
141
|
+
rule_id: string | null;
|
|
142
|
+
rule_name: string | null;
|
|
143
|
+
required_changes: Array<{
|
|
144
|
+
field: string;
|
|
145
|
+
current: unknown;
|
|
146
|
+
must_satisfy: string;
|
|
147
|
+
}>;
|
|
148
|
+
}>;
|
|
62
149
|
}
|
|
63
150
|
interface Artifact {
|
|
64
151
|
id: string;
|
|
@@ -85,6 +172,24 @@ interface ArtifactList {
|
|
|
85
172
|
limit: number;
|
|
86
173
|
offset: number;
|
|
87
174
|
}
|
|
175
|
+
interface ArtifactSchemaField {
|
|
176
|
+
name: string;
|
|
177
|
+
type: 'string' | 'number' | 'integer' | 'boolean' | 'date' | 'datetime' | 'enum' | 'array';
|
|
178
|
+
required: boolean;
|
|
179
|
+
description?: string;
|
|
180
|
+
enum?: string[];
|
|
181
|
+
min?: number;
|
|
182
|
+
max?: number;
|
|
183
|
+
format?: string;
|
|
184
|
+
}
|
|
185
|
+
interface ArtifactSchema {
|
|
186
|
+
artifact_id: string;
|
|
187
|
+
name: string;
|
|
188
|
+
fields: ArtifactSchemaField[];
|
|
189
|
+
required_fields: string[];
|
|
190
|
+
example_inputs: Record<string, unknown>;
|
|
191
|
+
field_count: number;
|
|
192
|
+
}
|
|
88
193
|
interface Contradiction {
|
|
89
194
|
type: 'threshold_conflict' | 'role_conflict' | 'ghost_term' | 'rule_collision' | 'layer_divergence';
|
|
90
195
|
severity: 'critical' | 'warning' | 'info';
|
|
@@ -226,6 +331,21 @@ declare class Artifacts {
|
|
|
226
331
|
* }
|
|
227
332
|
*/
|
|
228
333
|
listAutoPaging(params?: ListArtifactsParams, opts?: RequestOptions): AsyncGenerator<Artifact>;
|
|
334
|
+
/**
|
|
335
|
+
* Retrieve the declared input schema for a sealed artifact.
|
|
336
|
+
*
|
|
337
|
+
* Returns every field the artifact's rules reference — name, type, whether it's
|
|
338
|
+
* required, and a ready-to-use example_inputs object. Use this to build forms,
|
|
339
|
+
* validate payloads, or generate API docs without reading the rules manually.
|
|
340
|
+
*
|
|
341
|
+
* Requires an API key (artifact schemas are not public).
|
|
342
|
+
*
|
|
343
|
+
* @example
|
|
344
|
+
* const schema = await nomos.artifacts.schema('art_abc123');
|
|
345
|
+
* console.log(schema.required_fields); // ['credit_score', 'loan_amount']
|
|
346
|
+
* console.log(schema.example_inputs); // { credit_score: 0, loan_amount: 0 }
|
|
347
|
+
*/
|
|
348
|
+
schema(artifactId: string, opts?: RequestOptions): Promise<WithLastResponse<ArtifactSchema>>;
|
|
229
349
|
}
|
|
230
350
|
|
|
231
351
|
declare class Governance {
|
|
@@ -357,4 +477,13 @@ declare class Nomos {
|
|
|
357
477
|
constructor(apiKey: string, config?: NomosConfig);
|
|
358
478
|
}
|
|
359
479
|
|
|
360
|
-
|
|
480
|
+
declare function can(params: CanParams, opts?: CanOptions): Promise<CanResult>;
|
|
481
|
+
/**
|
|
482
|
+
* Ready-to-use, keyless entry point matching the canonical `nomos.can(...)` form.
|
|
483
|
+
* For authenticated, key-scoped operations use the `Nomos` class instead.
|
|
484
|
+
*/
|
|
485
|
+
declare const nomos: {
|
|
486
|
+
can: typeof can;
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
export { type Artifact, type ArtifactList, type ArtifactSchema, type ArtifactSchemaField, type CanOptions, type CanParams, type CanResult, type CanVerdict, type Contradiction, type DetectContradictionsParams, type DetectContradictionsResult, type GenerateGovernanceParams, type GenerateGovernanceResult, type ListArtifactsParams, Nomos, NomosAPIError, NomosAuthenticationError, NomosAuthorizationError, type NomosConfig, NomosError, type NomosErrorCode, NomosNetworkError, NomosNotFoundError, NomosRateLimitError, type NomosRawResponse, NomosValidationError, type NomosWebhookEvent, type NomosWebhookEventType, NomosWebhookSignatureError, type RequestOptions, type Verdict, type VerifyDecisionParams, type VerifyDecisionResult, type WithLastResponse, can, nomos };
|
package/dist/index.js
CHANGED
|
@@ -226,21 +226,28 @@ var Decisions = class {
|
|
|
226
226
|
} else {
|
|
227
227
|
httpResp = await this.http.post("/api/v1/verify-decision", {
|
|
228
228
|
artifact_id,
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
correlation_id: correlation_id ?? globalThis.crypto.randomUUID()
|
|
229
|
+
decision: proposed_decision ?? "evaluate",
|
|
230
|
+
inputs: decision_context,
|
|
231
|
+
caller: { correlation_id: correlation_id ?? globalThis.crypto.randomUUID() }
|
|
232
232
|
}, opts);
|
|
233
233
|
}
|
|
234
234
|
const raw = httpResp.data;
|
|
235
235
|
return {
|
|
236
|
+
id: raw.id ?? `req_${raw.execution_id ?? globalThis.crypto.randomUUID()}`,
|
|
237
|
+
object: raw.object ?? "decision",
|
|
238
|
+
artifact_id: raw.artifact_id ?? artifact_id,
|
|
239
|
+
artifact_name: raw.artifact_name ?? "",
|
|
236
240
|
allowed: raw.allowed ?? false,
|
|
237
|
-
verdict: raw.
|
|
241
|
+
verdict: raw.verdict ?? (raw.outcome === "auto_approved" ? "approved" : raw.outcome === "auto_rejected" ? "rejected" : "escalated"),
|
|
242
|
+
rule: raw.rule,
|
|
243
|
+
evaluation: raw.evaluation ?? { rules_evaluated: raw.rules_evaluated ?? 0, rules_matched: 0, rules_expired: 0, conflicts_resolved: 0 },
|
|
244
|
+
confidence: raw.confidence ?? { tier: raw.artifact_confidence ?? "DECLARED", score: 1, description: "" },
|
|
245
|
+
audit: raw.audit ?? { hash: raw.audit_hash ?? raw.audit_record ?? "", timestamp: raw.ts ?? (/* @__PURE__ */ new Date()).toISOString() },
|
|
246
|
+
performance: raw.performance ?? { latency_ms: raw.latency_ms ?? 0 },
|
|
247
|
+
schema_version: raw.schema_version ?? "1.0.0",
|
|
238
248
|
verdict_description: raw.verdict_description ?? "",
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
artifact_id: raw.artifact_id ?? artifact_id,
|
|
242
|
-
execution_id: raw.execution_id,
|
|
243
|
-
decided_at: raw.decided_at ?? raw.evaluated_at ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
249
|
+
incomplete_inputs: raw.incomplete_inputs,
|
|
250
|
+
paths_to_approval: raw.paths_to_approval,
|
|
244
251
|
lastResponse: httpResp.lastResponse
|
|
245
252
|
};
|
|
246
253
|
}
|
|
@@ -316,6 +323,27 @@ var Artifacts = class {
|
|
|
316
323
|
offset += page.data.length;
|
|
317
324
|
}
|
|
318
325
|
}
|
|
326
|
+
/**
|
|
327
|
+
* Retrieve the declared input schema for a sealed artifact.
|
|
328
|
+
*
|
|
329
|
+
* Returns every field the artifact's rules reference — name, type, whether it's
|
|
330
|
+
* required, and a ready-to-use example_inputs object. Use this to build forms,
|
|
331
|
+
* validate payloads, or generate API docs without reading the rules manually.
|
|
332
|
+
*
|
|
333
|
+
* Requires an API key (artifact schemas are not public).
|
|
334
|
+
*
|
|
335
|
+
* @example
|
|
336
|
+
* const schema = await nomos.artifacts.schema('art_abc123');
|
|
337
|
+
* console.log(schema.required_fields); // ['credit_score', 'loan_amount']
|
|
338
|
+
* console.log(schema.example_inputs); // { credit_score: 0, loan_amount: 0 }
|
|
339
|
+
*/
|
|
340
|
+
async schema(artifactId, opts) {
|
|
341
|
+
const { data, lastResponse } = await this.http.get(
|
|
342
|
+
`/api/v1/artifacts/${encodeURIComponent(artifactId)}/schema`,
|
|
343
|
+
opts
|
|
344
|
+
);
|
|
345
|
+
return { ...data, lastResponse };
|
|
346
|
+
}
|
|
319
347
|
};
|
|
320
348
|
|
|
321
349
|
// src/resources/governance.ts
|
|
@@ -494,6 +522,69 @@ var Nomos = class {
|
|
|
494
522
|
this.webhooks = new Webhooks();
|
|
495
523
|
}
|
|
496
524
|
};
|
|
525
|
+
|
|
526
|
+
// src/can.ts
|
|
527
|
+
var DEFAULT_EXCHANGE_BASE = "https://www.nomosprotocol.com";
|
|
528
|
+
async function can(params, opts) {
|
|
529
|
+
const { authority, action, inputs, ...flat } = params;
|
|
530
|
+
if (!authority || typeof authority !== "string") {
|
|
531
|
+
throw new Error("can(): `authority` (an Exchange artifact id or slug) is required.");
|
|
532
|
+
}
|
|
533
|
+
const facts = inputs && typeof inputs === "object" ? inputs : flat;
|
|
534
|
+
const base = (opts?.baseUrl ?? DEFAULT_EXCHANGE_BASE).replace(/\/$/, "");
|
|
535
|
+
const url = `${base}/api/exchange/artifacts/${encodeURIComponent(authority)}/query`;
|
|
536
|
+
let res;
|
|
537
|
+
try {
|
|
538
|
+
res = await fetch(url, {
|
|
539
|
+
method: "POST",
|
|
540
|
+
headers: { "Content-Type": "application/json" },
|
|
541
|
+
body: JSON.stringify({ inputs: facts, action }),
|
|
542
|
+
signal: opts?.signal
|
|
543
|
+
});
|
|
544
|
+
} catch (err) {
|
|
545
|
+
if (err?.name === "AbortError") throw new NomosNetworkError("Request aborted");
|
|
546
|
+
throw new NomosNetworkError(err?.message ?? "Network error");
|
|
547
|
+
}
|
|
548
|
+
const requestId = res.headers.get("x-request-id") ?? "";
|
|
549
|
+
const data = await res.json().catch(() => null);
|
|
550
|
+
if (!res.ok) {
|
|
551
|
+
const message = data?.error ?? data?.message ?? `NOMOS query failed (HTTP ${res.status})`;
|
|
552
|
+
switch (res.status) {
|
|
553
|
+
case 401:
|
|
554
|
+
throw new NomosAuthenticationError(message, requestId);
|
|
555
|
+
case 403:
|
|
556
|
+
throw new NomosAuthorizationError(message, requestId);
|
|
557
|
+
case 404:
|
|
558
|
+
throw new NomosNotFoundError(message, requestId);
|
|
559
|
+
case 422:
|
|
560
|
+
case 400:
|
|
561
|
+
throw new NomosValidationError(message, data?.details, requestId);
|
|
562
|
+
case 429:
|
|
563
|
+
throw new NomosRateLimitError(
|
|
564
|
+
message,
|
|
565
|
+
res.headers.get("retry-after") ? parseInt(res.headers.get("retry-after"), 10) : void 0,
|
|
566
|
+
requestId
|
|
567
|
+
);
|
|
568
|
+
default:
|
|
569
|
+
throw new NomosAPIError(message, res.status, requestId);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
return {
|
|
573
|
+
allowed: data.verdict === "AUTHORIZED",
|
|
574
|
+
verdict: data.verdict,
|
|
575
|
+
reason: data.verdict_description,
|
|
576
|
+
rule: data.matched_rule_id ?? null,
|
|
577
|
+
query_id: data.query_id,
|
|
578
|
+
url: data.url,
|
|
579
|
+
authority: {
|
|
580
|
+
id: data.artifact?.id ?? authority,
|
|
581
|
+
title: data.artifact?.title ?? "",
|
|
582
|
+
standing: data.artifact?.standing ?? ""
|
|
583
|
+
},
|
|
584
|
+
missing_inputs: data.missing_inputs ?? []
|
|
585
|
+
};
|
|
586
|
+
}
|
|
587
|
+
var nomos = { can };
|
|
497
588
|
export {
|
|
498
589
|
Nomos,
|
|
499
590
|
NomosAPIError,
|
|
@@ -504,6 +595,8 @@ export {
|
|
|
504
595
|
NomosNotFoundError,
|
|
505
596
|
NomosRateLimitError,
|
|
506
597
|
NomosValidationError,
|
|
507
|
-
NomosWebhookSignatureError
|
|
598
|
+
NomosWebhookSignatureError,
|
|
599
|
+
can,
|
|
600
|
+
nomos
|
|
508
601
|
};
|
|
509
602
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/util.ts","../src/http-client.ts","../src/resources/decisions.ts","../src/resources/artifacts.ts","../src/resources/governance.ts","../src/resources/webhooks.ts","../src/nomos.ts"],"sourcesContent":["export type NomosErrorCode =\n | 'authentication_error'\n | 'authorization_error'\n | 'rate_limit_error'\n | 'validation_error'\n | 'not_found'\n | 'api_error'\n | 'network_error'\n | 'webhook_signature_error';\n\nexport class NomosError extends Error {\n readonly code: NomosErrorCode;\n readonly status?: number;\n readonly requestId?: string;\n\n constructor(message: string, code: NomosErrorCode, status?: number, requestId?: string) {\n super(message);\n this.name = 'NomosError';\n this.code = code;\n this.status = status;\n this.requestId = requestId;\n }\n}\n\nexport class NomosAuthenticationError extends NomosError {\n constructor(message = 'Invalid API key', requestId?: string) {\n super(message, 'authentication_error', 401, requestId);\n this.name = 'NomosAuthenticationError';\n }\n}\n\nexport class NomosAuthorizationError extends NomosError {\n constructor(message = 'Access denied', requestId?: string) {\n super(message, 'authorization_error', 403, requestId);\n this.name = 'NomosAuthorizationError';\n }\n}\n\nexport class NomosRateLimitError extends NomosError {\n readonly retryAfter?: number;\n\n constructor(message = 'Rate limit exceeded', retryAfter?: number, requestId?: string) {\n super(message, 'rate_limit_error', 429, requestId);\n this.name = 'NomosRateLimitError';\n this.retryAfter = retryAfter;\n }\n}\n\nexport class NomosValidationError extends NomosError {\n readonly details?: unknown;\n\n constructor(message: string, details?: unknown, requestId?: string) {\n super(message, 'validation_error', 400, requestId);\n this.name = 'NomosValidationError';\n this.details = details;\n }\n}\n\nexport class NomosNotFoundError extends NomosError {\n constructor(message: string, requestId?: string) {\n super(message, 'not_found', 404, requestId);\n this.name = 'NomosNotFoundError';\n }\n}\n\nexport class NomosAPIError extends NomosError {\n constructor(message: string, status: number, requestId?: string) {\n super(message, 'api_error', status, requestId);\n this.name = 'NomosAPIError';\n }\n}\n\nexport class NomosNetworkError extends NomosError {\n constructor(message: string) {\n super(message, 'network_error');\n this.name = 'NomosNetworkError';\n }\n}\n\nexport class NomosWebhookSignatureError extends NomosError {\n constructor(message: string) {\n super(message, 'webhook_signature_error', 400);\n this.name = 'NomosWebhookSignatureError';\n }\n}\n","export async function sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nexport function jitteredBackoff(attempt: number, baseMs = 500): number {\n const exp = Math.min(baseMs * 2 ** attempt, 16000);\n return exp * (0.75 + Math.random() * 0.5); // ±25% jitter\n}\n\nexport function isRetryable(status: number): boolean {\n return status === 429 || status >= 500;\n}\n","import {\n NomosAuthenticationError,\n NomosAuthorizationError,\n NomosRateLimitError,\n NomosValidationError,\n NomosNotFoundError,\n NomosAPIError,\n NomosNetworkError,\n} from './errors.js';\nimport { sleep, jitteredBackoff, isRetryable } from './util.js';\nimport type { RequestOptions, NomosRawResponse } from './types.js';\n\nconst SDK_VERSION = '1.1.0';\n\nexport interface HttpClientOptions {\n apiKey: string;\n baseUrl: string;\n maxRetries: number;\n timeout: number;\n}\n\nexport interface HttpResponse<T> {\n data: T;\n lastResponse: NomosRawResponse;\n}\n\nexport class HttpClient {\n constructor(private readonly opts: HttpClientOptions) {}\n\n async get<T>(path: string, reqOpts?: RequestOptions): Promise<HttpResponse<T>> {\n return this.request<T>('GET', path, undefined, reqOpts);\n }\n\n async post<T>(path: string, body: unknown, reqOpts?: RequestOptions): Promise<HttpResponse<T>> {\n return this.request<T>('POST', path, body, reqOpts);\n }\n\n private async request<T>(\n method: string,\n path: string,\n body: unknown,\n reqOpts?: RequestOptions,\n attempt = 0,\n ): Promise<HttpResponse<T>> {\n const apiKey = reqOpts?.apiKey ?? this.opts.apiKey;\n const timeout = reqOpts?.timeout ?? this.opts.timeout;\n const maxRetries = reqOpts?.maxRetries ?? this.opts.maxRetries;\n\n const url = `${this.opts.baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeout);\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-Nomos-Api-Key': apiKey,\n 'User-Agent': `nomos-node/${SDK_VERSION}`,\n 'NOMOS-SDK-Version': SDK_VERSION,\n };\n if (reqOpts?.idempotencyKey) {\n headers['Idempotency-Key'] = reqOpts.idempotencyKey;\n }\n\n let res: Response;\n try {\n res = await fetch(url, {\n method,\n signal: controller.signal,\n headers,\n body: body != null ? JSON.stringify(body) : undefined,\n });\n } catch (err: any) {\n clearTimeout(timer);\n if (err.name === 'AbortError') {\n throw new NomosNetworkError(`Request timed out after ${timeout}ms`);\n }\n throw new NomosNetworkError(err.message ?? 'Network error');\n } finally {\n clearTimeout(timer);\n }\n\n const requestId = res.headers.get('x-request-id') ?? '';\n const rawHeaders: Record<string, string> = {};\n res.headers.forEach((value, key) => { rawHeaders[key] = value; });\n const lastResponse: NomosRawResponse = {\n requestId,\n statusCode: res.status,\n headers: rawHeaders,\n };\n\n if (res.ok) {\n const data = await res.json() as T;\n return { data, lastResponse };\n }\n\n // Retry on 429 / 5xx\n if (isRetryable(res.status) && attempt < maxRetries) {\n const retryAfter = res.headers.get('retry-after');\n const delay = retryAfter ? parseInt(retryAfter, 10) * 1000 : jitteredBackoff(attempt);\n await sleep(delay);\n return this.request<T>(method, path, body, reqOpts, attempt + 1);\n }\n\n let errBody: any = {};\n try { errBody = await res.json(); } catch {}\n const message: string = errBody?.error ?? errBody?.message ?? res.statusText;\n\n switch (res.status) {\n case 401: throw new NomosAuthenticationError(message, requestId);\n case 403: throw new NomosAuthorizationError(message, requestId);\n case 404: throw new NomosNotFoundError(message, requestId);\n case 422:\n case 400: throw new NomosValidationError(message, errBody?.details, requestId);\n case 429: throw new NomosRateLimitError(\n message,\n res.headers.get('retry-after') ? parseInt(res.headers.get('retry-after')!, 10) : undefined,\n requestId,\n );\n default: throw new NomosAPIError(message, res.status, requestId);\n }\n }\n}\n","import type { HttpClient } from '../http-client.js';\nimport type {\n VerifyDecisionParams,\n VerifyDecisionResult,\n RequestOptions,\n WithLastResponse,\n} from '../types.js';\n\nexport class Decisions {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Verify whether an AI decision is permitted under a governance artifact.\n *\n * Public demo artifacts (`pub_*`) work without an API key.\n * Custom artifacts require a valid API key.\n *\n * @example\n * const result = await nomos.decisions.verify({\n * artifact_id: 'pub_lending_v1',\n * decision_context: { credit_score: 720, loan_amount: 50000 },\n * });\n *\n * if (!result.allowed) {\n * throw new Error(`Blocked: ${result.verdict_description}`);\n * }\n *\n * // Debugging / tracing\n * console.log(result.lastResponse.requestId);\n *\n * @example\n * // Per-request options\n * const result = await nomos.decisions.verify(params, {\n * idempotencyKey: `verify-${transactionId}`,\n * timeout: 5000,\n * });\n */\n async verify(\n params: VerifyDecisionParams,\n opts?: RequestOptions,\n ): Promise<WithLastResponse<VerifyDecisionResult>> {\n const { artifact_id, decision_context, proposed_decision, correlation_id } = params;\n\n // Public artifacts (pub_*) use the open /verify endpoint — no API key required\n const isPublic = artifact_id.startsWith('pub_');\n let httpResp: Awaited<ReturnType<HttpClient['post']>>;\n\n if (isPublic) {\n httpResp = await this.http.post<any>('/api/v1/verify', {\n artifact_id,\n decision: proposed_decision ?? 'evaluate',\n inputs: decision_context,\n }, opts);\n } else {\n httpResp = await this.http.post<any>('/api/v1/verify-decision', {\n artifact_id,\n decision_context,\n proposed_decision,\n correlation_id: correlation_id ?? globalThis.crypto.randomUUID(),\n }, opts);\n }\n\n const raw: any = httpResp.data;\n\n return {\n allowed: raw.allowed ?? false,\n verdict: raw.outcome ?? raw.verdict ?? 'pending_human_review',\n verdict_description: raw.verdict_description ?? '',\n rule_reference: raw.rule_reference ?? raw.rule_applied,\n audit_record: raw.audit_record ?? raw.audit_hash,\n artifact_id: raw.artifact_id ?? artifact_id,\n execution_id: raw.execution_id,\n decided_at: raw.decided_at ?? raw.evaluated_at ?? new Date().toISOString(),\n lastResponse: httpResp.lastResponse,\n };\n }\n}\n","import type { HttpClient } from '../http-client.js';\nimport type {\n Artifact,\n ArtifactList,\n ListArtifactsParams,\n RequestOptions,\n WithLastResponse,\n} from '../types.js';\n\nexport class Artifacts {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Retrieve a single artifact by ID.\n *\n * @example\n * const artifact = await nomos.artifacts.retrieve('loan_approval_v1');\n * console.log(artifact.ari_score, artifact.autonomy_band);\n * console.log(artifact.lastResponse.requestId); // for support tickets\n */\n async retrieve(\n artifactId: string,\n opts?: RequestOptions,\n ): Promise<WithLastResponse<Artifact>> {\n const { data, lastResponse } = await this.http.get<Artifact>(\n `/api/exchange/artifacts/${encodeURIComponent(artifactId)}`,\n opts,\n );\n return { ...data, lastResponse };\n }\n\n /**\n * List published artifacts on the Exchange with optional filters.\n *\n * @example\n * const { data, total } = await nomos.artifacts.list({ band: 'autonomous', limit: 10 });\n *\n * @example\n * // With per-request options\n * const page = await nomos.artifacts.list({ limit: 20 }, { timeout: 5000 });\n */\n async list(\n params: ListArtifactsParams = {},\n opts?: RequestOptions,\n ): Promise<WithLastResponse<ArtifactList>> {\n const qs = new URLSearchParams();\n if (params.band) qs.set('band', params.band);\n if (params.domain) qs.set('domain', params.domain);\n if (params.jurisdiction) qs.set('jurisdiction', params.jurisdiction);\n if (params.sort) qs.set('sort', params.sort);\n if (params.limit != null) qs.set('limit', String(params.limit));\n if (params.offset != null) qs.set('offset', String(params.offset));\n const query = qs.toString();\n\n const { data: raw, lastResponse } = await this.http.get<any>(\n `/api/exchange/artifacts${query ? `?${query}` : ''}`,\n opts,\n );\n\n // API returns { artifacts: [], total: N } — normalise to { data: [], total: N }\n const normalized: ArtifactList = {\n data: Array.isArray(raw) ? raw : (raw.artifacts ?? raw.data ?? []),\n total: raw.total ?? (Array.isArray(raw) ? raw.length : 0),\n limit: params.limit ?? 20,\n offset: params.offset ?? 0,\n };\n\n return { ...normalized, lastResponse };\n }\n\n /**\n * Auto-paginating iterator — yields every artifact across all pages.\n * Stops automatically when the last page is reached.\n *\n * @example\n * for await (const artifact of nomos.artifacts.listAutoPaging({ band: 'autonomous' })) {\n * console.log(artifact.title, artifact.ari_score);\n * }\n */\n async *listAutoPaging(\n params: ListArtifactsParams = {},\n opts?: RequestOptions,\n ): AsyncGenerator<Artifact> {\n let offset = params.offset ?? 0;\n const limit = params.limit ?? 20;\n\n while (true) {\n const page = await this.list({ ...params, offset, limit }, opts);\n for (const item of page.data) yield item;\n if (page.data.length < limit || offset + page.data.length >= page.total) break;\n offset += page.data.length;\n }\n }\n}\n","import type { HttpClient } from '../http-client.js';\nimport type {\n GenerateGovernanceParams,\n GenerateGovernanceResult,\n DetectContradictionsParams,\n DetectContradictionsResult,\n RequestOptions,\n WithLastResponse,\n} from '../types.js';\n\nexport class Governance {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Generate a sealed .nomos governance artifact from policy documents\n * and optional historical decision logs.\n *\n * @example\n * const artifact = await nomos.governance.generate({\n * policies: [policyText],\n * decision_logs: historicalRows,\n * domain: 'loan_approval',\n * });\n * console.log(artifact.ari_score, artifact.seal_hash);\n */\n async generate(\n params: GenerateGovernanceParams,\n opts?: RequestOptions,\n ): Promise<WithLastResponse<GenerateGovernanceResult>> {\n const { data, lastResponse } = await this.http.post<GenerateGovernanceResult>(\n '/api/v1/generate-governance',\n params,\n opts,\n );\n return { ...data, lastResponse };\n }\n\n /**\n * Detect contradictions and conflicts in a rule set before sealing.\n *\n * @example\n * const report = await nomos.governance.detectContradictions({ rules });\n * if (!report.clean) {\n * console.log(report.contradictions);\n * }\n */\n async detectContradictions(\n params: DetectContradictionsParams,\n opts?: RequestOptions,\n ): Promise<WithLastResponse<DetectContradictionsResult>> {\n const { data, lastResponse } = await this.http.post<DetectContradictionsResult>(\n '/api/v1/detect-contradictions',\n params,\n opts,\n );\n return { ...data, lastResponse };\n }\n}\n","import { NomosWebhookSignatureError } from '../errors.js';\nimport type { NomosWebhookEvent } from '../types.js';\n\n// Hex string → Uint8Array (no Buffer dependency — works in Node and browsers)\nfunction hexToBytes(hex: string): Uint8Array {\n if (hex.length % 2 !== 0) throw new NomosWebhookSignatureError('Invalid hex encoding in signature');\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n const byte = parseInt(hex.slice(i, i + 2), 16);\n if (isNaN(byte)) throw new NomosWebhookSignatureError('Invalid hex encoding in signature');\n bytes[i / 2] = byte;\n }\n return bytes;\n}\n\n// Constant-time comparison (prevents timing attacks)\nfunction safeEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];\n return diff === 0;\n}\n\nexport class Webhooks {\n /**\n * Verify a NOMOS webhook signature and return the parsed event.\n *\n * Signature header format: `t=<unix_ts>,v1=<hmac_sha256_hex>`\n * Signed payload: `<timestamp>.<raw_body>`\n *\n * @example\n * // Express\n * app.post('/webhooks/nomos', express.raw({ type: 'application/json' }), async (req, res) => {\n * const event = await nomos.webhooks.constructEvent(\n * req.body,\n * req.headers['nomos-signature'] as string,\n * process.env.NOMOS_WEBHOOK_SECRET!,\n * );\n * console.log(event.type, event.data);\n * res.sendStatus(200);\n * });\n *\n * @throws {NomosWebhookSignatureError} if signature is invalid, expired, or malformed\n */\n async constructEvent(\n payload: string | Uint8Array,\n signature: string,\n secret: string,\n toleranceSeconds = 300,\n ): Promise<NomosWebhookEvent> {\n const body = typeof payload === 'string'\n ? payload\n : new TextDecoder().decode(payload);\n\n // Parse \"t=<ts>,v1=<hex>\" header\n const parts: Record<string, string> = {};\n for (const part of signature.split(',')) {\n const eq = part.indexOf('=');\n if (eq > -1) parts[part.slice(0, eq).trim()] = part.slice(eq + 1).trim();\n }\n\n if (!parts['t'] || !parts['v1']) {\n throw new NomosWebhookSignatureError(\n 'Invalid signature format — expected \"t=<timestamp>,v1=<hmac>\"',\n );\n }\n\n const timestamp = parseInt(parts['t'], 10);\n if (isNaN(timestamp)) {\n throw new NomosWebhookSignatureError('Invalid timestamp in webhook signature');\n }\n\n const ageSecs = Math.abs(Date.now() / 1000 - timestamp);\n if (toleranceSeconds > 0 && ageSecs > toleranceSeconds) {\n throw new NomosWebhookSignatureError(\n `Webhook timestamp too old (${Math.round(ageSecs)}s > ${toleranceSeconds}s tolerance). ` +\n 'Ensure your server clock is synced and the event is not being replayed.',\n );\n }\n\n // HMAC-SHA256 via Web Crypto API (Node 18+ / modern browsers — no dependencies)\n const enc = new TextEncoder();\n const keyMaterial = await globalThis.crypto.subtle.importKey(\n 'raw',\n enc.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n );\n const signedPayload = `${parts['t']}.${body}`;\n const expectedBuf = await globalThis.crypto.subtle.sign(\n 'HMAC',\n keyMaterial,\n enc.encode(signedPayload),\n );\n const expected = new Uint8Array(expectedBuf);\n const received = hexToBytes(parts['v1']);\n\n if (!safeEqual(expected, received)) {\n throw new NomosWebhookSignatureError(\n 'Webhook signature mismatch — verify your NOMOS_WEBHOOK_SECRET matches the one in Studio.',\n );\n }\n\n try {\n return JSON.parse(body) as NomosWebhookEvent;\n } catch {\n throw new NomosWebhookSignatureError('Webhook payload is not valid JSON');\n }\n }\n\n /**\n * Verify a webhook signature without parsing the event.\n * Returns `true` if valid, `false` if not (never throws).\n *\n * @example\n * const valid = await nomos.webhooks.verifySignature(rawBody, sig, secret);\n * if (!valid) return res.sendStatus(400);\n */\n async verifySignature(\n payload: string | Uint8Array,\n signature: string,\n secret: string,\n toleranceSeconds = 300,\n ): Promise<boolean> {\n try {\n await this.constructEvent(payload, signature, secret, toleranceSeconds);\n return true;\n } catch {\n return false;\n }\n }\n}\n","import { HttpClient } from './http-client.js';\nimport { Decisions } from './resources/decisions.js';\nimport { Artifacts } from './resources/artifacts.js';\nimport { Governance } from './resources/governance.js';\nimport { Webhooks } from './resources/webhooks.js';\nimport * as errors from './errors.js';\nimport type { NomosConfig } from './types.js';\n\nconst DEFAULT_BASE_URL = 'https://nomos.ai';\nconst DEFAULT_MAX_RETRIES = 3;\nconst DEFAULT_TIMEOUT = 30_000;\n\nexport class Nomos {\n readonly decisions: Decisions;\n readonly artifacts: Artifacts;\n readonly governance: Governance;\n readonly webhooks: Webhooks;\n\n /** Whether this instance is using a live or test API key. */\n readonly mode: 'live' | 'test';\n\n static readonly errors = errors;\n\n constructor(apiKey: string, config: NomosConfig = {}) {\n if (!apiKey || typeof apiKey !== 'string') {\n throw new errors.NomosAuthenticationError(\n 'A valid API key is required. Pass it as the first argument: new Nomos(\"nms_live_...\")',\n );\n }\n\n this.mode = apiKey.startsWith('nms_test_') ? 'test' : 'live';\n\n const http = new HttpClient({\n apiKey,\n baseUrl: (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, ''),\n maxRetries: config.maxRetries ?? DEFAULT_MAX_RETRIES,\n timeout: config.timeout ?? DEFAULT_TIMEOUT,\n });\n\n this.decisions = new Decisions(http);\n this.artifacts = new Artifacts(http);\n this.governance = new Governance(http);\n this.webhooks = new Webhooks();\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/util.ts","../src/http-client.ts","../src/resources/decisions.ts","../src/resources/artifacts.ts","../src/resources/governance.ts","../src/resources/webhooks.ts","../src/nomos.ts","../src/can.ts"],"sourcesContent":["export type NomosErrorCode =\n | 'authentication_error'\n | 'authorization_error'\n | 'rate_limit_error'\n | 'validation_error'\n | 'not_found'\n | 'api_error'\n | 'network_error'\n | 'webhook_signature_error';\n\nexport class NomosError extends Error {\n readonly code: NomosErrorCode;\n readonly status?: number;\n readonly requestId?: string;\n\n constructor(message: string, code: NomosErrorCode, status?: number, requestId?: string) {\n super(message);\n this.name = 'NomosError';\n this.code = code;\n this.status = status;\n this.requestId = requestId;\n }\n}\n\nexport class NomosAuthenticationError extends NomosError {\n constructor(message = 'Invalid API key', requestId?: string) {\n super(message, 'authentication_error', 401, requestId);\n this.name = 'NomosAuthenticationError';\n }\n}\n\nexport class NomosAuthorizationError extends NomosError {\n constructor(message = 'Access denied', requestId?: string) {\n super(message, 'authorization_error', 403, requestId);\n this.name = 'NomosAuthorizationError';\n }\n}\n\nexport class NomosRateLimitError extends NomosError {\n readonly retryAfter?: number;\n\n constructor(message = 'Rate limit exceeded', retryAfter?: number, requestId?: string) {\n super(message, 'rate_limit_error', 429, requestId);\n this.name = 'NomosRateLimitError';\n this.retryAfter = retryAfter;\n }\n}\n\nexport class NomosValidationError extends NomosError {\n readonly details?: unknown;\n\n constructor(message: string, details?: unknown, requestId?: string) {\n super(message, 'validation_error', 400, requestId);\n this.name = 'NomosValidationError';\n this.details = details;\n }\n}\n\nexport class NomosNotFoundError extends NomosError {\n constructor(message: string, requestId?: string) {\n super(message, 'not_found', 404, requestId);\n this.name = 'NomosNotFoundError';\n }\n}\n\nexport class NomosAPIError extends NomosError {\n constructor(message: string, status: number, requestId?: string) {\n super(message, 'api_error', status, requestId);\n this.name = 'NomosAPIError';\n }\n}\n\nexport class NomosNetworkError extends NomosError {\n constructor(message: string) {\n super(message, 'network_error');\n this.name = 'NomosNetworkError';\n }\n}\n\nexport class NomosWebhookSignatureError extends NomosError {\n constructor(message: string) {\n super(message, 'webhook_signature_error', 400);\n this.name = 'NomosWebhookSignatureError';\n }\n}\n","export async function sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nexport function jitteredBackoff(attempt: number, baseMs = 500): number {\n const exp = Math.min(baseMs * 2 ** attempt, 16000);\n return exp * (0.75 + Math.random() * 0.5); // ±25% jitter\n}\n\nexport function isRetryable(status: number): boolean {\n return status === 429 || status >= 500;\n}\n","import {\n NomosAuthenticationError,\n NomosAuthorizationError,\n NomosRateLimitError,\n NomosValidationError,\n NomosNotFoundError,\n NomosAPIError,\n NomosNetworkError,\n} from './errors.js';\nimport { sleep, jitteredBackoff, isRetryable } from './util.js';\nimport type { RequestOptions, NomosRawResponse } from './types.js';\n\nconst SDK_VERSION = '1.1.0';\n\nexport interface HttpClientOptions {\n apiKey: string;\n baseUrl: string;\n maxRetries: number;\n timeout: number;\n}\n\nexport interface HttpResponse<T> {\n data: T;\n lastResponse: NomosRawResponse;\n}\n\nexport class HttpClient {\n constructor(private readonly opts: HttpClientOptions) {}\n\n async get<T>(path: string, reqOpts?: RequestOptions): Promise<HttpResponse<T>> {\n return this.request<T>('GET', path, undefined, reqOpts);\n }\n\n async post<T>(path: string, body: unknown, reqOpts?: RequestOptions): Promise<HttpResponse<T>> {\n return this.request<T>('POST', path, body, reqOpts);\n }\n\n private async request<T>(\n method: string,\n path: string,\n body: unknown,\n reqOpts?: RequestOptions,\n attempt = 0,\n ): Promise<HttpResponse<T>> {\n const apiKey = reqOpts?.apiKey ?? this.opts.apiKey;\n const timeout = reqOpts?.timeout ?? this.opts.timeout;\n const maxRetries = reqOpts?.maxRetries ?? this.opts.maxRetries;\n\n const url = `${this.opts.baseUrl}${path}`;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeout);\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'X-Nomos-Api-Key': apiKey,\n 'User-Agent': `nomos-node/${SDK_VERSION}`,\n 'NOMOS-SDK-Version': SDK_VERSION,\n };\n if (reqOpts?.idempotencyKey) {\n headers['Idempotency-Key'] = reqOpts.idempotencyKey;\n }\n\n let res: Response;\n try {\n res = await fetch(url, {\n method,\n signal: controller.signal,\n headers,\n body: body != null ? JSON.stringify(body) : undefined,\n });\n } catch (err: any) {\n clearTimeout(timer);\n if (err.name === 'AbortError') {\n throw new NomosNetworkError(`Request timed out after ${timeout}ms`);\n }\n throw new NomosNetworkError(err.message ?? 'Network error');\n } finally {\n clearTimeout(timer);\n }\n\n const requestId = res.headers.get('x-request-id') ?? '';\n const rawHeaders: Record<string, string> = {};\n res.headers.forEach((value, key) => { rawHeaders[key] = value; });\n const lastResponse: NomosRawResponse = {\n requestId,\n statusCode: res.status,\n headers: rawHeaders,\n };\n\n if (res.ok) {\n const data = await res.json() as T;\n return { data, lastResponse };\n }\n\n // Retry on 429 / 5xx\n if (isRetryable(res.status) && attempt < maxRetries) {\n const retryAfter = res.headers.get('retry-after');\n const delay = retryAfter ? parseInt(retryAfter, 10) * 1000 : jitteredBackoff(attempt);\n await sleep(delay);\n return this.request<T>(method, path, body, reqOpts, attempt + 1);\n }\n\n let errBody: any = {};\n try { errBody = await res.json(); } catch {}\n const message: string = errBody?.error ?? errBody?.message ?? res.statusText;\n\n switch (res.status) {\n case 401: throw new NomosAuthenticationError(message, requestId);\n case 403: throw new NomosAuthorizationError(message, requestId);\n case 404: throw new NomosNotFoundError(message, requestId);\n case 422:\n case 400: throw new NomosValidationError(message, errBody?.details, requestId);\n case 429: throw new NomosRateLimitError(\n message,\n res.headers.get('retry-after') ? parseInt(res.headers.get('retry-after')!, 10) : undefined,\n requestId,\n );\n default: throw new NomosAPIError(message, res.status, requestId);\n }\n }\n}\n","import type { HttpClient } from '../http-client.js';\nimport type {\n VerifyDecisionParams,\n VerifyDecisionResult,\n RequestOptions,\n WithLastResponse,\n} from '../types.js';\n\nexport class Decisions {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Verify whether an AI decision is permitted under a governance artifact.\n *\n * Public demo artifacts (`pub_*`) work without an API key.\n * Custom artifacts require a valid API key.\n *\n * @example\n * const result = await nomos.decisions.verify({\n * artifact_id: 'pub_lending_v1',\n * decision_context: { credit_score: 720, loan_amount: 50000 },\n * });\n *\n * if (!result.allowed) {\n * throw new Error(`Blocked: ${result.verdict_description}`);\n * }\n *\n * // Debugging / tracing\n * console.log(result.lastResponse.requestId);\n *\n * @example\n * // Per-request options\n * const result = await nomos.decisions.verify(params, {\n * idempotencyKey: `verify-${transactionId}`,\n * timeout: 5000,\n * });\n */\n async verify(\n params: VerifyDecisionParams,\n opts?: RequestOptions,\n ): Promise<WithLastResponse<VerifyDecisionResult>> {\n const { artifact_id, decision_context, proposed_decision, correlation_id } = params;\n\n // Public artifacts (pub_*) use the open /verify endpoint — no API key required\n const isPublic = artifact_id.startsWith('pub_');\n let httpResp: Awaited<ReturnType<HttpClient['post']>>;\n\n if (isPublic) {\n httpResp = await this.http.post<any>('/api/v1/verify', {\n artifact_id,\n decision: proposed_decision ?? 'evaluate',\n inputs: decision_context,\n }, opts);\n } else {\n // /verify-decision expects: { artifact_id, decision, inputs, caller? }\n // NOT decision_context / proposed_decision at the top level.\n httpResp = await this.http.post<any>('/api/v1/verify-decision', {\n artifact_id,\n decision: proposed_decision ?? 'evaluate',\n inputs: decision_context,\n caller: { correlation_id: correlation_id ?? globalThis.crypto.randomUUID() },\n }, opts);\n }\n\n const raw: any = httpResp.data;\n\n return {\n id: raw.id ?? `req_${raw.execution_id ?? globalThis.crypto.randomUUID()}`,\n object: raw.object ?? 'decision',\n artifact_id: raw.artifact_id ?? artifact_id,\n artifact_name: raw.artifact_name ?? '',\n allowed: raw.allowed ?? false,\n verdict: raw.verdict ?? (raw.outcome === 'auto_approved' ? 'approved' : raw.outcome === 'auto_rejected' ? 'rejected' : 'escalated'),\n rule: raw.rule,\n evaluation: raw.evaluation ?? { rules_evaluated: raw.rules_evaluated ?? 0, rules_matched: 0, rules_expired: 0, conflicts_resolved: 0 },\n confidence: raw.confidence ?? { tier: raw.artifact_confidence ?? 'DECLARED', score: 1, description: '' },\n audit: raw.audit ?? { hash: raw.audit_hash ?? raw.audit_record ?? '', timestamp: raw.ts ?? new Date().toISOString() },\n performance: raw.performance ?? { latency_ms: raw.latency_ms ?? 0 },\n schema_version: raw.schema_version ?? '1.0.0',\n verdict_description: raw.verdict_description ?? '',\n incomplete_inputs: raw.incomplete_inputs,\n paths_to_approval: raw.paths_to_approval,\n lastResponse: httpResp.lastResponse,\n };\n }\n}\n","import type { HttpClient } from '../http-client.js';\nimport type {\n Artifact,\n ArtifactList,\n ArtifactSchema,\n ListArtifactsParams,\n RequestOptions,\n WithLastResponse,\n} from '../types.js';\n\nexport class Artifacts {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Retrieve a single artifact by ID.\n *\n * @example\n * const artifact = await nomos.artifacts.retrieve('loan_approval_v1');\n * console.log(artifact.ari_score, artifact.autonomy_band);\n * console.log(artifact.lastResponse.requestId); // for support tickets\n */\n async retrieve(\n artifactId: string,\n opts?: RequestOptions,\n ): Promise<WithLastResponse<Artifact>> {\n const { data, lastResponse } = await this.http.get<Artifact>(\n `/api/exchange/artifacts/${encodeURIComponent(artifactId)}`,\n opts,\n );\n return { ...data, lastResponse };\n }\n\n /**\n * List published artifacts on the Exchange with optional filters.\n *\n * @example\n * const { data, total } = await nomos.artifacts.list({ band: 'autonomous', limit: 10 });\n *\n * @example\n * // With per-request options\n * const page = await nomos.artifacts.list({ limit: 20 }, { timeout: 5000 });\n */\n async list(\n params: ListArtifactsParams = {},\n opts?: RequestOptions,\n ): Promise<WithLastResponse<ArtifactList>> {\n const qs = new URLSearchParams();\n if (params.band) qs.set('band', params.band);\n if (params.domain) qs.set('domain', params.domain);\n if (params.jurisdiction) qs.set('jurisdiction', params.jurisdiction);\n if (params.sort) qs.set('sort', params.sort);\n if (params.limit != null) qs.set('limit', String(params.limit));\n if (params.offset != null) qs.set('offset', String(params.offset));\n const query = qs.toString();\n\n const { data: raw, lastResponse } = await this.http.get<any>(\n `/api/exchange/artifacts${query ? `?${query}` : ''}`,\n opts,\n );\n\n // API returns { artifacts: [], total: N } — normalise to { data: [], total: N }\n const normalized: ArtifactList = {\n data: Array.isArray(raw) ? raw : (raw.artifacts ?? raw.data ?? []),\n total: raw.total ?? (Array.isArray(raw) ? raw.length : 0),\n limit: params.limit ?? 20,\n offset: params.offset ?? 0,\n };\n\n return { ...normalized, lastResponse };\n }\n\n /**\n * Auto-paginating iterator — yields every artifact across all pages.\n * Stops automatically when the last page is reached.\n *\n * @example\n * for await (const artifact of nomos.artifacts.listAutoPaging({ band: 'autonomous' })) {\n * console.log(artifact.title, artifact.ari_score);\n * }\n */\n async *listAutoPaging(\n params: ListArtifactsParams = {},\n opts?: RequestOptions,\n ): AsyncGenerator<Artifact> {\n let offset = params.offset ?? 0;\n const limit = params.limit ?? 20;\n\n while (true) {\n const page = await this.list({ ...params, offset, limit }, opts);\n for (const item of page.data) yield item;\n if (page.data.length < limit || offset + page.data.length >= page.total) break;\n offset += page.data.length;\n }\n }\n\n /**\n * Retrieve the declared input schema for a sealed artifact.\n *\n * Returns every field the artifact's rules reference — name, type, whether it's\n * required, and a ready-to-use example_inputs object. Use this to build forms,\n * validate payloads, or generate API docs without reading the rules manually.\n *\n * Requires an API key (artifact schemas are not public).\n *\n * @example\n * const schema = await nomos.artifacts.schema('art_abc123');\n * console.log(schema.required_fields); // ['credit_score', 'loan_amount']\n * console.log(schema.example_inputs); // { credit_score: 0, loan_amount: 0 }\n */\n async schema(\n artifactId: string,\n opts?: RequestOptions,\n ): Promise<WithLastResponse<ArtifactSchema>> {\n const { data, lastResponse } = await this.http.get<ArtifactSchema>(\n `/api/v1/artifacts/${encodeURIComponent(artifactId)}/schema`,\n opts,\n );\n return { ...data, lastResponse };\n }\n}\n","import type { HttpClient } from '../http-client.js';\nimport type {\n GenerateGovernanceParams,\n GenerateGovernanceResult,\n DetectContradictionsParams,\n DetectContradictionsResult,\n RequestOptions,\n WithLastResponse,\n} from '../types.js';\n\nexport class Governance {\n constructor(private readonly http: HttpClient) {}\n\n /**\n * Generate a sealed .nomos governance artifact from policy documents\n * and optional historical decision logs.\n *\n * @example\n * const artifact = await nomos.governance.generate({\n * policies: [policyText],\n * decision_logs: historicalRows,\n * domain: 'loan_approval',\n * });\n * console.log(artifact.ari_score, artifact.seal_hash);\n */\n async generate(\n params: GenerateGovernanceParams,\n opts?: RequestOptions,\n ): Promise<WithLastResponse<GenerateGovernanceResult>> {\n const { data, lastResponse } = await this.http.post<GenerateGovernanceResult>(\n '/api/v1/generate-governance',\n params,\n opts,\n );\n return { ...data, lastResponse };\n }\n\n /**\n * Detect contradictions and conflicts in a rule set before sealing.\n *\n * @example\n * const report = await nomos.governance.detectContradictions({ rules });\n * if (!report.clean) {\n * console.log(report.contradictions);\n * }\n */\n async detectContradictions(\n params: DetectContradictionsParams,\n opts?: RequestOptions,\n ): Promise<WithLastResponse<DetectContradictionsResult>> {\n const { data, lastResponse } = await this.http.post<DetectContradictionsResult>(\n '/api/v1/detect-contradictions',\n params,\n opts,\n );\n return { ...data, lastResponse };\n }\n}\n","import { NomosWebhookSignatureError } from '../errors.js';\nimport type { NomosWebhookEvent } from '../types.js';\n\n// Hex string → Uint8Array (no Buffer dependency — works in Node and browsers)\nfunction hexToBytes(hex: string): Uint8Array {\n if (hex.length % 2 !== 0) throw new NomosWebhookSignatureError('Invalid hex encoding in signature');\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < hex.length; i += 2) {\n const byte = parseInt(hex.slice(i, i + 2), 16);\n if (isNaN(byte)) throw new NomosWebhookSignatureError('Invalid hex encoding in signature');\n bytes[i / 2] = byte;\n }\n return bytes;\n}\n\n// Constant-time comparison (prevents timing attacks)\nfunction safeEqual(a: Uint8Array, b: Uint8Array): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];\n return diff === 0;\n}\n\nexport class Webhooks {\n /**\n * Verify a NOMOS webhook signature and return the parsed event.\n *\n * Signature header format: `t=<unix_ts>,v1=<hmac_sha256_hex>`\n * Signed payload: `<timestamp>.<raw_body>`\n *\n * @example\n * // Express\n * app.post('/webhooks/nomos', express.raw({ type: 'application/json' }), async (req, res) => {\n * const event = await nomos.webhooks.constructEvent(\n * req.body,\n * req.headers['nomos-signature'] as string,\n * process.env.NOMOS_WEBHOOK_SECRET!,\n * );\n * console.log(event.type, event.data);\n * res.sendStatus(200);\n * });\n *\n * @throws {NomosWebhookSignatureError} if signature is invalid, expired, or malformed\n */\n async constructEvent(\n payload: string | Uint8Array,\n signature: string,\n secret: string,\n toleranceSeconds = 300,\n ): Promise<NomosWebhookEvent> {\n const body = typeof payload === 'string'\n ? payload\n : new TextDecoder().decode(payload);\n\n // Parse \"t=<ts>,v1=<hex>\" header\n const parts: Record<string, string> = {};\n for (const part of signature.split(',')) {\n const eq = part.indexOf('=');\n if (eq > -1) parts[part.slice(0, eq).trim()] = part.slice(eq + 1).trim();\n }\n\n if (!parts['t'] || !parts['v1']) {\n throw new NomosWebhookSignatureError(\n 'Invalid signature format — expected \"t=<timestamp>,v1=<hmac>\"',\n );\n }\n\n const timestamp = parseInt(parts['t'], 10);\n if (isNaN(timestamp)) {\n throw new NomosWebhookSignatureError('Invalid timestamp in webhook signature');\n }\n\n const ageSecs = Math.abs(Date.now() / 1000 - timestamp);\n if (toleranceSeconds > 0 && ageSecs > toleranceSeconds) {\n throw new NomosWebhookSignatureError(\n `Webhook timestamp too old (${Math.round(ageSecs)}s > ${toleranceSeconds}s tolerance). ` +\n 'Ensure your server clock is synced and the event is not being replayed.',\n );\n }\n\n // HMAC-SHA256 via Web Crypto API (Node 18+ / modern browsers — no dependencies)\n const enc = new TextEncoder();\n const keyMaterial = await globalThis.crypto.subtle.importKey(\n 'raw',\n enc.encode(secret),\n { name: 'HMAC', hash: 'SHA-256' },\n false,\n ['sign'],\n );\n const signedPayload = `${parts['t']}.${body}`;\n const expectedBuf = await globalThis.crypto.subtle.sign(\n 'HMAC',\n keyMaterial,\n enc.encode(signedPayload),\n );\n const expected = new Uint8Array(expectedBuf);\n const received = hexToBytes(parts['v1']);\n\n if (!safeEqual(expected, received)) {\n throw new NomosWebhookSignatureError(\n 'Webhook signature mismatch — verify your NOMOS_WEBHOOK_SECRET matches the one in Studio.',\n );\n }\n\n try {\n return JSON.parse(body) as NomosWebhookEvent;\n } catch {\n throw new NomosWebhookSignatureError('Webhook payload is not valid JSON');\n }\n }\n\n /**\n * Verify a webhook signature without parsing the event.\n * Returns `true` if valid, `false` if not (never throws).\n *\n * @example\n * const valid = await nomos.webhooks.verifySignature(rawBody, sig, secret);\n * if (!valid) return res.sendStatus(400);\n */\n async verifySignature(\n payload: string | Uint8Array,\n signature: string,\n secret: string,\n toleranceSeconds = 300,\n ): Promise<boolean> {\n try {\n await this.constructEvent(payload, signature, secret, toleranceSeconds);\n return true;\n } catch {\n return false;\n }\n }\n}\n","import { HttpClient } from './http-client.js';\nimport { Decisions } from './resources/decisions.js';\nimport { Artifacts } from './resources/artifacts.js';\nimport { Governance } from './resources/governance.js';\nimport { Webhooks } from './resources/webhooks.js';\nimport * as errors from './errors.js';\nimport type { NomosConfig } from './types.js';\n\nconst DEFAULT_BASE_URL = 'https://nomos.ai';\nconst DEFAULT_MAX_RETRIES = 3;\nconst DEFAULT_TIMEOUT = 30_000;\n\nexport class Nomos {\n readonly decisions: Decisions;\n readonly artifacts: Artifacts;\n readonly governance: Governance;\n readonly webhooks: Webhooks;\n\n /** Whether this instance is using a live or test API key. */\n readonly mode: 'live' | 'test';\n\n static readonly errors = errors;\n\n constructor(apiKey: string, config: NomosConfig = {}) {\n if (!apiKey || typeof apiKey !== 'string') {\n throw new errors.NomosAuthenticationError(\n 'A valid API key is required. Pass it as the first argument: new Nomos(\"nms_live_...\")',\n );\n }\n\n this.mode = apiKey.startsWith('nms_test_') ? 'test' : 'live';\n\n const http = new HttpClient({\n apiKey,\n baseUrl: (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, ''),\n maxRetries: config.maxRetries ?? DEFAULT_MAX_RETRIES,\n timeout: config.timeout ?? DEFAULT_TIMEOUT,\n });\n\n this.decisions = new Decisions(http);\n this.artifacts = new Artifacts(http);\n this.governance = new Governance(http);\n this.webhooks = new Webhooks();\n }\n}\n","import type { CanParams, CanResult, CanOptions } from './types.js';\nimport {\n NomosAuthenticationError,\n NomosAuthorizationError,\n NomosRateLimitError,\n NomosValidationError,\n NomosNotFoundError,\n NomosAPIError,\n NomosNetworkError,\n} from './errors.js';\n\n/**\n * The whole product in one verb: \"Can I do this?\"\n *\n * Ask a public Exchange authority a question and get back a deterministic, verifiable\n * verdict — no API key, no SDK setup, no reading a policy PDF. This is a thin, faithful\n * wrapper over the public Exchange query endpoint (the same call the exchange.nomosprotocol.com\n * \"Ask Authority\" box makes), so every answer is a real, addressable transcript you can open\n * at its `url` / `query_id`.\n *\n * Verdicts are exactly what the authority returns — AUTHORIZED / DENIED / ESCALATED — never\n * an invented shape. `allowed` is simply `verdict === 'AUTHORIZED'`; an ESCALATED result means\n * the authority needs more facts to decide (see `missing_inputs`), not a flat \"no\".\n *\n * @example\n * import { nomos } from '@nomosprotocol/sdk';\n *\n * const verdict = await nomos.can({\n * authority: 'eu-ai-act.nomos',\n * ai_system_circumvents_refugee_convention: true,\n * });\n * // → { allowed: false, verdict: 'DENIED', reason: 'Rule \"Prohibition…\" triggered…',\n * // query_id: 'qry_…', url: '/queries/qry_…', … }\n */\nconst DEFAULT_EXCHANGE_BASE = 'https://www.nomosprotocol.com';\n\nexport async function can(params: CanParams, opts?: CanOptions): Promise<CanResult> {\n const { authority, action, inputs, ...flat } = params;\n if (!authority || typeof authority !== 'string') {\n throw new Error('can(): `authority` (an Exchange artifact id or slug) is required.');\n }\n // Two equally valid shapes: an explicit `inputs` object, or the facts spread flat\n // alongside `authority`/`action`. Explicit `inputs` wins when both are present.\n const facts: Record<string, unknown> =\n inputs && typeof inputs === 'object' ? inputs : (flat as Record<string, unknown>);\n\n const base = (opts?.baseUrl ?? DEFAULT_EXCHANGE_BASE).replace(/\\/$/, '');\n const url = `${base}/api/exchange/artifacts/${encodeURIComponent(authority)}/query`;\n\n let res: Response;\n try {\n res = await fetch(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ inputs: facts, action }),\n signal: opts?.signal,\n });\n } catch (err: any) {\n if (err?.name === 'AbortError') throw new NomosNetworkError('Request aborted');\n throw new NomosNetworkError(err?.message ?? 'Network error');\n }\n\n const requestId = res.headers.get('x-request-id') ?? '';\n const data: any = await res.json().catch(() => null);\n if (!res.ok) {\n // Same status-code -> error-class mapping HttpClient uses for every other SDK call,\n // so `instanceof NomosNotFoundError` etc. works consistently everywhere — can() used to\n // throw a plain Error here, bypassing the SDK's own error hierarchy entirely.\n const message: string = data?.error ?? data?.message ?? `NOMOS query failed (HTTP ${res.status})`;\n switch (res.status) {\n case 401: throw new NomosAuthenticationError(message, requestId);\n case 403: throw new NomosAuthorizationError(message, requestId);\n case 404: throw new NomosNotFoundError(message, requestId);\n case 422:\n case 400: throw new NomosValidationError(message, data?.details, requestId);\n case 429: throw new NomosRateLimitError(\n message,\n res.headers.get('retry-after') ? parseInt(res.headers.get('retry-after')!, 10) : undefined,\n requestId,\n );\n default: throw new NomosAPIError(message, res.status, requestId);\n }\n }\n\n return {\n allowed: data.verdict === 'AUTHORIZED',\n verdict: data.verdict,\n reason: data.verdict_description,\n rule: data.matched_rule_id ?? null,\n query_id: data.query_id,\n url: data.url,\n authority: {\n id: data.artifact?.id ?? authority,\n title: data.artifact?.title ?? '',\n standing: data.artifact?.standing ?? '',\n },\n missing_inputs: data.missing_inputs ?? [],\n };\n}\n\n/**\n * Ready-to-use, keyless entry point matching the canonical `nomos.can(...)` form.\n * For authenticated, key-scoped operations use the `Nomos` class instead.\n */\nexport const nomos = { can };\n"],"mappings":"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","names":[]}
|