@nomosprotocol/sdk 1.3.3 → 1.3.4

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 CHANGED
@@ -111,12 +111,15 @@ NOMOS performs the entire verification locally:
111
111
 
112
112
  1. Walk the presented certificate chain from the root key you've pinned.
113
113
  2. Verify each link's signature and check it hasn't expired.
114
- 3. Check that no key in the chain has been revoked.
114
+ 3. Check that no key in the chain has been revoked, at every hop it visits — not just the
115
+ presented target — so a revoked intermediate is dead on every path a presenter might
116
+ construct through it.
115
117
  4. Verify the artifact's own cryptographic seal against the resolved key.
116
118
  5. Check whether the issuer has revoked this exact sealed version (NOMOS-SPEC-006). A revoked
117
119
  artifact returns `DENIED` with `revoked: true` and its rules are not consulted at all.
118
120
  6. Evaluate the artifact's rules against the supplied facts.
119
- 7. Return `AUTHORIZED`, `DENIED`, or `ESCALATED`.
121
+ 7. Return `AUTHORIZED`, `DENIED`, or `ESCALATED`, with `revocation_checked` disclosing how
122
+ confidently step 3 was actually able to check.
120
123
 
121
124
  Step 5 is deliberately identical to what the Exchange rail does, and runs off the same shared
122
125
  lookup. Which rail you use must never change whether an authority still stands behind its own
@@ -133,6 +136,32 @@ The root key is deliberately supplied by the relying party. NOMOS does not defin
133
136
 
