@nexart/ai-execution 0.4.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -2
- package/dist/index.cjs +1433 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +140 -3
- package/dist/index.d.ts +140 -3
- package/dist/index.mjs +1425 -10
- package/dist/index.mjs.map +1 -1
- package/dist/providers/anthropic.cjs +1 -1
- package/dist/providers/anthropic.cjs.map +1 -1
- package/dist/providers/anthropic.d.cts +1 -1
- package/dist/providers/anthropic.d.ts +1 -1
- package/dist/providers/anthropic.mjs +1 -1
- package/dist/providers/anthropic.mjs.map +1 -1
- package/dist/providers/openai.cjs +1 -1
- package/dist/providers/openai.cjs.map +1 -1
- package/dist/providers/openai.d.cts +1 -1
- package/dist/providers/openai.d.ts +1 -1
- package/dist/providers/openai.mjs +1 -1
- package/dist/providers/openai.mjs.map +1 -1
- package/dist/providers/wrap.cjs +1 -1
- package/dist/providers/wrap.cjs.map +1 -1
- package/dist/providers/wrap.d.cts +1 -1
- package/dist/providers/wrap.d.ts +1 -1
- package/dist/providers/wrap.mjs +1 -1
- package/dist/providers/wrap.mjs.map +1 -1
- package/dist/{types-Cnm2G_rg.d.cts → types-Cgb52dTx.d.cts} +90 -1
- package/dist/{types-Cnm2G_rg.d.ts → types-Cgb52dTx.d.ts} +90 -1
- package/fixtures/attestation/keys-v1.json +18 -0
- package/fixtures/attestation/receipt-v1.json +10 -0
- package/fixtures/attestation/receipt-v1.pub +1 -0
- package/fixtures/attestation/receipt-v1.sig +1 -0
- package/fixtures/v060/legacy-attestation.json +32 -0
- package/fixtures/v060/original-meta-bundle.json +36 -0
- package/fixtures/v060/pre-v05-bundle.json +29 -0
- package/fixtures/v060/redacted-bundle.json +36 -0
- package/package.json +6 -4
package/README.md
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
# @nexart/ai-execution v0.
|
|
1
|
+
# @nexart/ai-execution v0.6.0
|
|
2
2
|
|
|
3
3
|
Tamper-evident records and Certified Execution Records (CER) for AI operations.
|
|
4
4
|
|
|
5
|
+
## Version Information
|
|
6
|
+
|
|
7
|
+
| Component | Version |
|
|
8
|
+
|---|---|
|
|
9
|
+
| Service | — |
|
|
10
|
+
| SDK | 0.6.0 |
|
|
11
|
+
| Protocol | 1.2.0 |
|
|
12
|
+
|
|
5
13
|
## Why Not Just Store Logs?
|
|
6
14
|
|
|
7
15
|
Logs tell you what happened. CERs prove integrity. A log entry can be edited, truncated, or fabricated after the fact with no way to detect it. A CER bundle is cryptographically sealed: any modification — to the input, output, parameters, or ordering — invalidates the certificate hash. If you need to demonstrate to an auditor, regulator, or downstream system that a recorded execution has not been modified post-hoc, logs are insufficient. CERs provide the tamper-evident chain of custody that logs cannot. **CERs certify records, not model determinism or provider execution.**
|
|
@@ -192,6 +200,8 @@ type AttestationReceipt = {
|
|
|
192
200
|
protocolVersion: string;
|
|
193
201
|
nodeId?: string;
|
|
194
202
|
attestedAt?: string; // ISO 8601
|
|
203
|
+
attestorKeyId?: string; // kid of the signing key (v0.5.0+)
|
|
204
|
+
signatureB64Url?: string; // base64url Ed25519 signature (v0.5.0+)
|
|
195
205
|
};
|
|
196
206
|
```
|
|
197
207
|
|
|
@@ -221,6 +231,49 @@ const receipt = getAttestationReceipt(bundle); // null if not yet attested
|
|
|
221
231
|
- `attestIfNeeded(bundle, options)` — skips the node call if a valid receipt is already present; prevents double-attestation
|
|
222
232
|
- `certifyAndAttestDecision(params, options)` — recommended one-call integration: `certifyDecision` + `attest` + normalized receipt
|
|
223
233
|
|
|
234
|
+
### Signed Receipt Verification (v0.5.0+)
|
|
235
|
+
|
|
236
|
+
After a node signs the receipt, verify it offline without a round-trip:
|
|
237
|
+
|
|
238
|
+
```ts
|
|
239
|
+
import {
|
|
240
|
+
verifyNodeReceiptSignature,
|
|
241
|
+
verifyBundleAttestation,
|
|
242
|
+
fetchNodeKeys,
|
|
243
|
+
selectNodeKey,
|
|
244
|
+
} from '@nexart/ai-execution';
|
|
245
|
+
|
|
246
|
+
// One-call: fetches node keys, selects correct key, verifies Ed25519 signature
|
|
247
|
+
const result = await verifyBundleAttestation(bundle, {
|
|
248
|
+
nodeUrl: 'https://my-node.example.com',
|
|
249
|
+
});
|
|
250
|
+
// result.ok === true → signature is valid
|
|
251
|
+
// result.code → CerVerifyCode enum value
|
|
252
|
+
// result.details → string[] with failure explanation (when ok=false)
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**Verify against a specific key directly:**
|
|
256
|
+
|
|
257
|
+
```ts
|
|
258
|
+
const result = await verifyNodeReceiptSignature({
|
|
259
|
+
receipt: { attestationId: '...', certificateHash: 'sha256:...', ... },
|
|
260
|
+
signatureB64Url: 'aDEKyu...Q',
|
|
261
|
+
key: { jwk: { kty: 'OKP', crv: 'Ed25519', x: '<base64url pubkey>' } },
|
|
262
|
+
// or: key: { rawB64Url: '<base64url raw 32 bytes>' }
|
|
263
|
+
});
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
**Failure codes:**
|
|
267
|
+
|
|
268
|
+
| Code | Meaning |
|
|
269
|
+
|---|---|
|
|
270
|
+
| `ATTESTATION_MISSING` | No signed receipt in bundle |
|
|
271
|
+
| `ATTESTATION_KEY_NOT_FOUND` | kid not found in node keys document |
|
|
272
|
+
| `ATTESTATION_INVALID_SIGNATURE` | Ed25519 signature did not verify |
|
|
273
|
+
| `ATTESTATION_KEY_FORMAT_UNSUPPORTED` | Key cannot be decoded (wrong crv, no fields, etc.) |
|
|
274
|
+
|
|
275
|
+
**Node keys document** is fetched from `{nodeUrl}/.well-known/nexart-node.json`. See `SPEC.md` for the full shape.
|
|
276
|
+
|
|
224
277
|
### Sanitization and Redaction
|
|
225
278
|
|
|
226
279
|
`sanitizeForAttestation(bundle)` returns a JSON-safe deep clone:
|
|
@@ -282,11 +335,29 @@ Fixtures at `fixtures/vectors/` and `fixtures/golden/`. Cross-language implement
|
|
|
282
335
|
| `certifyAndAttestDecision(params, options)` | One-call: certifyDecision + attest + receipt |
|
|
283
336
|
| `attestIfNeeded(bundle, options)` | Attest only if no receipt already present |
|
|
284
337
|
| `getAttestationReceipt(bundle)` | Extract normalized `AttestationReceipt` or `null` |
|
|
338
|
+
| `verifyNodeReceiptSignature(params)` | Verify an Ed25519-signed receipt offline (v0.5.0+) |
|
|
339
|
+
| `fetchNodeKeys(nodeUrl)` | Fetch `NodeKeysDocument` from `/.well-known/nexart-node.json` (v0.5.0+) |
|
|
340
|
+
| `selectNodeKey(doc, kid?)` | Select a key from a `NodeKeysDocument` by kid or activeKid (v0.5.0+) |
|
|
341
|
+
| `verifyBundleAttestation(bundle, options)` | One-call offline attestation verification (v0.5.0+) |
|
|
285
342
|
| `sanitizeForAttestation(bundle)` | Remove `undefined` keys, reject BigInt/functions/symbols |
|
|
343
|
+
| `sanitizeForStorage(bundle, options?)` | Sanitize for DB storage with optional path-based redaction; does not recompute hashes (v0.6.0+) |
|
|
344
|
+
| `sanitizeForStamp(bundle)` | Extract attestable core (no meta); does not recompute hashes (v0.6.0+) |
|
|
286
345
|
| `hasAttestation(bundle)` | Check if bundle already has attestation fields |
|
|
287
346
|
| `exportCer(bundle)` | Serialize to canonical JSON string |
|
|
288
347
|
| `importCer(json)` | Parse + verify from JSON string |
|
|
289
348
|
|
|
349
|
+
### Provider Drop-in (v0.6.0+)
|
|
350
|
+
|
|
351
|
+
| Function | Description |
|
|
352
|
+
|---|---|
|
|
353
|
+
| `certifyDecisionFromProviderCall(params)` | One-function wrapper: extracts prompt/input/output/params from raw provider request+response and returns `{ ok, bundle }` or `{ ok: false, code: 'SCHEMA_ERROR', reason }`. Supports OpenAI, Anthropic, Gemini, Mistral, Bedrock, and generic shapes. |
|
|
354
|
+
|
|
355
|
+
### Opinionated Client (v0.6.0+)
|
|
356
|
+
|
|
357
|
+
| Export | Description |
|
|
358
|
+
|---|---|
|
|
359
|
+
| `createClient(defaults)` | Returns a `NexArtClient` with bound defaults (`appId`, `workflowId`, `nodeUrl`, `apiKey`, `tags`, `source`). Methods: `certifyDecision`, `certifyAndAttestDecision`, `verify`, `verifyBundleAttestation`. Defaults do not affect bundle hashing. |
|
|
360
|
+
|
|
290
361
|
### Reason Codes
|
|
291
362
|
|
|
292
363
|
`CerVerifyCode` — stable string-union constant exported from the package root:
|
|
@@ -302,6 +373,10 @@ Fixtures at `fixtures/vectors/` and `fixtures/golden/`. Cross-language implement
|
|
|
302
373
|
| `SCHEMA_ERROR` | Wrong bundleType/version, missing snapshot, non-finite parameters, etc. |
|
|
303
374
|
| `CANONICALIZATION_ERROR` | `toCanonicalJson` threw during verification |
|
|
304
375
|
| `UNKNOWN_ERROR` | Catch-all for unclassified failures |
|
|
376
|
+
| `ATTESTATION_MISSING` | No signed receipt found in bundle (v0.5.0+) |
|
|
377
|
+
| `ATTESTATION_KEY_NOT_FOUND` | kid not found in node keys document (v0.5.0+) |
|
|
378
|
+
| `ATTESTATION_INVALID_SIGNATURE` | Ed25519 signature did not verify (v0.5.0+) |
|
|
379
|
+
| `ATTESTATION_KEY_FORMAT_UNSUPPORTED` | Key cannot be decoded (v0.5.0+) |
|
|
305
380
|
|
|
306
381
|
Priority when multiple failures exist: `CANONICALIZATION_ERROR` > `SCHEMA_ERROR` > `INVALID_SHA256_FORMAT` > `CERTIFICATE_HASH_MISMATCH` > `INPUT_HASH_MISMATCH` > `OUTPUT_HASH_MISMATCH` > `SNAPSHOT_HASH_MISMATCH` > `UNKNOWN_ERROR`.
|
|
307
382
|
|
|
@@ -324,7 +399,9 @@ Priority when multiple failures exist: `CANONICALIZATION_ERROR` > `SCHEMA_ERROR`
|
|
|
324
399
|
| v0.3.0 | Attestation hardening (hash validation, timeout), `verify` alias, `CerAttestationError.details`, release hygiene |
|
|
325
400
|
| v0.4.0 | Dual ESM/CJS build, `sanitizeForAttestation`, `hasAttestation`, auto-sanitize in `attest()`, fixed `ERR_PACKAGE_PATH_NOT_EXPORTED` |
|
|
326
401
|
| v0.4.1 | Verification reason codes (`CerVerifyCode`), `code` + `details` on `VerificationResult`, README provenance wording tightened |
|
|
327
|
-
|
|
|
402
|
+
| v0.4.2 | `AttestationReceipt`, `getAttestationReceipt`, `certifyAndAttestDecision`, `attestIfNeeded` |
|
|
403
|
+
| v0.5.0 | Ed25519 signed receipt verification: `verifyNodeReceiptSignature`, `verifyBundleAttestation`, `fetchNodeKeys`, `selectNodeKey`; new attestation `CerVerifyCode` entries; `SPEC.md`; `NodeKeysDocument`, `SignedAttestationReceipt`, `NodeReceiptVerifyResult` types |
|
|
404
|
+
| **v0.6.0** | Frictionless integration: `certifyDecisionFromProviderCall` (OpenAI/Anthropic/Gemini/Mistral/Bedrock drop-in); `sanitizeForStorage` + `sanitizeForStamp` redaction helpers; `createClient(defaults)` factory; regression fixture suite; all backward-compatible, no hash changes |
|
|
328
405
|
| v1.0.0 | Planned: API stabilization, freeze public API surface |
|
|
329
406
|
|
|
330
407
|
## Releasing
|