134
137
  This rail implements [NOMOS-SPEC-007](https://github.com/nomos-spec/spec/blob/main/spec/NOMOS-SPEC-007.md), published as **Draft**. It has exactly one implementation — this one — and makes no interoperability claim until a second, independent implementation exists; that's what publishing a Draft is for.
135
138
 
139
+ #### `revocation_checked` — how confidently step 3 actually ran
140
+
141
+ ```ts
142
+ verdict.revocation_checked; // "live" | "staple" | "unchecked"
143
+ ```
144
+
145
+ On this deployment it is always `"live"` in practice: `can()` always talks to NOMOS's own hosted
146
+ endpoint, which always holds its own revocation list, so a presented staple would never be
147
+ consulted here — `can()` has no parameter for one, and this deployment never needs it. The
148
+ tri-state exists because the underlying primitive (NOMOS-SPEC-007 §5.5) is designed for a
149
+ verifier with **no** revocation source of its own at all — the exact case of someone running the
150
+ [pure reference implementation](https://github.com/nomos-spec/spec/tree/main/prototype/chain-of-trust)
151
+ standalone. That verifier cannot say a key is unrevoked; it can only raise confidence from
152
+ `"unchecked"` to `"staple"` if the presenter attaches a short-lived, issuer-signed "not revoked as
153
+ of T" proof directly to `POST /api/v1/chain-of-trust/verify`'s `freshness_staples` field (below
154
+ `can()`'s abstraction, not exposed through it) — or `"live"` if that verifier is given a real
155
+ revocation source of its own. `"unchecked"` means neither was available for at least one key on
156
+ the path (routinely the root itself — nothing certifies a root, so nothing but your own decision
157
+ to un-pin it answers "is my root still good"), and it is always the *weakest* result among every
158
+ key checked, never the best.
159
+
160
+ This deployment mints staples on request for keys it has issued
161
+ (`POST /api/v1/chain-of-trust/freshness`) — useful if you're forwarding a chain to a third party
162
+ who will verify it with nothing but the pure reference implementation, not something `can()`
163
+ itself needs.
164
+
136
165
  ## `.nomos` — the portable authority artifact
137
166
 
138
167
  A `.nomos` file is a sealed, machine-executable representation of institutional authority.
@@ -267,6 +296,8 @@ try {
267
296
  console.log(err.reason);
268
297
  // ISSUER_NOT_RECOGNIZED
269
298
  // KEY_REVOKED
299
+ // CERTIFICATE_REVOKED
300
+ // OUT_OF_SCOPE
270
301
  // SEAL_INVALID
271
302
  } else if (err instanceof NomosNetworkError) {
272
303
  // Network failure or timeout.
package/dist/index.cjs CHANGED
@@ -687,14 +687,17 @@ async function canViaChain(artifact, keyCerts, rootPublicKeyPem, facts, action,
687
687
  // data the caller is already holding.
688
688
  ...artifact?.meta?.version ? { version: artifact.meta.version } : {},
689
689
  missing_inputs: data.missing_inputs ?? [],
690
- ...Array.isArray(data.obligations) && data.obligations.length > 0 ? { obligations: data.obligations } : {}
690
+ ...Array.isArray(data.obligations) && data.obligations.length > 0 ? { obligations: data.obligations } : {},
691
+ // §5.5 — composing to a real permission decision must not silently drop the chain's own
692
+ // revocation-confidence disclosure; the server already threads this through, so forward it.
693
+ ...data.revocation_checked ? { revocation_checked: data.revocation_checked } : {}
691
694
  // Deliberately no query_id/url/audit — this evaluation is stateless by design (the whole
692
695
  // point is answering without NOMOS needing to have seen this artifact before); there is no
693
696
  // permanent transcript to point to, and faking one would misrepresent what just happened.
694
697
  };
695
698
  }
696
699
  const message = data?.detail ?? `Chain verification failed (HTTP ${res.status})`;
697
- if (data?.decision === "ISSUER_NOT_RECOGNIZED" || data?.decision === "KEY_REVOKED" || data?.decision === "SEAL_INVALID" || data?.decision === "ALLOWED") {
700
+ if (data?.decision === "ISSUER_NOT_RECOGNIZED" || data?.decision === "KEY_REVOKED" || data?.decision === "CERTIFICATE_REVOKED" || data?.decision === "OUT_OF_SCOPE" || data?.decision === "SEAL_INVALID" || data?.decision === "ALLOWED") {
698
701
  throw new NomosIssuerNotTrustedError(message, data.decision, requestId);
699
702
  }
700
703
  if (data?.decision === "MALFORMED") throw new NomosValidationError(message, data, requestId);
@@ -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/can.ts","../src/nomos.ts","../src/verify-chain.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';\n// Chain-of-trust verification (PROTOTYPE, not a numbered spec) — also keyless, same reasoning\n// as `can()`: verification itself should never require an account.\nexport { verifyChain } from './verify-chain.js';\nexport * from './errors.js';\nexport type {\n CanParams,\n CanOptions,\n CanResult,\n CanVerdict,\n AttestationInfo,\n NomosConfig,\n RequestOptions,\n NomosRawResponse,\n WithLastResponse,\n VerifyDecisionParams,\n VerifyDecisionResult,\n VerifyChainParams,\n VerifyChainOptions,\n VerifyChainResult,\n ChainVerdictDecision,\n KeyCertificate,\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 | 'payment_required'\n | 'issuer_not_trusted';\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\n/** can() asked about a paid authority the caller hasn't purchased or licensed. Distinct from a\n * generic 403 on purpose: this isn't \"you're not allowed,\" it's \"here's exactly what unlocks\n * it\" — price and a URL to complete the purchase. NOMOS never auto-charges on your behalf;\n * this is the seam where a caller decides to buy, not where a payment silently happens. */\nexport class NomosPaymentRequiredError extends NomosError {\n readonly priceUsd: number;\n readonly purchaseUrl: string;\n\n constructor(message: string, priceUsd: number, purchaseUrl: string, requestId?: string) {\n super(message, 'payment_required', 402, requestId);\n this.name = 'NomosPaymentRequiredError';\n this.priceUsd = priceUsd;\n this.purchaseUrl = purchaseUrl;\n }\n}\n\n/** can()'s chain-of-trust rail couldn't establish that the presented artifact is trustworthy —\n * an unrecognized issuer, a revoked key, a tampered seal, or a malformed presentation. This is\n * deliberately NOT a DENIED verdict: \"the rules say no\" and \"we never got far enough to ask the\n * rules anything\" are different claims, and collapsing them would tell the caller the wrong\n * thing to do next (re-presenting a better chain can fix the first case; it can never fix a\n * genuinely tampered artifact). `reason` is the underlying chain decision\n * (ISSUER_NOT_RECOGNIZED / KEY_REVOKED / SEAL_INVALID / MALFORMED) for callers that need to\n * distinguish them. */\nexport class NomosIssuerNotTrustedError extends NomosError {\n readonly reason: string;\n\n constructor(message: string, reason: string, requestId?: string) {\n super(message, 'issuer_not_trusted', 403, requestId);\n this.name = 'NomosIssuerNotTrustedError';\n this.reason = reason;\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 type { CanParams, CanResult, CanOptions } from './types.js';\nimport type { HttpClient } from './http-client.js';\nimport {\n NomosAuthenticationError,\n NomosAuthorizationError,\n NomosRateLimitError,\n NomosValidationError,\n NomosNotFoundError,\n NomosAPIError,\n NomosNetworkError,\n NomosPaymentRequiredError,\n NomosIssuerNotTrustedError,\n} from './errors.js';\n\nconst CHAIN_PROTOCOL_VERSION = '1';\n\n/**\n * The whole product in one verb: \"Can I do this?\"\n *\n * Same pattern as Stripe's PaymentIntents API: one function, several rails underneath (a public\n * Exchange authority — free or paid — or your own authenticated artifact), and the caller never\n * has to know which one ran. Don't read `can()` as \"the Exchange's query function\" — the\n * Exchange is one of two rails behind it, not what it means.\n *\n * Both rails call into the SAME server-side implementation NOMOS itself uses (POST /api/v1/can,\n * backed by authority-query.ts's runAuthorityQuery) — not a parallel path, so there is exactly\n * one place that can drift between \"what the SDK returns\" and \"what NOMOS actually decided.\"\n *\n * Verdicts are always AUTHORIZED / DENIED / ESCALATED, normalized into that one vocabulary\n * regardless of which rail answered. `allowed` is simply `verdict === 'AUTHORIZED'`; an\n * ESCALATED result means the authority needs more facts to decide (see `missing_inputs`), not a\n * flat \"no\". A paid Exchange artifact you haven't purchased throws NomosPaymentRequiredError —\n * with the price and a purchase URL attached — rather than a generic 403 or a silent failure.\n * NOMOS never auto-charges on your behalf; this is the seam where a caller decides to buy.\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\nfunction splitFacts(params: CanParams): { facts: Record<string, unknown>; action: string | undefined } {\n const { authority, artifact_id, action, inputs, ...flat } = params;\n void authority; void artifact_id;\n // Two equally valid shapes: an explicit `inputs` object, or the facts spread flat\n // alongside `authority`/`artifact_id`/`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 return { facts, action };\n}\n\nfunction mapHttpError(status: number, data: any, requestId: string): never {\n const message: string = data?.error ?? data?.message ?? `NOMOS query failed (HTTP ${status})`;\n // Checked by CODE, not by the raw wire status (403) — this is \"here's what unlocks it,\" a\n // materially different thing for a caller to act on than \"you're not allowed at all.\"\n if (data?.code === 'PURCHASE_REQUIRED') {\n throw new NomosPaymentRequiredError(message, data.price_usd ?? 0, data.purchase_url ?? '', requestId);\n }\n switch (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(message, undefined, requestId);\n default: throw new NomosAPIError(message, status, requestId);\n }\n}\n\n/** Both Exchange-rail paths (keyless and authenticated) return the same underlying shape —\n * authority-query.ts's AuthorityQueryResult, spread with a few convenience fields by the\n * /api/v1/can route. One normalizer for both, so they can't quietly drift apart. */\nfunction normalizeAuthorityQueryResult(data: any, authority: string): CanResult {\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 ...(data.artifact?.attestation ? { attestation: data.artifact.attestation } : {}),\n },\n ...(data.artifact?.version ? { version: data.artifact.version } : {}),\n missing_inputs: data.missing_inputs ?? [],\n ...(typeof data.max_age === 'number' ? { max_age: data.max_age } : {}),\n // authority-query.ts already returns { kind, rule_id, rule_name } — the public-safe shape\n // CanResult uses directly.\n ...(Array.isArray(data.obligations) && data.obligations.length > 0 ? { obligations: data.obligations } : {}),\n // NOMOS-SPEC-006 — present only when the issuer has actually revoked this exact sealed\n // version; omitted (not false) when revocation doesn't structurally apply here, so \"checked\n // and clean\" and \"couldn't check\" never look the same to a caller.\n ...(data.revoked === true ? { revoked: true, revocation_reason: data.revocation_reason } : {}),\n };\n}\n\n/** Keyless — used only by the free top-level `can()` export. Free Exchange artifacts answer\n * anonymously; a paid one throws NomosPaymentRequiredError, since there's no API key here to\n * check purchase/license ownership against. */\nasync function canViaExchange(authority: string, facts: Record<string, unknown>, action: string | undefined, opts?: CanOptions): Promise<CanResult> {\n const base = (opts?.baseUrl ?? DEFAULT_EXCHANGE_BASE).replace(/\\/$/, '');\n const url = `${base}/api/v1/can`;\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({ artifact: authority, action, ...facts }),\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) mapHttpError(res.status, data, requestId);\n return normalizeAuthorityQueryResult(data, authority);\n}\n\n/** Authenticated — used by `client.can({ authority })`. Same endpoint, same normalization, but\n * routed through the instance's own HttpClient so its API key rides along: a paid artifact the\n * caller has purchased or published now actually works, which the keyless rail structurally\n * cannot support (there is no key there to check ownership against). */\nasync function canViaExchangeAuthenticated(http: HttpClient, authority: string, facts: Record<string, unknown>, action: string | undefined): Promise<CanResult> {\n const { data } = await http.post<any>('/api/v1/can', { artifact: authority, action, ...facts });\n return normalizeAuthorityQueryResult(data, authority);\n}\n\n/** The authenticated-artifact rail — your own artifact, requires an API key (an authenticated\n * `Nomos` instance's HttpClient). Normalizes the engine's own response shape (approved/rejected/\n * escalated, an audit hash) into the SAME AUTHORIZED/DENIED/ESCALATED verdict shape the Exchange\n * rail returns, rather than leaking a second vocabulary out to the caller. */\nasync function canViaArtifact(http: HttpClient, artifactId: string, facts: Record<string, unknown>, action: string | undefined): Promise<CanResult> {\n const isPublic = artifactId.startsWith('pub_');\n const path = isPublic ? '/api/v1/verify' : '/api/v1/verify-decision';\n const body = isPublic\n ? { artifact_id: artifactId, decision: action ?? 'evaluate', inputs: facts }\n : { artifact_id: artifactId, decision: action ?? 'evaluate', inputs: facts, caller: { correlation_id: globalThis.crypto.randomUUID() } };\n\n // Note: CanOptions.signal has no effect here — HttpClient has no external abort-signal\n // passthrough anywhere in the SDK today (its own internal AbortController is timeout-only).\n // Pre-existing limitation, not introduced by this rail; not worth faking a parameter that\n // silently does nothing.\n const { data: raw } = await http.post<any>(path, body);\n\n const verdict: CanResult['verdict'] =\n raw.verdict === 'approved' ? 'AUTHORIZED'\n : raw.verdict === 'rejected' ? 'DENIED'\n : raw.outcome === 'auto_approved' ? 'AUTHORIZED'\n : raw.outcome === 'auto_rejected' ? 'DENIED'\n : 'ESCALATED';\n\n return {\n allowed: raw.allowed ?? verdict === 'AUTHORIZED',\n verdict,\n reason: raw.verdict_description ?? '',\n rule: raw.rule?.id ?? null,\n authority: {\n id: raw.artifact_id ?? artifactId,\n title: raw.artifact_name ?? '',\n standing: raw.confidence?.tier ?? '',\n },\n ...(raw.artifact_version ? { version: raw.artifact_version } : {}),\n missing_inputs: raw.incomplete_inputs?.fields ?? [],\n ...(raw.audit ? { audit: { hash: raw.audit.hash ?? raw.audit_hash ?? '', timestamp: raw.audit.timestamp ?? raw.ts ?? new Date().toISOString() } } : {}),\n // This rail's obligations are RuleEffect objects (authority-types.ts) — a richer, INTERNAL\n // shape ({ effect_type, value, provenance: { rule_id, rule_name } }), NOT the same shape the\n // Exchange rail already returns ({ kind, rule_id, rule_name }). Mapped explicitly here rather\n // than passed through raw — the two rails' server-side representations genuinely differ, and\n // assuming they matched would have been the actual bug.\n ...(Array.isArray(raw.obligations) && raw.obligations.length > 0\n ? { obligations: raw.obligations.map((o: any) => ({\n kind: o.kind ?? o.value ?? 'obligation',\n rule_id: o.rule_id ?? o.provenance?.rule_id ?? null,\n rule_name: o.rule_name ?? o.provenance?.rule_name ?? null,\n ...(o.reason ? { reason: o.reason } : {}),\n })) }\n : {}),\n };\n}\n\n/**\n * The chain-of-trust rail (PROTOTYPE, not a numbered spec). Keyless — works identically on the\n * free `can()` export and `client.can()`, since there's no account relationship to check here.\n * The server verifies the presented chain resolves to `root_public_key_pem` and, ONLY once that\n * succeeds, evaluates the artifact's own rules against `facts` — the same evaluator every other\n * rail uses (evaluateArtifactAgainstFacts, extracted from and proven identical to\n * /api/v1/verify-decision). An artifact whose chain doesn't resolve is never evaluated: this\n * throws NomosIssuerNotTrustedError instead of returning a verdict, because \"the rules say no\"\n * and \"we never established who's asking\" are different claims a caller needs to react to\n * differently — collapsing them into DENIED would tell the caller the wrong thing to do next.\n */\nasync function canViaChain(\n artifact: unknown, keyCerts: unknown, rootPublicKeyPem: string,\n facts: Record<string, unknown>, action: string | undefined, opts?: CanOptions,\n): Promise<CanResult> {\n const base = (opts?.baseUrl ?? DEFAULT_EXCHANGE_BASE).replace(/\\/$/, '');\n const url = `${base}/api/v1/chain-of-trust/verify`;\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({ version: CHAIN_PROTOCOL_VERSION, artifact, key_certs: keyCerts, root_public_key_pem: rootPublicKeyPem, 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\n if (data?.decision === 'AUTHORIZED' || data?.decision === 'DENIED' || data?.decision === 'ESCALATED') {\n return {\n allowed: data.decision === 'AUTHORIZED',\n verdict: data.decision,\n reason: data.reason ?? '',\n rule: data.rule ?? null,\n authority: { id: 'presented-artifact', title: '', standing: '' },\n // Read directly off the artifact the caller already has — no server round-trip needed for\n // data the caller is already holding.\n ...((artifact as any)?.meta?.version ? { version: (artifact as any).meta.version } : {}),\n missing_inputs: data.missing_inputs ?? [],\n ...(Array.isArray(data.obligations) && data.obligations.length > 0 ? { obligations: data.obligations } : {}),\n // Deliberately no query_id/url/audit — this evaluation is stateless by design (the whole\n // point is answering without NOMOS needing to have seen this artifact before); there is no\n // permanent transcript to point to, and faking one would misrepresent what just happened.\n };\n }\n\n // ALLOWED (facts were somehow not evaluated — shouldn't happen when facts are always sent, but\n // handled rather than assumed impossible), or one of the chain-failure decisions.\n const message: string = data?.detail ?? `Chain verification failed (HTTP ${res.status})`;\n if (data?.decision === 'ISSUER_NOT_RECOGNIZED' || data?.decision === 'KEY_REVOKED' || data?.decision === 'SEAL_INVALID' || data?.decision === 'ALLOWED') {\n throw new NomosIssuerNotTrustedError(message, data.decision, requestId);\n }\n if (data?.decision === 'MALFORMED') throw new NomosValidationError(message, data, requestId);\n mapHttpError(res.status, data, requestId);\n}\n\nexport async function can(params: CanParams, opts?: CanOptions): Promise<CanResult> {\n if (params.artifact !== undefined) {\n if (!params.key_certs || !params.root_public_key_pem) {\n throw new Error('can(): `artifact` requires `key_certs` and `root_public_key_pem` alongside it.');\n }\n const { facts, action } = splitFacts(params);\n return canViaChain(params.artifact, params.key_certs, params.root_public_key_pem, facts, action, opts);\n }\n if (params.artifact_id) {\n throw new Error('can(): `artifact_id` requires an API key — use `client.can(...)` on an authenticated Nomos instance, not the free `can()` export.');\n }\n if (!params.authority || typeof params.authority !== 'string') {\n throw new Error('can(): `authority` (an Exchange artifact id or slug), `artifact_id` (via client.can()), or `artifact` (chain-of-trust) is required.');\n }\n const { facts, action } = splitFacts(params);\n return canViaExchange(params.authority, facts, action, opts);\n}\n\n/** Shared implementation behind `Nomos.prototype.can()` — see nomos.ts. Exported so the class\n * stays a thin wrapper and this routing logic lives in exactly one place. */\nexport async function canAuthenticated(http: HttpClient, params: CanParams, opts?: CanOptions): Promise<CanResult> {\n void opts; // reserved — HttpClient has no external signal passthrough today, see canViaArtifact's note\n const { facts, action } = splitFacts(params);\n if (params.artifact !== undefined) {\n if (!params.key_certs || !params.root_public_key_pem) {\n throw new Error('can(): `artifact` requires `key_certs` and `root_public_key_pem` alongside it.');\n }\n // Keyless rail — an authenticated client is still free to use it, same server endpoint.\n return canViaChain(params.artifact, params.key_certs, params.root_public_key_pem, facts, action, opts);\n }\n if (params.artifact_id) return canViaArtifact(http, params.artifact_id, facts, action);\n if (params.authority) return canViaExchangeAuthenticated(http, params.authority, facts, action);\n throw new Error('can(): `authority` (a public Exchange artifact), `artifact_id` (your own artifact), or `artifact` (chain-of-trust) is required.');\n}\n\n/**\n * Ready-to-use, keyless entry point matching the canonical `nomos.can(...)` form.\n * For paid artifacts or your own artifacts, use `client.can(...)` on an authenticated `Nomos`\n * instance instead — same function name, same verdict shape, the only difference is which rail\n * answers and what it can unlock.\n */\nexport const nomos = { can };\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 { canAuthenticated } from './can.js';\nimport * as errors from './errors.js';\nimport type { NomosConfig, CanParams, CanOptions, CanResult } 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 private readonly http: HttpClient;\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 this.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(this.http);\n this.artifacts = new Artifacts(this.http);\n this.governance = new Governance(this.http);\n this.webhooks = new Webhooks();\n }\n\n /**\n * \"Can I do this?\" — the one verb, now covering your own artifacts too. Pass `authority` for a\n * public Exchange artifact, or `artifact_id` for your own (Studio or the Exchange) — same\n * return shape either way, so calling code never needs to know which rail answered.\n *\n * @example\n * const client = new Nomos('nms_live_...');\n * const verdict = await client.can({ artifact_id: 'loan_approval_v1', credit_score: 720 });\n */\n async can(params: CanParams, opts?: CanOptions): Promise<CanResult> {\n return canAuthenticated(this.http, params, opts);\n }\n}\n","import type { VerifyChainParams, VerifyChainOptions, VerifyChainResult } from './types.js';\nimport {\n NomosValidationError,\n NomosRateLimitError,\n NomosAPIError,\n NomosNetworkError,\n} from './errors.js';\n\nconst CHAIN_PROTOCOL_VERSION = '1';\nconst DEFAULT_BASE = 'https://www.nomosprotocol.com';\n\n/**\n * Chain-of-trust verification (PROTOTYPE — not a numbered spec). Checks whether a presented\n * artifact's signing key resolves, through the presented key certificates, back to a root you\n * have independently decided to trust — entirely server-side against nomos-chain.ts's pure\n * verifier, with no account or API key required (keyless, matching `nomos.can()`'s precedent).\n *\n * There is no default root anywhere in this call — `root_public_key_pem` is required. That's\n * deliberate: it keeps the trust decision with the caller, not with this SDK or the platform.\n *\n * @example\n * import { verifyChain } from '@nomosprotocol/sdk';\n *\n * const result = await verifyChain({\n * artifact: sealedArtifact,\n * key_certs: [rootToIntermediate, intermediateToLeaf],\n * root_public_key_pem: myPinnedRootPem,\n * });\n * if (result.decision === 'ALLOWED') { ... }\n */\nexport async function verifyChain(params: VerifyChainParams, opts?: VerifyChainOptions): Promise<VerifyChainResult> {\n if (!params.root_public_key_pem) {\n throw new Error('verifyChain(): `root_public_key_pem` is required — there is no default root.');\n }\n const base = (opts?.baseUrl ?? DEFAULT_BASE).replace(/\\/$/, '');\n const url = `${base}/api/v1/chain-of-trust/verify`;\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({\n version: CHAIN_PROTOCOL_VERSION,\n artifact: params.artifact,\n key_certs: params.key_certs,\n root_public_key_pem: params.root_public_key_pem,\n }),\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\n // 400/403/422 all carry a real ChainVerdict body (MALFORMED/ISSUER_NOT_RECOGNIZED/KEY_REVOKED/\n // SEAL_INVALID) — that's a verdict, not a transport failure, so it's returned, not thrown.\n if (data && typeof data.decision === 'string') {\n return data as VerifyChainResult;\n }\n\n const message: string = data?.error ?? `Chain verification request failed (HTTP ${res.status})`;\n if (res.status === 429) {\n throw new NomosRateLimitError(message, res.headers.get('retry-after') ? parseInt(res.headers.get('retry-after')!, 10) : undefined, requestId);\n }\n if (res.status === 400) throw new NomosValidationError(message, data?.details, requestId);\n throw new NomosAPIError(message, res.status, requestId);\n}\n"],"mappings":"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","names":["facts","action","CHAIN_PROTOCOL_VERSION"]}
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/can.ts","../src/nomos.ts","../src/verify-chain.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';\n// Chain-of-trust verification (PROTOTYPE, not a numbered spec) — also keyless, same reasoning\n// as `can()`: verification itself should never require an account.\nexport { verifyChain } from './verify-chain.js';\nexport * from './errors.js';\nexport type {\n CanParams,\n CanOptions,\n CanResult,\n CanVerdict,\n AttestationInfo,\n NomosConfig,\n RequestOptions,\n NomosRawResponse,\n WithLastResponse,\n VerifyDecisionParams,\n VerifyDecisionResult,\n VerifyChainParams,\n VerifyChainOptions,\n VerifyChainResult,\n ChainVerdictDecision,\n KeyCertificate,\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 | 'payment_required'\n | 'issuer_not_trusted';\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\n/** can() asked about a paid authority the caller hasn't purchased or licensed. Distinct from a\n * generic 403 on purpose: this isn't \"you're not allowed,\" it's \"here's exactly what unlocks\n * it\" — price and a URL to complete the purchase. NOMOS never auto-charges on your behalf;\n * this is the seam where a caller decides to buy, not where a payment silently happens. */\nexport class NomosPaymentRequiredError extends NomosError {\n readonly priceUsd: number;\n readonly purchaseUrl: string;\n\n constructor(message: string, priceUsd: number, purchaseUrl: string, requestId?: string) {\n super(message, 'payment_required', 402, requestId);\n this.name = 'NomosPaymentRequiredError';\n this.priceUsd = priceUsd;\n this.purchaseUrl = purchaseUrl;\n }\n}\n\n/** can()'s chain-of-trust rail could not establish that the presented artifact carries authority\n * it is entitled to — an unrecognized issuer, a revoked key, a delegation that never covered\n * this artifact, a tampered seal, or a malformed presentation. This is deliberately NOT a DENIED\n * verdict: \"the rules say no\" and \"we never got far enough to ask the rules anything\" are\n * different claims, and collapsing them would tell the caller the wrong thing to do next.\n *\n * `reason` carries the underlying chain decision so callers can distinguish them, because the\n * right next action genuinely differs:\n * ISSUER_NOT_RECOGNIZED — presenting a more complete chain may fix this\n * KEY_REVOKED — that key is dead; a different, unrevoked chain might work\n * CERTIFICATE_REVOKED — one delegation was withdrawn; another certificate for the same\n * key may still resolve\n * OUT_OF_SCOPE — the issuer IS recognized but was not delegated authority over this\n * artifact; only a broader (validly issued) delegation fixes it\n * SEAL_INVALID — the artifact itself was altered; nothing about presentation helps\n * MALFORMED — the request shape was wrong (a client-side bug) */\nexport class NomosIssuerNotTrustedError extends NomosError {\n readonly reason: string;\n\n constructor(message: string, reason: string, requestId?: string) {\n super(message, 'issuer_not_trusted', 403, requestId);\n this.name = 'NomosIssuerNotTrustedError';\n this.reason = reason;\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 type { CanParams, CanResult, CanOptions } from './types.js';\nimport type { HttpClient } from './http-client.js';\nimport {\n NomosAuthenticationError,\n NomosAuthorizationError,\n NomosRateLimitError,\n NomosValidationError,\n NomosNotFoundError,\n NomosAPIError,\n NomosNetworkError,\n NomosPaymentRequiredError,\n NomosIssuerNotTrustedError,\n} from './errors.js';\n\nconst CHAIN_PROTOCOL_VERSION = '1';\n\n/**\n * The whole product in one verb: \"Can I do this?\"\n *\n * Same pattern as Stripe's PaymentIntents API: one function, several rails underneath (a public\n * Exchange authority — free or paid — or your own authenticated artifact), and the caller never\n * has to know which one ran. Don't read `can()` as \"the Exchange's query function\" — the\n * Exchange is one of two rails behind it, not what it means.\n *\n * Both rails call into the SAME server-side implementation NOMOS itself uses (POST /api/v1/can,\n * backed by authority-query.ts's runAuthorityQuery) — not a parallel path, so there is exactly\n * one place that can drift between \"what the SDK returns\" and \"what NOMOS actually decided.\"\n *\n * Verdicts are always AUTHORIZED / DENIED / ESCALATED, normalized into that one vocabulary\n * regardless of which rail answered. `allowed` is simply `verdict === 'AUTHORIZED'`; an\n * ESCALATED result means the authority needs more facts to decide (see `missing_inputs`), not a\n * flat \"no\". A paid Exchange artifact you haven't purchased throws NomosPaymentRequiredError —\n * with the price and a purchase URL attached — rather than a generic 403 or a silent failure.\n * NOMOS never auto-charges on your behalf; this is the seam where a caller decides to buy.\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\nfunction splitFacts(params: CanParams): { facts: Record<string, unknown>; action: string | undefined } {\n const { authority, artifact_id, action, inputs, ...flat } = params;\n void authority; void artifact_id;\n // Two equally valid shapes: an explicit `inputs` object, or the facts spread flat\n // alongside `authority`/`artifact_id`/`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 return { facts, action };\n}\n\nfunction mapHttpError(status: number, data: any, requestId: string): never {\n const message: string = data?.error ?? data?.message ?? `NOMOS query failed (HTTP ${status})`;\n // Checked by CODE, not by the raw wire status (403) — this is \"here's what unlocks it,\" a\n // materially different thing for a caller to act on than \"you're not allowed at all.\"\n if (data?.code === 'PURCHASE_REQUIRED') {\n throw new NomosPaymentRequiredError(message, data.price_usd ?? 0, data.purchase_url ?? '', requestId);\n }\n switch (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(message, undefined, requestId);\n default: throw new NomosAPIError(message, status, requestId);\n }\n}\n\n/** Both Exchange-rail paths (keyless and authenticated) return the same underlying shape —\n * authority-query.ts's AuthorityQueryResult, spread with a few convenience fields by the\n * /api/v1/can route. One normalizer for both, so they can't quietly drift apart. */\nfunction normalizeAuthorityQueryResult(data: any, authority: string): CanResult {\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 ...(data.artifact?.attestation ? { attestation: data.artifact.attestation } : {}),\n },\n ...(data.artifact?.version ? { version: data.artifact.version } : {}),\n missing_inputs: data.missing_inputs ?? [],\n ...(typeof data.max_age === 'number' ? { max_age: data.max_age } : {}),\n // authority-query.ts already returns { kind, rule_id, rule_name } — the public-safe shape\n // CanResult uses directly.\n ...(Array.isArray(data.obligations) && data.obligations.length > 0 ? { obligations: data.obligations } : {}),\n // NOMOS-SPEC-006 — present only when the issuer has actually revoked this exact sealed\n // version; omitted (not false) when revocation doesn't structurally apply here, so \"checked\n // and clean\" and \"couldn't check\" never look the same to a caller.\n ...(data.revoked === true ? { revoked: true, revocation_reason: data.revocation_reason } : {}),\n };\n}\n\n/** Keyless — used only by the free top-level `can()` export. Free Exchange artifacts answer\n * anonymously; a paid one throws NomosPaymentRequiredError, since there's no API key here to\n * check purchase/license ownership against. */\nasync function canViaExchange(authority: string, facts: Record<string, unknown>, action: string | undefined, opts?: CanOptions): Promise<CanResult> {\n const base = (opts?.baseUrl ?? DEFAULT_EXCHANGE_BASE).replace(/\\/$/, '');\n const url = `${base}/api/v1/can`;\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({ artifact: authority, action, ...facts }),\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) mapHttpError(res.status, data, requestId);\n return normalizeAuthorityQueryResult(data, authority);\n}\n\n/** Authenticated — used by `client.can({ authority })`. Same endpoint, same normalization, but\n * routed through the instance's own HttpClient so its API key rides along: a paid artifact the\n * caller has purchased or published now actually works, which the keyless rail structurally\n * cannot support (there is no key there to check ownership against). */\nasync function canViaExchangeAuthenticated(http: HttpClient, authority: string, facts: Record<string, unknown>, action: string | undefined): Promise<CanResult> {\n const { data } = await http.post<any>('/api/v1/can', { artifact: authority, action, ...facts });\n return normalizeAuthorityQueryResult(data, authority);\n}\n\n/** The authenticated-artifact rail — your own artifact, requires an API key (an authenticated\n * `Nomos` instance's HttpClient). Normalizes the engine's own response shape (approved/rejected/\n * escalated, an audit hash) into the SAME AUTHORIZED/DENIED/ESCALATED verdict shape the Exchange\n * rail returns, rather than leaking a second vocabulary out to the caller. */\nasync function canViaArtifact(http: HttpClient, artifactId: string, facts: Record<string, unknown>, action: string | undefined): Promise<CanResult> {\n const isPublic = artifactId.startsWith('pub_');\n const path = isPublic ? '/api/v1/verify' : '/api/v1/verify-decision';\n const body = isPublic\n ? { artifact_id: artifactId, decision: action ?? 'evaluate', inputs: facts }\n : { artifact_id: artifactId, decision: action ?? 'evaluate', inputs: facts, caller: { correlation_id: globalThis.crypto.randomUUID() } };\n\n // Note: CanOptions.signal has no effect here — HttpClient has no external abort-signal\n // passthrough anywhere in the SDK today (its own internal AbortController is timeout-only).\n // Pre-existing limitation, not introduced by this rail; not worth faking a parameter that\n // silently does nothing.\n const { data: raw } = await http.post<any>(path, body);\n\n const verdict: CanResult['verdict'] =\n raw.verdict === 'approved' ? 'AUTHORIZED'\n : raw.verdict === 'rejected' ? 'DENIED'\n : raw.outcome === 'auto_approved' ? 'AUTHORIZED'\n : raw.outcome === 'auto_rejected' ? 'DENIED'\n : 'ESCALATED';\n\n return {\n allowed: raw.allowed ?? verdict === 'AUTHORIZED',\n verdict,\n reason: raw.verdict_description ?? '',\n rule: raw.rule?.id ?? null,\n authority: {\n id: raw.artifact_id ?? artifactId,\n title: raw.artifact_name ?? '',\n standing: raw.confidence?.tier ?? '',\n },\n ...(raw.artifact_version ? { version: raw.artifact_version } : {}),\n missing_inputs: raw.incomplete_inputs?.fields ?? [],\n ...(raw.audit ? { audit: { hash: raw.audit.hash ?? raw.audit_hash ?? '', timestamp: raw.audit.timestamp ?? raw.ts ?? new Date().toISOString() } } : {}),\n // This rail's obligations are RuleEffect objects (authority-types.ts) — a richer, INTERNAL\n // shape ({ effect_type, value, provenance: { rule_id, rule_name } }), NOT the same shape the\n // Exchange rail already returns ({ kind, rule_id, rule_name }). Mapped explicitly here rather\n // than passed through raw — the two rails' server-side representations genuinely differ, and\n // assuming they matched would have been the actual bug.\n ...(Array.isArray(raw.obligations) && raw.obligations.length > 0\n ? { obligations: raw.obligations.map((o: any) => ({\n kind: o.kind ?? o.value ?? 'obligation',\n rule_id: o.rule_id ?? o.provenance?.rule_id ?? null,\n rule_name: o.rule_name ?? o.provenance?.rule_name ?? null,\n ...(o.reason ? { reason: o.reason } : {}),\n })) }\n : {}),\n };\n}\n\n/**\n * The chain-of-trust rail (PROTOTYPE, not a numbered spec). Keyless — works identically on the\n * free `can()` export and `client.can()`, since there's no account relationship to check here.\n * The server verifies the presented chain resolves to `root_public_key_pem` and, ONLY once that\n * succeeds, evaluates the artifact's own rules against `facts` — the same evaluator every other\n * rail uses (evaluateArtifactAgainstFacts, extracted from and proven identical to\n * /api/v1/verify-decision). An artifact whose chain doesn't resolve is never evaluated: this\n * throws NomosIssuerNotTrustedError instead of returning a verdict, because \"the rules say no\"\n * and \"we never established who's asking\" are different claims a caller needs to react to\n * differently — collapsing them into DENIED would tell the caller the wrong thing to do next.\n */\nasync function canViaChain(\n artifact: unknown, keyCerts: unknown, rootPublicKeyPem: string,\n facts: Record<string, unknown>, action: string | undefined, opts?: CanOptions,\n): Promise<CanResult> {\n const base = (opts?.baseUrl ?? DEFAULT_EXCHANGE_BASE).replace(/\\/$/, '');\n const url = `${base}/api/v1/chain-of-trust/verify`;\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({ version: CHAIN_PROTOCOL_VERSION, artifact, key_certs: keyCerts, root_public_key_pem: rootPublicKeyPem, 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\n if (data?.decision === 'AUTHORIZED' || data?.decision === 'DENIED' || data?.decision === 'ESCALATED') {\n return {\n allowed: data.decision === 'AUTHORIZED',\n verdict: data.decision,\n reason: data.reason ?? '',\n rule: data.rule ?? null,\n authority: { id: 'presented-artifact', title: '', standing: '' },\n // Read directly off the artifact the caller already has — no server round-trip needed for\n // data the caller is already holding.\n ...((artifact as any)?.meta?.version ? { version: (artifact as any).meta.version } : {}),\n missing_inputs: data.missing_inputs ?? [],\n ...(Array.isArray(data.obligations) && data.obligations.length > 0 ? { obligations: data.obligations } : {}),\n // §5.5 — composing to a real permission decision must not silently drop the chain's own\n // revocation-confidence disclosure; the server already threads this through, so forward it.\n ...(data.revocation_checked ? { revocation_checked: data.revocation_checked } : {}),\n // Deliberately no query_id/url/audit — this evaluation is stateless by design (the whole\n // point is answering without NOMOS needing to have seen this artifact before); there is no\n // permanent transcript to point to, and faking one would misrepresent what just happened.\n };\n }\n\n // ALLOWED (facts were somehow not evaluated — shouldn't happen when facts are always sent, but\n // handled rather than assumed impossible), or one of the chain-failure decisions.\n const message: string = data?.detail ?? `Chain verification failed (HTTP ${res.status})`;\n if (data?.decision === 'ISSUER_NOT_RECOGNIZED' || data?.decision === 'KEY_REVOKED' || data?.decision === 'CERTIFICATE_REVOKED' || data?.decision === 'OUT_OF_SCOPE' || data?.decision === 'SEAL_INVALID' || data?.decision === 'ALLOWED') {\n throw new NomosIssuerNotTrustedError(message, data.decision, requestId);\n }\n if (data?.decision === 'MALFORMED') throw new NomosValidationError(message, data, requestId);\n mapHttpError(res.status, data, requestId);\n}\n\nexport async function can(params: CanParams, opts?: CanOptions): Promise<CanResult> {\n if (params.artifact !== undefined) {\n if (!params.key_certs || !params.root_public_key_pem) {\n throw new Error('can(): `artifact` requires `key_certs` and `root_public_key_pem` alongside it.');\n }\n const { facts, action } = splitFacts(params);\n return canViaChain(params.artifact, params.key_certs, params.root_public_key_pem, facts, action, opts);\n }\n if (params.artifact_id) {\n throw new Error('can(): `artifact_id` requires an API key — use `client.can(...)` on an authenticated Nomos instance, not the free `can()` export.');\n }\n if (!params.authority || typeof params.authority !== 'string') {\n throw new Error('can(): `authority` (an Exchange artifact id or slug), `artifact_id` (via client.can()), or `artifact` (chain-of-trust) is required.');\n }\n const { facts, action } = splitFacts(params);\n return canViaExchange(params.authority, facts, action, opts);\n}\n\n/** Shared implementation behind `Nomos.prototype.can()` — see nomos.ts. Exported so the class\n * stays a thin wrapper and this routing logic lives in exactly one place. */\nexport async function canAuthenticated(http: HttpClient, params: CanParams, opts?: CanOptions): Promise<CanResult> {\n void opts; // reserved — HttpClient has no external signal passthrough today, see canViaArtifact's note\n const { facts, action } = splitFacts(params);\n if (params.artifact !== undefined) {\n if (!params.key_certs || !params.root_public_key_pem) {\n throw new Error('can(): `artifact` requires `key_certs` and `root_public_key_pem` alongside it.');\n }\n // Keyless rail — an authenticated client is still free to use it, same server endpoint.\n return canViaChain(params.artifact, params.key_certs, params.root_public_key_pem, facts, action, opts);\n }\n if (params.artifact_id) return canViaArtifact(http, params.artifact_id, facts, action);\n if (params.authority) return canViaExchangeAuthenticated(http, params.authority, facts, action);\n throw new Error('can(): `authority` (a public Exchange artifact), `artifact_id` (your own artifact), or `artifact` (chain-of-trust) is required.');\n}\n\n/**\n * Ready-to-use, keyless entry point matching the canonical `nomos.can(...)` form.\n * For paid artifacts or your own artifacts, use `client.can(...)` on an authenticated `Nomos`\n * instance instead — same function name, same verdict shape, the only difference is which rail\n * answers and what it can unlock.\n */\nexport const nomos = { can };\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 { canAuthenticated } from './can.js';\nimport * as errors from './errors.js';\nimport type { NomosConfig, CanParams, CanOptions, CanResult } 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 private readonly http: HttpClient;\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 this.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(this.http);\n this.artifacts = new Artifacts(this.http);\n this.governance = new Governance(this.http);\n this.webhooks = new Webhooks();\n }\n\n /**\n * \"Can I do this?\" — the one verb, now covering your own artifacts too. Pass `authority` for a\n * public Exchange artifact, or `artifact_id` for your own (Studio or the Exchange) — same\n * return shape either way, so calling code never needs to know which rail answered.\n *\n * @example\n * const client = new Nomos('nms_live_...');\n * const verdict = await client.can({ artifact_id: 'loan_approval_v1', credit_score: 720 });\n */\n async can(params: CanParams, opts?: CanOptions): Promise<CanResult> {\n return canAuthenticated(this.http, params, opts);\n }\n}\n","import type { VerifyChainParams, VerifyChainOptions, VerifyChainResult } from './types.js';\nimport {\n NomosValidationError,\n NomosRateLimitError,\n NomosAPIError,\n NomosNetworkError,\n} from './errors.js';\n\nconst CHAIN_PROTOCOL_VERSION = '1';\nconst DEFAULT_BASE = 'https://www.nomosprotocol.com';\n\n/**\n * Chain-of-trust verification (PROTOTYPE — not a numbered spec). Checks whether a presented\n * artifact's signing key resolves, through the presented key certificates, back to a root you\n * have independently decided to trust — entirely server-side against nomos-chain.ts's pure\n * verifier, with no account or API key required (keyless, matching `nomos.can()`'s precedent).\n *\n * There is no default root anywhere in this call — `root_public_key_pem` is required. That's\n * deliberate: it keeps the trust decision with the caller, not with this SDK or the platform.\n *\n * @example\n * import { verifyChain } from '@nomosprotocol/sdk';\n *\n * const result = await verifyChain({\n * artifact: sealedArtifact,\n * key_certs: [rootToIntermediate, intermediateToLeaf],\n * root_public_key_pem: myPinnedRootPem,\n * });\n * if (result.decision === 'ALLOWED') { ... }\n */\nexport async function verifyChain(params: VerifyChainParams, opts?: VerifyChainOptions): Promise<VerifyChainResult> {\n if (!params.root_public_key_pem) {\n throw new Error('verifyChain(): `root_public_key_pem` is required — there is no default root.');\n }\n const base = (opts?.baseUrl ?? DEFAULT_BASE).replace(/\\/$/, '');\n const url = `${base}/api/v1/chain-of-trust/verify`;\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({\n version: CHAIN_PROTOCOL_VERSION,\n artifact: params.artifact,\n key_certs: params.key_certs,\n root_public_key_pem: params.root_public_key_pem,\n }),\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\n // 400/403/422 all carry a real ChainVerdict body (MALFORMED/ISSUER_NOT_RECOGNIZED/KEY_REVOKED/\n // SEAL_INVALID) — that's a verdict, not a transport failure, so it's returned, not thrown.\n if (data && typeof data.decision === 'string') {\n return data as VerifyChainResult;\n }\n\n const message: string = data?.error ?? `Chain verification request failed (HTTP ${res.status})`;\n if (res.status === 429) {\n throw new NomosRateLimitError(message, res.headers.get('retry-after') ? parseInt(res.headers.get('retry-after')!, 10) : undefined, requestId);\n }\n if (res.status === 400) throw new NomosValidationError(message, data?.details, requestId);\n throw new NomosAPIError(message, res.status, requestId);\n}\n"],"mappings":"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","names":["facts","action","CHAIN_PROTOCOL_VERSION"]}
package/dist/index.d.cts CHANGED
@@ -143,8 +143,15 @@ interface CanResult {
143
143
  revoked?: boolean;
144
144
  /** Present only alongside `revoked: true` — the issuer's stated reason. */
145
145
  revocation_reason?: string;
146
- }
147
- type ChainVerdictDecision = 'ALLOWED' | 'ISSUER_NOT_RECOGNIZED' | 'KEY_REVOKED' | 'SEAL_INVALID' | 'MALFORMED';
146
+ /** NOMOS-SPEC-007 §5.5 — chain-of-trust rail only. How confidently the chain's own KEY
147
+ * revocation was checked: `"live"` (checked against a real revocation source — always the
148
+ * case on this hosted deployment), `"staple"` (a presenter-supplied freshness staple was
149
+ * used instead — never happens here, since this endpoint always holds its own list), or
150
+ * `"unchecked"` (neither — e.g. the pinned root, which nothing else can vouch for). Omitted
151
+ * (not a guess) on the Exchange/private-artifact rails, where this concept doesn't apply. */
152
+ revocation_checked?: 'live' | 'staple' | 'unchecked';
153
+ }
154
+ type ChainVerdictDecision = 'ALLOWED' | 'ISSUER_NOT_RECOGNIZED' | 'KEY_REVOKED' | 'CERTIFICATE_REVOKED' | 'OUT_OF_SCOPE' | 'SEAL_INVALID' | 'MALFORMED';
148
155
  interface KeyCertificate {
149
156
  parent_kid: string;
150
157
  child_kid: string;
@@ -179,6 +186,15 @@ interface VerifyChainResult {
179
186
  reason?: string;
180
187
  /** Present only when decision === 'KEY_REVOKED'. */
181
188
  revoked_kid?: string;
189
+ /** Present only when decision === 'CERTIFICATE_REVOKED'. */
190
+ revoked_fingerprint?: string;
191
+ /** Present only when decision === 'OUT_OF_SCOPE' — which scope dimension failed. */
192
+ dimension?: string;
193
+ /** Present on ALLOWED and OUT_OF_SCOPE — the resolved chain's accumulated scope. */
194
+ effective_scope?: string;
195
+ /** Present only when decision === 'ALLOWED' (NOMOS-SPEC-007 §5.5). See CanResult's field of
196
+ * the same name for the full tri-state explanation. */
197
+ revocation_checked?: 'live' | 'staple' | 'unchecked';
182
198
  /** Human-readable detail for any non-ALLOWED decision. */
183
199
  detail?: string;
184
200
  }
@@ -551,14 +567,22 @@ declare class NomosPaymentRequiredError extends NomosError {
551
567
  readonly purchaseUrl: string;
552
568
  constructor(message: string, priceUsd: number, purchaseUrl: string, requestId?: string);
553
569
  }
554
- /** can()'s chain-of-trust rail couldn't establish that the presented artifact is trustworthy —
555
- * an unrecognized issuer, a revoked key, a tampered seal, or a malformed presentation. This is
556
- * deliberately NOT a DENIED verdict: "the rules say no" and "we never got far enough to ask the
557
- * rules anything" are different claims, and collapsing them would tell the caller the wrong
558
- * thing to do next (re-presenting a better chain can fix the first case; it can never fix a
559
- * genuinely tampered artifact). `reason` is the underlying chain decision
560
- * (ISSUER_NOT_RECOGNIZED / KEY_REVOKED / SEAL_INVALID / MALFORMED) for callers that need to
561
- * distinguish them. */
570
+ /** can()'s chain-of-trust rail could not establish that the presented artifact carries authority
571
+ * it is entitled to — an unrecognized issuer, a revoked key, a delegation that never covered
572
+ * this artifact, a tampered seal, or a malformed presentation. This is deliberately NOT a DENIED
573
+ * verdict: "the rules say no" and "we never got far enough to ask the rules anything" are
574
+ * different claims, and collapsing them would tell the caller the wrong thing to do next.
575
+ *
576
+ * `reason` carries the underlying chain decision so callers can distinguish them, because the
577
+ * right next action genuinely differs:
578
+ * ISSUER_NOT_RECOGNIZED — presenting a more complete chain may fix this
579
+ * KEY_REVOKED — that key is dead; a different, unrevoked chain might work
580
+ * CERTIFICATE_REVOKED — one delegation was withdrawn; another certificate for the same
581
+ * key may still resolve
582
+ * OUT_OF_SCOPE — the issuer IS recognized but was not delegated authority over this
583
+ * artifact; only a broader (validly issued) delegation fixes it
584
+ * SEAL_INVALID — the artifact itself was altered; nothing about presentation helps
585
+ * MALFORMED — the request shape was wrong (a client-side bug) */
562
586
  declare class NomosIssuerNotTrustedError extends NomosError {
563
587
  readonly reason: string;
564
588
  constructor(message: string, reason: string, requestId?: string);
package/dist/index.d.ts CHANGED
@@ -143,8 +143,15 @@ interface CanResult {
143
143
  revoked?: boolean;
144
144
  /** Present only alongside `revoked: true` — the issuer's stated reason. */
145
145
  revocation_reason?: string;
146
- }
147
- type ChainVerdictDecision = 'ALLOWED' | 'ISSUER_NOT_RECOGNIZED' | 'KEY_REVOKED' | 'SEAL_INVALID' | 'MALFORMED';
146
+ /** NOMOS-SPEC-007 §5.5 — chain-of-trust rail only. How confidently the chain's own KEY
147
+ * revocation was checked: `"live"` (checked against a real revocation source — always the
148
+ * case on this hosted deployment), `"staple"` (a presenter-supplied freshness staple was
149
+ * used instead — never happens here, since this endpoint always holds its own list), or
150
+ * `"unchecked"` (neither — e.g. the pinned root, which nothing else can vouch for). Omitted
151
+ * (not a guess) on the Exchange/private-artifact rails, where this concept doesn't apply. */
152
+ revocation_checked?: 'live' | 'staple' | 'unchecked';
153
+ }
154
+ type ChainVerdictDecision = 'ALLOWED' | 'ISSUER_NOT_RECOGNIZED' | 'KEY_REVOKED' | 'CERTIFICATE_REVOKED' | 'OUT_OF_SCOPE' | 'SEAL_INVALID' | 'MALFORMED';
148
155
  interface KeyCertificate {
149
156
  parent_kid: string;
150
157
  child_kid: string;
@@ -179,6 +186,15 @@ interface VerifyChainResult {
179
186
  reason?: string;
180
187
  /** Present only when decision === 'KEY_REVOKED'. */
181
188
  revoked_kid?: string;
189
+ /** Present only when decision === 'CERTIFICATE_REVOKED'. */
190
+ revoked_fingerprint?: string;
191
+ /** Present only when decision === 'OUT_OF_SCOPE' — which scope dimension failed. */
192
+ dimension?: string;
193
+ /** Present on ALLOWED and OUT_OF_SCOPE — the resolved chain's accumulated scope. */
194
+ effective_scope?: string;
195
+ /** Present only when decision === 'ALLOWED' (NOMOS-SPEC-007 §5.5). See CanResult's field of
196
+ * the same name for the full tri-state explanation. */
197
+ revocation_checked?: 'live' | 'staple' | 'unchecked';
182
198
  /** Human-readable detail for any non-ALLOWED decision. */
183
199
  detail?: string;
184
200
  }
@@ -551,14 +567,22 @@ declare class NomosPaymentRequiredError extends NomosError {
551
567
  readonly purchaseUrl: string;
552
568
  constructor(message: string, priceUsd: number, purchaseUrl: string, requestId?: string);
553
569
  }
554
- /** can()'s chain-of-trust rail couldn't establish that the presented artifact is trustworthy —
555
- * an unrecognized issuer, a revoked key, a tampered seal, or a malformed presentation. This is
556
- * deliberately NOT a DENIED verdict: "the rules say no" and "we never got far enough to ask the
557
- * rules anything" are different claims, and collapsing them would tell the caller the wrong
558
- * thing to do next (re-presenting a better chain can fix the first case; it can never fix a
559
- * genuinely tampered artifact). `reason` is the underlying chain decision
560
- * (ISSUER_NOT_RECOGNIZED / KEY_REVOKED / SEAL_INVALID / MALFORMED) for callers that need to
561
- * distinguish them. */
570
+ /** can()'s chain-of-trust rail could not establish that the presented artifact carries authority
571
+ * it is entitled to — an unrecognized issuer, a revoked key, a delegation that never covered
572
+ * this artifact, a tampered seal, or a malformed presentation. This is deliberately NOT a DENIED
573
+ * verdict: "the rules say no" and "we never got far enough to ask the rules anything" are
574
+ * different claims, and collapsing them would tell the caller the wrong thing to do next.
575
+ *
576
+ * `reason` carries the underlying chain decision so callers can distinguish them, because the
577
+ * right next action genuinely differs:
578
+ * ISSUER_NOT_RECOGNIZED — presenting a more complete chain may fix this
579
+ * KEY_REVOKED — that key is dead; a different, unrevoked chain might work
580
+ * CERTIFICATE_REVOKED — one delegation was withdrawn; another certificate for the same
581
+ * key may still resolve
582
+ * OUT_OF_SCOPE — the issuer IS recognized but was not delegated authority over this
583
+ * artifact; only a broader (validly issued) delegation fixes it
584
+ * SEAL_INVALID — the artifact itself was altered; nothing about presentation helps
585
+ * MALFORMED — the request shape was wrong (a client-side bug) */
562
586
  declare class NomosIssuerNotTrustedError extends NomosError {
563
587
  readonly reason: string;
564
588
  constructor(message: string, reason: string, requestId?: string);
package/dist/index.js CHANGED
@@ -653,14 +653,17 @@ async function canViaChain(artifact, keyCerts, rootPublicKeyPem, facts, action,
653
653
  // data the caller is already holding.
654
654
  ...artifact?.meta?.version ? { version: artifact.meta.version } : {},
655
655
  missing_inputs: data.missing_inputs ?? [],
656
- ...Array.isArray(data.obligations) && data.obligations.length > 0 ? { obligations: data.obligations } : {}
656
+ ...Array.isArray(data.obligations) && data.obligations.length > 0 ? { obligations: data.obligations } : {},
657
+ // §5.5 — composing to a real permission decision must not silently drop the chain's own
658
+ // revocation-confidence disclosure; the server already threads this through, so forward it.
659
+ ...data.revocation_checked ? { revocation_checked: data.revocation_checked } : {}
657
660
  // Deliberately no query_id/url/audit — this evaluation is stateless by design (the whole
658
661
  // point is answering without NOMOS needing to have seen this artifact before); there is no
659
662
  // permanent transcript to point to, and faking one would misrepresent what just happened.
660
663
  };
661
664
  }
662
665
  const message = data?.detail ?? `Chain verification failed (HTTP ${res.status})`;
663
- if (data?.decision === "ISSUER_NOT_RECOGNIZED" || data?.decision === "KEY_REVOKED" || data?.decision === "SEAL_INVALID" || data?.decision === "ALLOWED") {
666
+ if (data?.decision === "ISSUER_NOT_RECOGNIZED" || data?.decision === "KEY_REVOKED" || data?.decision === "CERTIFICATE_REVOKED" || data?.decision === "OUT_OF_SCOPE" || data?.decision === "SEAL_INVALID" || data?.decision === "ALLOWED") {
664
667
  throw new NomosIssuerNotTrustedError(message, data.decision, requestId);
665
668
  }
666
669
  if (data?.decision === "MALFORMED") throw new NomosValidationError(message, data, requestId);
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/can.ts","../src/nomos.ts","../src/verify-chain.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 | 'payment_required'\n | 'issuer_not_trusted';\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\n/** can() asked about a paid authority the caller hasn't purchased or licensed. Distinct from a\n * generic 403 on purpose: this isn't \"you're not allowed,\" it's \"here's exactly what unlocks\n * it\" — price and a URL to complete the purchase. NOMOS never auto-charges on your behalf;\n * this is the seam where a caller decides to buy, not where a payment silently happens. */\nexport class NomosPaymentRequiredError extends NomosError {\n readonly priceUsd: number;\n readonly purchaseUrl: string;\n\n constructor(message: string, priceUsd: number, purchaseUrl: string, requestId?: string) {\n super(message, 'payment_required', 402, requestId);\n this.name = 'NomosPaymentRequiredError';\n this.priceUsd = priceUsd;\n this.purchaseUrl = purchaseUrl;\n }\n}\n\n/** can()'s chain-of-trust rail couldn't establish that the presented artifact is trustworthy —\n * an unrecognized issuer, a revoked key, a tampered seal, or a malformed presentation. This is\n * deliberately NOT a DENIED verdict: \"the rules say no\" and \"we never got far enough to ask the\n * rules anything\" are different claims, and collapsing them would tell the caller the wrong\n * thing to do next (re-presenting a better chain can fix the first case; it can never fix a\n * genuinely tampered artifact). `reason` is the underlying chain decision\n * (ISSUER_NOT_RECOGNIZED / KEY_REVOKED / SEAL_INVALID / MALFORMED) for callers that need to\n * distinguish them. */\nexport class NomosIssuerNotTrustedError extends NomosError {\n readonly reason: string;\n\n constructor(message: string, reason: string, requestId?: string) {\n super(message, 'issuer_not_trusted', 403, requestId);\n this.name = 'NomosIssuerNotTrustedError';\n this.reason = reason;\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 type { CanParams, CanResult, CanOptions } from './types.js';\nimport type { HttpClient } from './http-client.js';\nimport {\n NomosAuthenticationError,\n NomosAuthorizationError,\n NomosRateLimitError,\n NomosValidationError,\n NomosNotFoundError,\n NomosAPIError,\n NomosNetworkError,\n NomosPaymentRequiredError,\n NomosIssuerNotTrustedError,\n} from './errors.js';\n\nconst CHAIN_PROTOCOL_VERSION = '1';\n\n/**\n * The whole product in one verb: \"Can I do this?\"\n *\n * Same pattern as Stripe's PaymentIntents API: one function, several rails underneath (a public\n * Exchange authority — free or paid — or your own authenticated artifact), and the caller never\n * has to know which one ran. Don't read `can()` as \"the Exchange's query function\" — the\n * Exchange is one of two rails behind it, not what it means.\n *\n * Both rails call into the SAME server-side implementation NOMOS itself uses (POST /api/v1/can,\n * backed by authority-query.ts's runAuthorityQuery) — not a parallel path, so there is exactly\n * one place that can drift between \"what the SDK returns\" and \"what NOMOS actually decided.\"\n *\n * Verdicts are always AUTHORIZED / DENIED / ESCALATED, normalized into that one vocabulary\n * regardless of which rail answered. `allowed` is simply `verdict === 'AUTHORIZED'`; an\n * ESCALATED result means the authority needs more facts to decide (see `missing_inputs`), not a\n * flat \"no\". A paid Exchange artifact you haven't purchased throws NomosPaymentRequiredError —\n * with the price and a purchase URL attached — rather than a generic 403 or a silent failure.\n * NOMOS never auto-charges on your behalf; this is the seam where a caller decides to buy.\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\nfunction splitFacts(params: CanParams): { facts: Record<string, unknown>; action: string | undefined } {\n const { authority, artifact_id, action, inputs, ...flat } = params;\n void authority; void artifact_id;\n // Two equally valid shapes: an explicit `inputs` object, or the facts spread flat\n // alongside `authority`/`artifact_id`/`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 return { facts, action };\n}\n\nfunction mapHttpError(status: number, data: any, requestId: string): never {\n const message: string = data?.error ?? data?.message ?? `NOMOS query failed (HTTP ${status})`;\n // Checked by CODE, not by the raw wire status (403) — this is \"here's what unlocks it,\" a\n // materially different thing for a caller to act on than \"you're not allowed at all.\"\n if (data?.code === 'PURCHASE_REQUIRED') {\n throw new NomosPaymentRequiredError(message, data.price_usd ?? 0, data.purchase_url ?? '', requestId);\n }\n switch (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(message, undefined, requestId);\n default: throw new NomosAPIError(message, status, requestId);\n }\n}\n\n/** Both Exchange-rail paths (keyless and authenticated) return the same underlying shape —\n * authority-query.ts's AuthorityQueryResult, spread with a few convenience fields by the\n * /api/v1/can route. One normalizer for both, so they can't quietly drift apart. */\nfunction normalizeAuthorityQueryResult(data: any, authority: string): CanResult {\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 ...(data.artifact?.attestation ? { attestation: data.artifact.attestation } : {}),\n },\n ...(data.artifact?.version ? { version: data.artifact.version } : {}),\n missing_inputs: data.missing_inputs ?? [],\n ...(typeof data.max_age === 'number' ? { max_age: data.max_age } : {}),\n // authority-query.ts already returns { kind, rule_id, rule_name } — the public-safe shape\n // CanResult uses directly.\n ...(Array.isArray(data.obligations) && data.obligations.length > 0 ? { obligations: data.obligations } : {}),\n // NOMOS-SPEC-006 — present only when the issuer has actually revoked this exact sealed\n // version; omitted (not false) when revocation doesn't structurally apply here, so \"checked\n // and clean\" and \"couldn't check\" never look the same to a caller.\n ...(data.revoked === true ? { revoked: true, revocation_reason: data.revocation_reason } : {}),\n };\n}\n\n/** Keyless — used only by the free top-level `can()` export. Free Exchange artifacts answer\n * anonymously; a paid one throws NomosPaymentRequiredError, since there's no API key here to\n * check purchase/license ownership against. */\nasync function canViaExchange(authority: string, facts: Record<string, unknown>, action: string | undefined, opts?: CanOptions): Promise<CanResult> {\n const base = (opts?.baseUrl ?? DEFAULT_EXCHANGE_BASE).replace(/\\/$/, '');\n const url = `${base}/api/v1/can`;\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({ artifact: authority, action, ...facts }),\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) mapHttpError(res.status, data, requestId);\n return normalizeAuthorityQueryResult(data, authority);\n}\n\n/** Authenticated — used by `client.can({ authority })`. Same endpoint, same normalization, but\n * routed through the instance's own HttpClient so its API key rides along: a paid artifact the\n * caller has purchased or published now actually works, which the keyless rail structurally\n * cannot support (there is no key there to check ownership against). */\nasync function canViaExchangeAuthenticated(http: HttpClient, authority: string, facts: Record<string, unknown>, action: string | undefined): Promise<CanResult> {\n const { data } = await http.post<any>('/api/v1/can', { artifact: authority, action, ...facts });\n return normalizeAuthorityQueryResult(data, authority);\n}\n\n/** The authenticated-artifact rail — your own artifact, requires an API key (an authenticated\n * `Nomos` instance's HttpClient). Normalizes the engine's own response shape (approved/rejected/\n * escalated, an audit hash) into the SAME AUTHORIZED/DENIED/ESCALATED verdict shape the Exchange\n * rail returns, rather than leaking a second vocabulary out to the caller. */\nasync function canViaArtifact(http: HttpClient, artifactId: string, facts: Record<string, unknown>, action: string | undefined): Promise<CanResult> {\n const isPublic = artifactId.startsWith('pub_');\n const path = isPublic ? '/api/v1/verify' : '/api/v1/verify-decision';\n const body = isPublic\n ? { artifact_id: artifactId, decision: action ?? 'evaluate', inputs: facts }\n : { artifact_id: artifactId, decision: action ?? 'evaluate', inputs: facts, caller: { correlation_id: globalThis.crypto.randomUUID() } };\n\n // Note: CanOptions.signal has no effect here — HttpClient has no external abort-signal\n // passthrough anywhere in the SDK today (its own internal AbortController is timeout-only).\n // Pre-existing limitation, not introduced by this rail; not worth faking a parameter that\n // silently does nothing.\n const { data: raw } = await http.post<any>(path, body);\n\n const verdict: CanResult['verdict'] =\n raw.verdict === 'approved' ? 'AUTHORIZED'\n : raw.verdict === 'rejected' ? 'DENIED'\n : raw.outcome === 'auto_approved' ? 'AUTHORIZED'\n : raw.outcome === 'auto_rejected' ? 'DENIED'\n : 'ESCALATED';\n\n return {\n allowed: raw.allowed ?? verdict === 'AUTHORIZED',\n verdict,\n reason: raw.verdict_description ?? '',\n rule: raw.rule?.id ?? null,\n authority: {\n id: raw.artifact_id ?? artifactId,\n title: raw.artifact_name ?? '',\n standing: raw.confidence?.tier ?? '',\n },\n ...(raw.artifact_version ? { version: raw.artifact_version } : {}),\n missing_inputs: raw.incomplete_inputs?.fields ?? [],\n ...(raw.audit ? { audit: { hash: raw.audit.hash ?? raw.audit_hash ?? '', timestamp: raw.audit.timestamp ?? raw.ts ?? new Date().toISOString() } } : {}),\n // This rail's obligations are RuleEffect objects (authority-types.ts) — a richer, INTERNAL\n // shape ({ effect_type, value, provenance: { rule_id, rule_name } }), NOT the same shape the\n // Exchange rail already returns ({ kind, rule_id, rule_name }). Mapped explicitly here rather\n // than passed through raw — the two rails' server-side representations genuinely differ, and\n // assuming they matched would have been the actual bug.\n ...(Array.isArray(raw.obligations) && raw.obligations.length > 0\n ? { obligations: raw.obligations.map((o: any) => ({\n kind: o.kind ?? o.value ?? 'obligation',\n rule_id: o.rule_id ?? o.provenance?.rule_id ?? null,\n rule_name: o.rule_name ?? o.provenance?.rule_name ?? null,\n ...(o.reason ? { reason: o.reason } : {}),\n })) }\n : {}),\n };\n}\n\n/**\n * The chain-of-trust rail (PROTOTYPE, not a numbered spec). Keyless — works identically on the\n * free `can()` export and `client.can()`, since there's no account relationship to check here.\n * The server verifies the presented chain resolves to `root_public_key_pem` and, ONLY once that\n * succeeds, evaluates the artifact's own rules against `facts` — the same evaluator every other\n * rail uses (evaluateArtifactAgainstFacts, extracted from and proven identical to\n * /api/v1/verify-decision). An artifact whose chain doesn't resolve is never evaluated: this\n * throws NomosIssuerNotTrustedError instead of returning a verdict, because \"the rules say no\"\n * and \"we never established who's asking\" are different claims a caller needs to react to\n * differently — collapsing them into DENIED would tell the caller the wrong thing to do next.\n */\nasync function canViaChain(\n artifact: unknown, keyCerts: unknown, rootPublicKeyPem: string,\n facts: Record<string, unknown>, action: string | undefined, opts?: CanOptions,\n): Promise<CanResult> {\n const base = (opts?.baseUrl ?? DEFAULT_EXCHANGE_BASE).replace(/\\/$/, '');\n const url = `${base}/api/v1/chain-of-trust/verify`;\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({ version: CHAIN_PROTOCOL_VERSION, artifact, key_certs: keyCerts, root_public_key_pem: rootPublicKeyPem, 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\n if (data?.decision === 'AUTHORIZED' || data?.decision === 'DENIED' || data?.decision === 'ESCALATED') {\n return {\n allowed: data.decision === 'AUTHORIZED',\n verdict: data.decision,\n reason: data.reason ?? '',\n rule: data.rule ?? null,\n authority: { id: 'presented-artifact', title: '', standing: '' },\n // Read directly off the artifact the caller already has — no server round-trip needed for\n // data the caller is already holding.\n ...((artifact as any)?.meta?.version ? { version: (artifact as any).meta.version } : {}),\n missing_inputs: data.missing_inputs ?? [],\n ...(Array.isArray(data.obligations) && data.obligations.length > 0 ? { obligations: data.obligations } : {}),\n // Deliberately no query_id/url/audit — this evaluation is stateless by design (the whole\n // point is answering without NOMOS needing to have seen this artifact before); there is no\n // permanent transcript to point to, and faking one would misrepresent what just happened.\n };\n }\n\n // ALLOWED (facts were somehow not evaluated — shouldn't happen when facts are always sent, but\n // handled rather than assumed impossible), or one of the chain-failure decisions.\n const message: string = data?.detail ?? `Chain verification failed (HTTP ${res.status})`;\n if (data?.decision === 'ISSUER_NOT_RECOGNIZED' || data?.decision === 'KEY_REVOKED' || data?.decision === 'SEAL_INVALID' || data?.decision === 'ALLOWED') {\n throw new NomosIssuerNotTrustedError(message, data.decision, requestId);\n }\n if (data?.decision === 'MALFORMED') throw new NomosValidationError(message, data, requestId);\n mapHttpError(res.status, data, requestId);\n}\n\nexport async function can(params: CanParams, opts?: CanOptions): Promise<CanResult> {\n if (params.artifact !== undefined) {\n if (!params.key_certs || !params.root_public_key_pem) {\n throw new Error('can(): `artifact` requires `key_certs` and `root_public_key_pem` alongside it.');\n }\n const { facts, action } = splitFacts(params);\n return canViaChain(params.artifact, params.key_certs, params.root_public_key_pem, facts, action, opts);\n }\n if (params.artifact_id) {\n throw new Error('can(): `artifact_id` requires an API key — use `client.can(...)` on an authenticated Nomos instance, not the free `can()` export.');\n }\n if (!params.authority || typeof params.authority !== 'string') {\n throw new Error('can(): `authority` (an Exchange artifact id or slug), `artifact_id` (via client.can()), or `artifact` (chain-of-trust) is required.');\n }\n const { facts, action } = splitFacts(params);\n return canViaExchange(params.authority, facts, action, opts);\n}\n\n/** Shared implementation behind `Nomos.prototype.can()` — see nomos.ts. Exported so the class\n * stays a thin wrapper and this routing logic lives in exactly one place. */\nexport async function canAuthenticated(http: HttpClient, params: CanParams, opts?: CanOptions): Promise<CanResult> {\n void opts; // reserved — HttpClient has no external signal passthrough today, see canViaArtifact's note\n const { facts, action } = splitFacts(params);\n if (params.artifact !== undefined) {\n if (!params.key_certs || !params.root_public_key_pem) {\n throw new Error('can(): `artifact` requires `key_certs` and `root_public_key_pem` alongside it.');\n }\n // Keyless rail — an authenticated client is still free to use it, same server endpoint.\n return canViaChain(params.artifact, params.key_certs, params.root_public_key_pem, facts, action, opts);\n }\n if (params.artifact_id) return canViaArtifact(http, params.artifact_id, facts, action);\n if (params.authority) return canViaExchangeAuthenticated(http, params.authority, facts, action);\n throw new Error('can(): `authority` (a public Exchange artifact), `artifact_id` (your own artifact), or `artifact` (chain-of-trust) is required.');\n}\n\n/**\n * Ready-to-use, keyless entry point matching the canonical `nomos.can(...)` form.\n * For paid artifacts or your own artifacts, use `client.can(...)` on an authenticated `Nomos`\n * instance instead — same function name, same verdict shape, the only difference is which rail\n * answers and what it can unlock.\n */\nexport const nomos = { can };\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 { canAuthenticated } from './can.js';\nimport * as errors from './errors.js';\nimport type { NomosConfig, CanParams, CanOptions, CanResult } 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 private readonly http: HttpClient;\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 this.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(this.http);\n this.artifacts = new Artifacts(this.http);\n this.governance = new Governance(this.http);\n this.webhooks = new Webhooks();\n }\n\n /**\n * \"Can I do this?\" — the one verb, now covering your own artifacts too. Pass `authority` for a\n * public Exchange artifact, or `artifact_id` for your own (Studio or the Exchange) — same\n * return shape either way, so calling code never needs to know which rail answered.\n *\n * @example\n * const client = new Nomos('nms_live_...');\n * const verdict = await client.can({ artifact_id: 'loan_approval_v1', credit_score: 720 });\n */\n async can(params: CanParams, opts?: CanOptions): Promise<CanResult> {\n return canAuthenticated(this.http, params, opts);\n }\n}\n","import type { VerifyChainParams, VerifyChainOptions, VerifyChainResult } from './types.js';\nimport {\n NomosValidationError,\n NomosRateLimitError,\n NomosAPIError,\n NomosNetworkError,\n} from './errors.js';\n\nconst CHAIN_PROTOCOL_VERSION = '1';\nconst DEFAULT_BASE = 'https://www.nomosprotocol.com';\n\n/**\n * Chain-of-trust verification (PROTOTYPE — not a numbered spec). Checks whether a presented\n * artifact's signing key resolves, through the presented key certificates, back to a root you\n * have independently decided to trust — entirely server-side against nomos-chain.ts's pure\n * verifier, with no account or API key required (keyless, matching `nomos.can()`'s precedent).\n *\n * There is no default root anywhere in this call — `root_public_key_pem` is required. That's\n * deliberate: it keeps the trust decision with the caller, not with this SDK or the platform.\n *\n * @example\n * import { verifyChain } from '@nomosprotocol/sdk';\n *\n * const result = await verifyChain({\n * artifact: sealedArtifact,\n * key_certs: [rootToIntermediate, intermediateToLeaf],\n * root_public_key_pem: myPinnedRootPem,\n * });\n * if (result.decision === 'ALLOWED') { ... }\n */\nexport async function verifyChain(params: VerifyChainParams, opts?: VerifyChainOptions): Promise<VerifyChainResult> {\n if (!params.root_public_key_pem) {\n throw new Error('verifyChain(): `root_public_key_pem` is required — there is no default root.');\n }\n const base = (opts?.baseUrl ?? DEFAULT_BASE).replace(/\\/$/, '');\n const url = `${base}/api/v1/chain-of-trust/verify`;\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({\n version: CHAIN_PROTOCOL_VERSION,\n artifact: params.artifact,\n key_certs: params.key_certs,\n root_public_key_pem: params.root_public_key_pem,\n }),\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\n // 400/403/422 all carry a real ChainVerdict body (MALFORMED/ISSUER_NOT_RECOGNIZED/KEY_REVOKED/\n // SEAL_INVALID) — that's a verdict, not a transport failure, so it's returned, not thrown.\n if (data && typeof data.decision === 'string') {\n return data as VerifyChainResult;\n }\n\n const message: string = data?.error ?? `Chain verification request failed (HTTP ${res.status})`;\n if (res.status === 429) {\n throw new NomosRateLimitError(message, res.headers.get('retry-after') ? parseInt(res.headers.get('retry-after')!, 10) : undefined, requestId);\n }\n if (res.status === 400) throw new NomosValidationError(message, data?.details, requestId);\n throw new NomosAPIError(message, res.status, requestId);\n}\n"],"mappings":"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","names":["facts","action","CHAIN_PROTOCOL_VERSION"]}
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/can.ts","../src/nomos.ts","../src/verify-chain.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 | 'payment_required'\n | 'issuer_not_trusted';\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\n/** can() asked about a paid authority the caller hasn't purchased or licensed. Distinct from a\n * generic 403 on purpose: this isn't \"you're not allowed,\" it's \"here's exactly what unlocks\n * it\" — price and a URL to complete the purchase. NOMOS never auto-charges on your behalf;\n * this is the seam where a caller decides to buy, not where a payment silently happens. */\nexport class NomosPaymentRequiredError extends NomosError {\n readonly priceUsd: number;\n readonly purchaseUrl: string;\n\n constructor(message: string, priceUsd: number, purchaseUrl: string, requestId?: string) {\n super(message, 'payment_required', 402, requestId);\n this.name = 'NomosPaymentRequiredError';\n this.priceUsd = priceUsd;\n this.purchaseUrl = purchaseUrl;\n }\n}\n\n/** can()'s chain-of-trust rail could not establish that the presented artifact carries authority\n * it is entitled to — an unrecognized issuer, a revoked key, a delegation that never covered\n * this artifact, a tampered seal, or a malformed presentation. This is deliberately NOT a DENIED\n * verdict: \"the rules say no\" and \"we never got far enough to ask the rules anything\" are\n * different claims, and collapsing them would tell the caller the wrong thing to do next.\n *\n * `reason` carries the underlying chain decision so callers can distinguish them, because the\n * right next action genuinely differs:\n * ISSUER_NOT_RECOGNIZED — presenting a more complete chain may fix this\n * KEY_REVOKED — that key is dead; a different, unrevoked chain might work\n * CERTIFICATE_REVOKED — one delegation was withdrawn; another certificate for the same\n * key may still resolve\n * OUT_OF_SCOPE — the issuer IS recognized but was not delegated authority over this\n * artifact; only a broader (validly issued) delegation fixes it\n * SEAL_INVALID — the artifact itself was altered; nothing about presentation helps\n * MALFORMED — the request shape was wrong (a client-side bug) */\nexport class NomosIssuerNotTrustedError extends NomosError {\n readonly reason: string;\n\n constructor(message: string, reason: string, requestId?: string) {\n super(message, 'issuer_not_trusted', 403, requestId);\n this.name = 'NomosIssuerNotTrustedError';\n this.reason = reason;\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 type { CanParams, CanResult, CanOptions } from './types.js';\nimport type { HttpClient } from './http-client.js';\nimport {\n NomosAuthenticationError,\n NomosAuthorizationError,\n NomosRateLimitError,\n NomosValidationError,\n NomosNotFoundError,\n NomosAPIError,\n NomosNetworkError,\n NomosPaymentRequiredError,\n NomosIssuerNotTrustedError,\n} from './errors.js';\n\nconst CHAIN_PROTOCOL_VERSION = '1';\n\n/**\n * The whole product in one verb: \"Can I do this?\"\n *\n * Same pattern as Stripe's PaymentIntents API: one function, several rails underneath (a public\n * Exchange authority — free or paid — or your own authenticated artifact), and the caller never\n * has to know which one ran. Don't read `can()` as \"the Exchange's query function\" — the\n * Exchange is one of two rails behind it, not what it means.\n *\n * Both rails call into the SAME server-side implementation NOMOS itself uses (POST /api/v1/can,\n * backed by authority-query.ts's runAuthorityQuery) — not a parallel path, so there is exactly\n * one place that can drift between \"what the SDK returns\" and \"what NOMOS actually decided.\"\n *\n * Verdicts are always AUTHORIZED / DENIED / ESCALATED, normalized into that one vocabulary\n * regardless of which rail answered. `allowed` is simply `verdict === 'AUTHORIZED'`; an\n * ESCALATED result means the authority needs more facts to decide (see `missing_inputs`), not a\n * flat \"no\". A paid Exchange artifact you haven't purchased throws NomosPaymentRequiredError —\n * with the price and a purchase URL attached — rather than a generic 403 or a silent failure.\n * NOMOS never auto-charges on your behalf; this is the seam where a caller decides to buy.\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\nfunction splitFacts(params: CanParams): { facts: Record<string, unknown>; action: string | undefined } {\n const { authority, artifact_id, action, inputs, ...flat } = params;\n void authority; void artifact_id;\n // Two equally valid shapes: an explicit `inputs` object, or the facts spread flat\n // alongside `authority`/`artifact_id`/`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 return { facts, action };\n}\n\nfunction mapHttpError(status: number, data: any, requestId: string): never {\n const message: string = data?.error ?? data?.message ?? `NOMOS query failed (HTTP ${status})`;\n // Checked by CODE, not by the raw wire status (403) — this is \"here's what unlocks it,\" a\n // materially different thing for a caller to act on than \"you're not allowed at all.\"\n if (data?.code === 'PURCHASE_REQUIRED') {\n throw new NomosPaymentRequiredError(message, data.price_usd ?? 0, data.purchase_url ?? '', requestId);\n }\n switch (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(message, undefined, requestId);\n default: throw new NomosAPIError(message, status, requestId);\n }\n}\n\n/** Both Exchange-rail paths (keyless and authenticated) return the same underlying shape —\n * authority-query.ts's AuthorityQueryResult, spread with a few convenience fields by the\n * /api/v1/can route. One normalizer for both, so they can't quietly drift apart. */\nfunction normalizeAuthorityQueryResult(data: any, authority: string): CanResult {\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 ...(data.artifact?.attestation ? { attestation: data.artifact.attestation } : {}),\n },\n ...(data.artifact?.version ? { version: data.artifact.version } : {}),\n missing_inputs: data.missing_inputs ?? [],\n ...(typeof data.max_age === 'number' ? { max_age: data.max_age } : {}),\n // authority-query.ts already returns { kind, rule_id, rule_name } — the public-safe shape\n // CanResult uses directly.\n ...(Array.isArray(data.obligations) && data.obligations.length > 0 ? { obligations: data.obligations } : {}),\n // NOMOS-SPEC-006 — present only when the issuer has actually revoked this exact sealed\n // version; omitted (not false) when revocation doesn't structurally apply here, so \"checked\n // and clean\" and \"couldn't check\" never look the same to a caller.\n ...(data.revoked === true ? { revoked: true, revocation_reason: data.revocation_reason } : {}),\n };\n}\n\n/** Keyless — used only by the free top-level `can()` export. Free Exchange artifacts answer\n * anonymously; a paid one throws NomosPaymentRequiredError, since there's no API key here to\n * check purchase/license ownership against. */\nasync function canViaExchange(authority: string, facts: Record<string, unknown>, action: string | undefined, opts?: CanOptions): Promise<CanResult> {\n const base = (opts?.baseUrl ?? DEFAULT_EXCHANGE_BASE).replace(/\\/$/, '');\n const url = `${base}/api/v1/can`;\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({ artifact: authority, action, ...facts }),\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) mapHttpError(res.status, data, requestId);\n return normalizeAuthorityQueryResult(data, authority);\n}\n\n/** Authenticated — used by `client.can({ authority })`. Same endpoint, same normalization, but\n * routed through the instance's own HttpClient so its API key rides along: a paid artifact the\n * caller has purchased or published now actually works, which the keyless rail structurally\n * cannot support (there is no key there to check ownership against). */\nasync function canViaExchangeAuthenticated(http: HttpClient, authority: string, facts: Record<string, unknown>, action: string | undefined): Promise<CanResult> {\n const { data } = await http.post<any>('/api/v1/can', { artifact: authority, action, ...facts });\n return normalizeAuthorityQueryResult(data, authority);\n}\n\n/** The authenticated-artifact rail — your own artifact, requires an API key (an authenticated\n * `Nomos` instance's HttpClient). Normalizes the engine's own response shape (approved/rejected/\n * escalated, an audit hash) into the SAME AUTHORIZED/DENIED/ESCALATED verdict shape the Exchange\n * rail returns, rather than leaking a second vocabulary out to the caller. */\nasync function canViaArtifact(http: HttpClient, artifactId: string, facts: Record<string, unknown>, action: string | undefined): Promise<CanResult> {\n const isPublic = artifactId.startsWith('pub_');\n const path = isPublic ? '/api/v1/verify' : '/api/v1/verify-decision';\n const body = isPublic\n ? { artifact_id: artifactId, decision: action ?? 'evaluate', inputs: facts }\n : { artifact_id: artifactId, decision: action ?? 'evaluate', inputs: facts, caller: { correlation_id: globalThis.crypto.randomUUID() } };\n\n // Note: CanOptions.signal has no effect here — HttpClient has no external abort-signal\n // passthrough anywhere in the SDK today (its own internal AbortController is timeout-only).\n // Pre-existing limitation, not introduced by this rail; not worth faking a parameter that\n // silently does nothing.\n const { data: raw } = await http.post<any>(path, body);\n\n const verdict: CanResult['verdict'] =\n raw.verdict === 'approved' ? 'AUTHORIZED'\n : raw.verdict === 'rejected' ? 'DENIED'\n : raw.outcome === 'auto_approved' ? 'AUTHORIZED'\n : raw.outcome === 'auto_rejected' ? 'DENIED'\n : 'ESCALATED';\n\n return {\n allowed: raw.allowed ?? verdict === 'AUTHORIZED',\n verdict,\n reason: raw.verdict_description ?? '',\n rule: raw.rule?.id ?? null,\n authority: {\n id: raw.artifact_id ?? artifactId,\n title: raw.artifact_name ?? '',\n standing: raw.confidence?.tier ?? '',\n },\n ...(raw.artifact_version ? { version: raw.artifact_version } : {}),\n missing_inputs: raw.incomplete_inputs?.fields ?? [],\n ...(raw.audit ? { audit: { hash: raw.audit.hash ?? raw.audit_hash ?? '', timestamp: raw.audit.timestamp ?? raw.ts ?? new Date().toISOString() } } : {}),\n // This rail's obligations are RuleEffect objects (authority-types.ts) — a richer, INTERNAL\n // shape ({ effect_type, value, provenance: { rule_id, rule_name } }), NOT the same shape the\n // Exchange rail already returns ({ kind, rule_id, rule_name }). Mapped explicitly here rather\n // than passed through raw — the two rails' server-side representations genuinely differ, and\n // assuming they matched would have been the actual bug.\n ...(Array.isArray(raw.obligations) && raw.obligations.length > 0\n ? { obligations: raw.obligations.map((o: any) => ({\n kind: o.kind ?? o.value ?? 'obligation',\n rule_id: o.rule_id ?? o.provenance?.rule_id ?? null,\n rule_name: o.rule_name ?? o.provenance?.rule_name ?? null,\n ...(o.reason ? { reason: o.reason } : {}),\n })) }\n : {}),\n };\n}\n\n/**\n * The chain-of-trust rail (PROTOTYPE, not a numbered spec). Keyless — works identically on the\n * free `can()` export and `client.can()`, since there's no account relationship to check here.\n * The server verifies the presented chain resolves to `root_public_key_pem` and, ONLY once that\n * succeeds, evaluates the artifact's own rules against `facts` — the same evaluator every other\n * rail uses (evaluateArtifactAgainstFacts, extracted from and proven identical to\n * /api/v1/verify-decision). An artifact whose chain doesn't resolve is never evaluated: this\n * throws NomosIssuerNotTrustedError instead of returning a verdict, because \"the rules say no\"\n * and \"we never established who's asking\" are different claims a caller needs to react to\n * differently — collapsing them into DENIED would tell the caller the wrong thing to do next.\n */\nasync function canViaChain(\n artifact: unknown, keyCerts: unknown, rootPublicKeyPem: string,\n facts: Record<string, unknown>, action: string | undefined, opts?: CanOptions,\n): Promise<CanResult> {\n const base = (opts?.baseUrl ?? DEFAULT_EXCHANGE_BASE).replace(/\\/$/, '');\n const url = `${base}/api/v1/chain-of-trust/verify`;\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({ version: CHAIN_PROTOCOL_VERSION, artifact, key_certs: keyCerts, root_public_key_pem: rootPublicKeyPem, 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\n if (data?.decision === 'AUTHORIZED' || data?.decision === 'DENIED' || data?.decision === 'ESCALATED') {\n return {\n allowed: data.decision === 'AUTHORIZED',\n verdict: data.decision,\n reason: data.reason ?? '',\n rule: data.rule ?? null,\n authority: { id: 'presented-artifact', title: '', standing: '' },\n // Read directly off the artifact the caller already has — no server round-trip needed for\n // data the caller is already holding.\n ...((artifact as any)?.meta?.version ? { version: (artifact as any).meta.version } : {}),\n missing_inputs: data.missing_inputs ?? [],\n ...(Array.isArray(data.obligations) && data.obligations.length > 0 ? { obligations: data.obligations } : {}),\n // §5.5 — composing to a real permission decision must not silently drop the chain's own\n // revocation-confidence disclosure; the server already threads this through, so forward it.\n ...(data.revocation_checked ? { revocation_checked: data.revocation_checked } : {}),\n // Deliberately no query_id/url/audit — this evaluation is stateless by design (the whole\n // point is answering without NOMOS needing to have seen this artifact before); there is no\n // permanent transcript to point to, and faking one would misrepresent what just happened.\n };\n }\n\n // ALLOWED (facts were somehow not evaluated — shouldn't happen when facts are always sent, but\n // handled rather than assumed impossible), or one of the chain-failure decisions.\n const message: string = data?.detail ?? `Chain verification failed (HTTP ${res.status})`;\n if (data?.decision === 'ISSUER_NOT_RECOGNIZED' || data?.decision === 'KEY_REVOKED' || data?.decision === 'CERTIFICATE_REVOKED' || data?.decision === 'OUT_OF_SCOPE' || data?.decision === 'SEAL_INVALID' || data?.decision === 'ALLOWED') {\n throw new NomosIssuerNotTrustedError(message, data.decision, requestId);\n }\n if (data?.decision === 'MALFORMED') throw new NomosValidationError(message, data, requestId);\n mapHttpError(res.status, data, requestId);\n}\n\nexport async function can(params: CanParams, opts?: CanOptions): Promise<CanResult> {\n if (params.artifact !== undefined) {\n if (!params.key_certs || !params.root_public_key_pem) {\n throw new Error('can(): `artifact` requires `key_certs` and `root_public_key_pem` alongside it.');\n }\n const { facts, action } = splitFacts(params);\n return canViaChain(params.artifact, params.key_certs, params.root_public_key_pem, facts, action, opts);\n }\n if (params.artifact_id) {\n throw new Error('can(): `artifact_id` requires an API key — use `client.can(...)` on an authenticated Nomos instance, not the free `can()` export.');\n }\n if (!params.authority || typeof params.authority !== 'string') {\n throw new Error('can(): `authority` (an Exchange artifact id or slug), `artifact_id` (via client.can()), or `artifact` (chain-of-trust) is required.');\n }\n const { facts, action } = splitFacts(params);\n return canViaExchange(params.authority, facts, action, opts);\n}\n\n/** Shared implementation behind `Nomos.prototype.can()` — see nomos.ts. Exported so the class\n * stays a thin wrapper and this routing logic lives in exactly one place. */\nexport async function canAuthenticated(http: HttpClient, params: CanParams, opts?: CanOptions): Promise<CanResult> {\n void opts; // reserved — HttpClient has no external signal passthrough today, see canViaArtifact's note\n const { facts, action } = splitFacts(params);\n if (params.artifact !== undefined) {\n if (!params.key_certs || !params.root_public_key_pem) {\n throw new Error('can(): `artifact` requires `key_certs` and `root_public_key_pem` alongside it.');\n }\n // Keyless rail — an authenticated client is still free to use it, same server endpoint.\n return canViaChain(params.artifact, params.key_certs, params.root_public_key_pem, facts, action, opts);\n }\n if (params.artifact_id) return canViaArtifact(http, params.artifact_id, facts, action);\n if (params.authority) return canViaExchangeAuthenticated(http, params.authority, facts, action);\n throw new Error('can(): `authority` (a public Exchange artifact), `artifact_id` (your own artifact), or `artifact` (chain-of-trust) is required.');\n}\n\n/**\n * Ready-to-use, keyless entry point matching the canonical `nomos.can(...)` form.\n * For paid artifacts or your own artifacts, use `client.can(...)` on an authenticated `Nomos`\n * instance instead — same function name, same verdict shape, the only difference is which rail\n * answers and what it can unlock.\n */\nexport const nomos = { can };\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 { canAuthenticated } from './can.js';\nimport * as errors from './errors.js';\nimport type { NomosConfig, CanParams, CanOptions, CanResult } 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 private readonly http: HttpClient;\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 this.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(this.http);\n this.artifacts = new Artifacts(this.http);\n this.governance = new Governance(this.http);\n this.webhooks = new Webhooks();\n }\n\n /**\n * \"Can I do this?\" — the one verb, now covering your own artifacts too. Pass `authority` for a\n * public Exchange artifact, or `artifact_id` for your own (Studio or the Exchange) — same\n * return shape either way, so calling code never needs to know which rail answered.\n *\n * @example\n * const client = new Nomos('nms_live_...');\n * const verdict = await client.can({ artifact_id: 'loan_approval_v1', credit_score: 720 });\n */\n async can(params: CanParams, opts?: CanOptions): Promise<CanResult> {\n return canAuthenticated(this.http, params, opts);\n }\n}\n","import type { VerifyChainParams, VerifyChainOptions, VerifyChainResult } from './types.js';\nimport {\n NomosValidationError,\n NomosRateLimitError,\n NomosAPIError,\n NomosNetworkError,\n} from './errors.js';\n\nconst CHAIN_PROTOCOL_VERSION = '1';\nconst DEFAULT_BASE = 'https://www.nomosprotocol.com';\n\n/**\n * Chain-of-trust verification (PROTOTYPE — not a numbered spec). Checks whether a presented\n * artifact's signing key resolves, through the presented key certificates, back to a root you\n * have independently decided to trust — entirely server-side against nomos-chain.ts's pure\n * verifier, with no account or API key required (keyless, matching `nomos.can()`'s precedent).\n *\n * There is no default root anywhere in this call — `root_public_key_pem` is required. That's\n * deliberate: it keeps the trust decision with the caller, not with this SDK or the platform.\n *\n * @example\n * import { verifyChain } from '@nomosprotocol/sdk';\n *\n * const result = await verifyChain({\n * artifact: sealedArtifact,\n * key_certs: [rootToIntermediate, intermediateToLeaf],\n * root_public_key_pem: myPinnedRootPem,\n * });\n * if (result.decision === 'ALLOWED') { ... }\n */\nexport async function verifyChain(params: VerifyChainParams, opts?: VerifyChainOptions): Promise<VerifyChainResult> {\n if (!params.root_public_key_pem) {\n throw new Error('verifyChain(): `root_public_key_pem` is required — there is no default root.');\n }\n const base = (opts?.baseUrl ?? DEFAULT_BASE).replace(/\\/$/, '');\n const url = `${base}/api/v1/chain-of-trust/verify`;\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({\n version: CHAIN_PROTOCOL_VERSION,\n artifact: params.artifact,\n key_certs: params.key_certs,\n root_public_key_pem: params.root_public_key_pem,\n }),\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\n // 400/403/422 all carry a real ChainVerdict body (MALFORMED/ISSUER_NOT_RECOGNIZED/KEY_REVOKED/\n // SEAL_INVALID) — that's a verdict, not a transport failure, so it's returned, not thrown.\n if (data && typeof data.decision === 'string') {\n return data as VerifyChainResult;\n }\n\n const message: string = data?.error ?? `Chain verification request failed (HTTP ${res.status})`;\n if (res.status === 429) {\n throw new NomosRateLimitError(message, res.headers.get('retry-after') ? parseInt(res.headers.get('retry-after')!, 10) : undefined, requestId);\n }\n if (res.status === 400) throw new NomosValidationError(message, data?.details, requestId);\n throw new NomosAPIError(message, res.status, requestId);\n}\n"],"mappings":"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","names":["facts","action","CHAIN_PROTOCOL_VERSION"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nomosprotocol/sdk",
3
- "version": "1.3.3",
3
+ "version": "1.3.4",
4
4
  "description": "Official TypeScript SDK for the NOMOS governance runtime",
5
5
  "publishConfig": {
6
6
  "access": "public"