@nexart/ai-execution 0.7.0 → 0.8.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/dist/index.d.cts CHANGED
@@ -353,4 +353,152 @@ interface ProfileValidationResult {
353
353
  */
354
354
  declare function validateProfile(target: AiExecutionSnapshotV1 | CerAiExecutionBundle, profile: AiefProfile): ProfileValidationResult;
355
355
 
356
- export { AiExecutionSnapshotV1, AiefProfile, AiefVerifyResult, AttestOptions, AttestationReceipt, AttestationResult, BundleDeclaration, CerAiExecutionBundle, CerAttestationError, CerMeta, CerVerificationError, CerVerifyCode, CerVerifyCode as CerVerifyCodeType, CertifyDecisionParams, CreateSnapshotParams, type MakeToolEventParams, NodeKeysDocument, NodeReceiptVerifyResult, type ProfileValidationResult, type RedactBeforeSealPolicy, RunBuilder, RunBuilderOptions, RunSummary, RunSummaryVerifyResult, SanitizeStorageOptions, SignedAttestationReceipt, StepParams, ToolEvent, VerificationResult, type VerifyRunSummaryOptions, attest, attestIfNeeded, certifyAndAttestDecision, certifyDecision, certifyDecisionFromProviderCall, computeInputHash, computeOutputHash, createClient, createSnapshot, exportCer, fetchNodeKeys, getAttestationReceipt, hasAttestation, hashCanonicalJson, hashToolOutput, hashUtf8, importCer, makeToolEvent, mapToAiefReason, redactBeforeSeal, sanitizeForAttestation, sanitizeForStamp, sanitizeForStorage, sealCer, selectNodeKey, sha256Hex, toCanonicalJson, validateProfile, verifyCer as verify, verifyAief, verifyBundleAttestation, verifyCer, verifyNodeReceiptSignature, verifyRunSummary, verifySnapshot };
356
+ /**
357
+ * @nexart/ai-execution — Verifiable redacted export helper
358
+ *
359
+ * exportVerifiableRedacted() produces a NEW sealed bundle whose snapshot has
360
+ * sensitive fields replaced with redaction envelopes via redactBeforeSeal().
361
+ *
362
+ * The result is a fully independently verifiable bundle with a NEW certificateHash.
363
+ * The original certificateHash is preserved in meta.provenance as an informational
364
+ * cross-reference ONLY — it does not establish any cryptographic relationship
365
+ * between the two bundles.
366
+ *
367
+ * verify(newBundle) → { ok: true } ✅ the new bundle verifies on its own
368
+ * verify(originalBundle) → { ok: true } ✅ the original is unaffected
369
+ *
370
+ * IMPORTANT CONSTRAINTS:
371
+ * - Only `input` and `output` paths are safe to redact (their content hashes are
372
+ * recomputed from the envelope). Schema-validated string fields like `prompt`
373
+ * cannot be replaced with an object envelope — verify() will return SCHEMA_ERROR.
374
+ * - `meta.provenance.originalCertificateHash` is reference metadata only.
375
+ * Anyone who receives only the new bundle cannot verify the original's integrity.
376
+ */
377
+
378
+ interface ExportVerifiableRedactedOptions {
379
+ createdAt?: string;
380
+ }
381
+ interface ExportVerifiableRedactedProvenance {
382
+ originalCertificateHash: string;
383
+ redactionPolicy: {
384
+ paths: string[];
385
+ };
386
+ redactedAt: string;
387
+ }
388
+ interface ExportVerifiableRedactedResult {
389
+ bundle: CerAiExecutionBundle;
390
+ /**
391
+ * The original bundle's certificateHash. Convenience alias for
392
+ * `bundle.meta.provenance.originalCertificateHash`.
393
+ * Reference only — no cryptographic link to the new bundle.
394
+ */
395
+ originalCertificateHash: string;
396
+ }
397
+ /**
398
+ * Produce a new sealed bundle with redacted snapshot fields.
399
+ *
400
+ * @param bundle The original sealed bundle to redact from.
401
+ * @param policy Which snapshot paths to redact. Only 'input' and 'output'
402
+ * are safe for verifiable redaction (their content hashes are
403
+ * recomputed). Other schema-validated string fields will cause
404
+ * verify() to return SCHEMA_ERROR on the new bundle.
405
+ * @param options Optional overrides (createdAt).
406
+ *
407
+ * @example
408
+ * ```typescript
409
+ * import { certifyDecision, verify, exportVerifiableRedacted } from '@nexart/ai-execution';
410
+ *
411
+ * const original = certifyDecision({ ... });
412
+ * const { bundle, originalCertificateHash } = exportVerifiableRedacted(
413
+ * original,
414
+ * { paths: ['input', 'output'] },
415
+ * );
416
+ *
417
+ * verify(bundle).ok; // true
418
+ * bundle.meta.provenance.originalCertificateHash; // 'sha256:...' — reference only
419
+ * bundle.snapshot.input; // { _redacted: true, hash: 'sha256:...' }
420
+ * ```
421
+ */
422
+ declare function exportVerifiableRedacted(bundle: CerAiExecutionBundle, policy: RedactBeforeSealPolicy, options?: ExportVerifiableRedactedOptions): ExportVerifiableRedactedResult;
423
+
424
+ /**
425
+ * @nexart/ai-execution — Opinionated run helper
426
+ *
427
+ * certifyAndAttestRun(): certify every step in a multi-step run via RunBuilder,
428
+ * optionally attest each sealed bundle, and return a consolidated result.
429
+ *
430
+ * Design principles:
431
+ * - Does NOT mutate or wrap any externally-owned RunBuilder. Creates its own.
432
+ * - RunBuilder semantics are unchanged: prevStepHash chaining is automatic.
433
+ * - attestStep is optional and injectable so callers can mock in tests without
434
+ * hitting the network.
435
+ * - Network failures from attestStep bubble up — wrap in try/catch for partial
436
+ * failure tolerance.
437
+ */
438
+
439
+ interface CertifyAndAttestRunOptions {
440
+ runId?: string;
441
+ workflowId?: string | null;
442
+ conversationId?: string | null;
443
+ appId?: string | null;
444
+ /**
445
+ * Optional per-step attestation function. Receives each sealed step bundle
446
+ * immediately after it is created. Return an AttestationReceipt on success.
447
+ *
448
+ * If omitted, all receipts will be null (bundles are sealed but not attested).
449
+ *
450
+ * @example
451
+ * ```typescript
452
+ * import { attest } from '@nexart/ai-execution';
453
+ * certifyAndAttestRun(steps, {
454
+ * attestStep: (bundle) => attest(bundle, { nodeUrl, apiKey }),
455
+ * });
456
+ * ```
457
+ */
458
+ attestStep?: (bundle: CerAiExecutionBundle) => Promise<AttestationReceipt>;
459
+ }
460
+ interface CertifyAndAttestRunResult {
461
+ runSummary: RunSummary;
462
+ stepBundles: CerAiExecutionBundle[];
463
+ /**
464
+ * Attestation receipts in step order. `null` at index i means the step
465
+ * was sealed but not attested (no `attestStep` option was provided).
466
+ */
467
+ receipts: (AttestationReceipt | null)[];
468
+ /** Alias for runSummary.finalStepHash — the last step's certificateHash. */
469
+ finalStepHash: string | null;
470
+ }
471
+ /**
472
+ * Certify every step in a multi-step run and optionally attest each bundle.
473
+ *
474
+ * Each step is sealed via RunBuilder, which automatically:
475
+ * - assigns stepIndex (0-based)
476
+ * - sets prevStepHash to the previous step's certificateHash
477
+ * - assigns a unique executionId and stepId per step
478
+ *
479
+ * The resulting runSummary + stepBundles can be validated offline with
480
+ * verifyRunSummary(runSummary, stepBundles).
481
+ *
482
+ * @param steps Ordered list of step parameters (step 0 first).
483
+ * @param options Run-level options and optional attestation hook.
484
+ *
485
+ * @example
486
+ * ```typescript
487
+ * import { certifyAndAttestRun, verifyRunSummary } from '@nexart/ai-execution';
488
+ *
489
+ * const { runSummary, stepBundles, receipts, finalStepHash } =
490
+ * await certifyAndAttestRun(
491
+ * [step0Params, step1Params, step2Params],
492
+ * {
493
+ * runId: 'analysis-run',
494
+ * workflowId: 'data-pipeline',
495
+ * attestStep: (bundle) => attest(bundle, { nodeUrl, apiKey }),
496
+ * },
497
+ * );
498
+ *
499
+ * verifyRunSummary(runSummary, stepBundles); // { ok: true }
500
+ * ```
501
+ */
502
+ declare function certifyAndAttestRun(steps: StepParams[], options?: CertifyAndAttestRunOptions): Promise<CertifyAndAttestRunResult>;
503
+
504
+ export { AiExecutionSnapshotV1, AiefProfile, AiefVerifyResult, AttestOptions, AttestationReceipt, AttestationResult, BundleDeclaration, CerAiExecutionBundle, CerAttestationError, CerMeta, CerVerificationError, CerVerifyCode, CerVerifyCode as CerVerifyCodeType, type CertifyAndAttestRunOptions, type CertifyAndAttestRunResult, CertifyDecisionParams, CreateSnapshotParams, type ExportVerifiableRedactedOptions, type ExportVerifiableRedactedProvenance, type ExportVerifiableRedactedResult, type MakeToolEventParams, NodeKeysDocument, NodeReceiptVerifyResult, type ProfileValidationResult, type RedactBeforeSealPolicy, RunBuilder, RunBuilderOptions, RunSummary, RunSummaryVerifyResult, SanitizeStorageOptions, SignedAttestationReceipt, StepParams, ToolEvent, VerificationResult, type VerifyRunSummaryOptions, attest, attestIfNeeded, certifyAndAttestDecision, certifyAndAttestRun, certifyDecision, certifyDecisionFromProviderCall, computeInputHash, computeOutputHash, createClient, createSnapshot, exportCer, exportVerifiableRedacted, fetchNodeKeys, getAttestationReceipt, hasAttestation, hashCanonicalJson, hashToolOutput, hashUtf8, importCer, makeToolEvent, mapToAiefReason, redactBeforeSeal, sanitizeForAttestation, sanitizeForStamp, sanitizeForStorage, sealCer, selectNodeKey, sha256Hex, toCanonicalJson, validateProfile, verifyCer as verify, verifyAief, verifyBundleAttestation, verifyCer, verifyNodeReceiptSignature, verifyRunSummary, verifySnapshot };
package/dist/index.d.ts CHANGED
@@ -353,4 +353,152 @@ interface ProfileValidationResult {
353
353
  */
354
354
  declare function validateProfile(target: AiExecutionSnapshotV1 | CerAiExecutionBundle, profile: AiefProfile): ProfileValidationResult;
355
355
 
356
- export { AiExecutionSnapshotV1, AiefProfile, AiefVerifyResult, AttestOptions, AttestationReceipt, AttestationResult, BundleDeclaration, CerAiExecutionBundle, CerAttestationError, CerMeta, CerVerificationError, CerVerifyCode, CerVerifyCode as CerVerifyCodeType, CertifyDecisionParams, CreateSnapshotParams, type MakeToolEventParams, NodeKeysDocument, NodeReceiptVerifyResult, type ProfileValidationResult, type RedactBeforeSealPolicy, RunBuilder, RunBuilderOptions, RunSummary, RunSummaryVerifyResult, SanitizeStorageOptions, SignedAttestationReceipt, StepParams, ToolEvent, VerificationResult, type VerifyRunSummaryOptions, attest, attestIfNeeded, certifyAndAttestDecision, certifyDecision, certifyDecisionFromProviderCall, computeInputHash, computeOutputHash, createClient, createSnapshot, exportCer, fetchNodeKeys, getAttestationReceipt, hasAttestation, hashCanonicalJson, hashToolOutput, hashUtf8, importCer, makeToolEvent, mapToAiefReason, redactBeforeSeal, sanitizeForAttestation, sanitizeForStamp, sanitizeForStorage, sealCer, selectNodeKey, sha256Hex, toCanonicalJson, validateProfile, verifyCer as verify, verifyAief, verifyBundleAttestation, verifyCer, verifyNodeReceiptSignature, verifyRunSummary, verifySnapshot };
356
+ /**
357
+ * @nexart/ai-execution — Verifiable redacted export helper
358
+ *
359
+ * exportVerifiableRedacted() produces a NEW sealed bundle whose snapshot has
360
+ * sensitive fields replaced with redaction envelopes via redactBeforeSeal().
361
+ *
362
+ * The result is a fully independently verifiable bundle with a NEW certificateHash.
363
+ * The original certificateHash is preserved in meta.provenance as an informational
364
+ * cross-reference ONLY — it does not establish any cryptographic relationship
365
+ * between the two bundles.
366
+ *
367
+ * verify(newBundle) → { ok: true } ✅ the new bundle verifies on its own
368
+ * verify(originalBundle) → { ok: true } ✅ the original is unaffected
369
+ *
370
+ * IMPORTANT CONSTRAINTS:
371
+ * - Only `input` and `output` paths are safe to redact (their content hashes are
372
+ * recomputed from the envelope). Schema-validated string fields like `prompt`
373
+ * cannot be replaced with an object envelope — verify() will return SCHEMA_ERROR.
374
+ * - `meta.provenance.originalCertificateHash` is reference metadata only.
375
+ * Anyone who receives only the new bundle cannot verify the original's integrity.
376
+ */
377
+
378
+ interface ExportVerifiableRedactedOptions {
379
+ createdAt?: string;
380
+ }
381
+ interface ExportVerifiableRedactedProvenance {
382
+ originalCertificateHash: string;
383
+ redactionPolicy: {
384
+ paths: string[];
385
+ };
386
+ redactedAt: string;
387
+ }
388
+ interface ExportVerifiableRedactedResult {
389
+ bundle: CerAiExecutionBundle;
390
+ /**
391
+ * The original bundle's certificateHash. Convenience alias for
392
+ * `bundle.meta.provenance.originalCertificateHash`.
393
+ * Reference only — no cryptographic link to the new bundle.
394
+ */
395
+ originalCertificateHash: string;
396
+ }
397
+ /**
398
+ * Produce a new sealed bundle with redacted snapshot fields.
399
+ *
400
+ * @param bundle The original sealed bundle to redact from.
401
+ * @param policy Which snapshot paths to redact. Only 'input' and 'output'
402
+ * are safe for verifiable redaction (their content hashes are
403
+ * recomputed). Other schema-validated string fields will cause
404
+ * verify() to return SCHEMA_ERROR on the new bundle.
405
+ * @param options Optional overrides (createdAt).
406
+ *
407
+ * @example
408
+ * ```typescript
409
+ * import { certifyDecision, verify, exportVerifiableRedacted } from '@nexart/ai-execution';
410
+ *
411
+ * const original = certifyDecision({ ... });
412
+ * const { bundle, originalCertificateHash } = exportVerifiableRedacted(
413
+ * original,
414
+ * { paths: ['input', 'output'] },
415
+ * );
416
+ *
417
+ * verify(bundle).ok; // true
418
+ * bundle.meta.provenance.originalCertificateHash; // 'sha256:...' — reference only
419
+ * bundle.snapshot.input; // { _redacted: true, hash: 'sha256:...' }
420
+ * ```
421
+ */
422
+ declare function exportVerifiableRedacted(bundle: CerAiExecutionBundle, policy: RedactBeforeSealPolicy, options?: ExportVerifiableRedactedOptions): ExportVerifiableRedactedResult;
423
+
424
+ /**
425
+ * @nexart/ai-execution — Opinionated run helper
426
+ *
427
+ * certifyAndAttestRun(): certify every step in a multi-step run via RunBuilder,
428
+ * optionally attest each sealed bundle, and return a consolidated result.
429
+ *
430
+ * Design principles:
431
+ * - Does NOT mutate or wrap any externally-owned RunBuilder. Creates its own.
432
+ * - RunBuilder semantics are unchanged: prevStepHash chaining is automatic.
433
+ * - attestStep is optional and injectable so callers can mock in tests without
434
+ * hitting the network.
435
+ * - Network failures from attestStep bubble up — wrap in try/catch for partial
436
+ * failure tolerance.
437
+ */
438
+
439
+ interface CertifyAndAttestRunOptions {
440
+ runId?: string;
441
+ workflowId?: string | null;
442
+ conversationId?: string | null;
443
+ appId?: string | null;
444
+ /**
445
+ * Optional per-step attestation function. Receives each sealed step bundle
446
+ * immediately after it is created. Return an AttestationReceipt on success.
447
+ *
448
+ * If omitted, all receipts will be null (bundles are sealed but not attested).
449
+ *
450
+ * @example
451
+ * ```typescript
452
+ * import { attest } from '@nexart/ai-execution';
453
+ * certifyAndAttestRun(steps, {
454
+ * attestStep: (bundle) => attest(bundle, { nodeUrl, apiKey }),
455
+ * });
456
+ * ```
457
+ */
458
+ attestStep?: (bundle: CerAiExecutionBundle) => Promise<AttestationReceipt>;
459
+ }
460
+ interface CertifyAndAttestRunResult {
461
+ runSummary: RunSummary;
462
+ stepBundles: CerAiExecutionBundle[];
463
+ /**
464
+ * Attestation receipts in step order. `null` at index i means the step
465
+ * was sealed but not attested (no `attestStep` option was provided).
466
+ */
467
+ receipts: (AttestationReceipt | null)[];
468
+ /** Alias for runSummary.finalStepHash — the last step's certificateHash. */
469
+ finalStepHash: string | null;
470
+ }
471
+ /**
472
+ * Certify every step in a multi-step run and optionally attest each bundle.
473
+ *
474
+ * Each step is sealed via RunBuilder, which automatically:
475
+ * - assigns stepIndex (0-based)
476
+ * - sets prevStepHash to the previous step's certificateHash
477
+ * - assigns a unique executionId and stepId per step
478
+ *
479
+ * The resulting runSummary + stepBundles can be validated offline with
480
+ * verifyRunSummary(runSummary, stepBundles).
481
+ *
482
+ * @param steps Ordered list of step parameters (step 0 first).
483
+ * @param options Run-level options and optional attestation hook.
484
+ *
485
+ * @example
486
+ * ```typescript
487
+ * import { certifyAndAttestRun, verifyRunSummary } from '@nexart/ai-execution';
488
+ *
489
+ * const { runSummary, stepBundles, receipts, finalStepHash } =
490
+ * await certifyAndAttestRun(
491
+ * [step0Params, step1Params, step2Params],
492
+ * {
493
+ * runId: 'analysis-run',
494
+ * workflowId: 'data-pipeline',
495
+ * attestStep: (bundle) => attest(bundle, { nodeUrl, apiKey }),
496
+ * },
497
+ * );
498
+ *
499
+ * verifyRunSummary(runSummary, stepBundles); // { ok: true }
500
+ * ```
501
+ */
502
+ declare function certifyAndAttestRun(steps: StepParams[], options?: CertifyAndAttestRunOptions): Promise<CertifyAndAttestRunResult>;
503
+
504
+ export { AiExecutionSnapshotV1, AiefProfile, AiefVerifyResult, AttestOptions, AttestationReceipt, AttestationResult, BundleDeclaration, CerAiExecutionBundle, CerAttestationError, CerMeta, CerVerificationError, CerVerifyCode, CerVerifyCode as CerVerifyCodeType, type CertifyAndAttestRunOptions, type CertifyAndAttestRunResult, CertifyDecisionParams, CreateSnapshotParams, type ExportVerifiableRedactedOptions, type ExportVerifiableRedactedProvenance, type ExportVerifiableRedactedResult, type MakeToolEventParams, NodeKeysDocument, NodeReceiptVerifyResult, type ProfileValidationResult, type RedactBeforeSealPolicy, RunBuilder, RunBuilderOptions, RunSummary, RunSummaryVerifyResult, SanitizeStorageOptions, SignedAttestationReceipt, StepParams, ToolEvent, VerificationResult, type VerifyRunSummaryOptions, attest, attestIfNeeded, certifyAndAttestDecision, certifyAndAttestRun, certifyDecision, certifyDecisionFromProviderCall, computeInputHash, computeOutputHash, createClient, createSnapshot, exportCer, exportVerifiableRedacted, fetchNodeKeys, getAttestationReceipt, hasAttestation, hashCanonicalJson, hashToolOutput, hashUtf8, importCer, makeToolEvent, mapToAiefReason, redactBeforeSeal, sanitizeForAttestation, sanitizeForStamp, sanitizeForStorage, sealCer, selectNodeKey, sha256Hex, toCanonicalJson, validateProfile, verifyCer as verify, verifyAief, verifyBundleAttestation, verifyCer, verifyNodeReceiptSignature, verifyRunSummary, verifySnapshot };
package/dist/index.mjs CHANGED
@@ -114,7 +114,7 @@ function computeOutputHash(output) {
114
114
  }
115
115
 
116
116
  // src/snapshot.ts
117
- var PACKAGE_VERSION = "0.7.0";
117
+ var PACKAGE_VERSION = "0.8.0";
118
118
  function validateParameters(params) {
119
119
  const errors = [];
120
120
  if (typeof params.temperature !== "number" || !Number.isFinite(params.temperature)) {
@@ -2410,6 +2410,59 @@ function validateProfile(target, profile) {
2410
2410
  }
2411
2411
  return { ok: errors.length === 0, errors };
2412
2412
  }
2413
+
2414
+ // src/exportRedacted.ts
2415
+ function exportVerifiableRedacted(bundle, policy, options) {
2416
+ const createdAt = options?.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
2417
+ const redactedSnapshot = redactBeforeSeal(bundle.snapshot, policy);
2418
+ const provenance = {
2419
+ originalCertificateHash: bundle.certificateHash,
2420
+ redactionPolicy: { paths: [...policy.paths] },
2421
+ redactedAt: createdAt
2422
+ };
2423
+ const mergedMeta = {
2424
+ ...bundle.meta,
2425
+ provenance
2426
+ };
2427
+ const newBundle = sealCer(redactedSnapshot, {
2428
+ createdAt,
2429
+ meta: mergedMeta,
2430
+ declaration: bundle.declaration
2431
+ });
2432
+ return {
2433
+ bundle: newBundle,
2434
+ originalCertificateHash: bundle.certificateHash
2435
+ };
2436
+ }
2437
+
2438
+ // src/runHelper.ts
2439
+ async function certifyAndAttestRun(steps, options) {
2440
+ const run = new RunBuilder({
2441
+ runId: options?.runId,
2442
+ workflowId: options?.workflowId,
2443
+ conversationId: options?.conversationId,
2444
+ appId: options?.appId
2445
+ });
2446
+ const stepBundles = [];
2447
+ const receipts = [];
2448
+ for (const stepParams of steps) {
2449
+ const bundle = run.step(stepParams);
2450
+ stepBundles.push(bundle);
2451
+ if (options?.attestStep) {
2452
+ const receipt = await options.attestStep(bundle);
2453
+ receipts.push(receipt);
2454
+ } else {
2455
+ receipts.push(null);
2456
+ }
2457
+ }
2458
+ const runSummary = run.finalize();
2459
+ return {
2460
+ runSummary,
2461
+ stepBundles,
2462
+ receipts,
2463
+ finalStepHash: runSummary.finalStepHash
2464
+ };
2465
+ }
2413
2466
  export {
2414
2467
  CerAttestationError,
2415
2468
  CerVerificationError,
@@ -2418,6 +2471,7 @@ export {
2418
2471
  attest,
2419
2472
  attestIfNeeded,
2420
2473
  certifyAndAttestDecision,
2474
+ certifyAndAttestRun,
2421
2475
  certifyDecision,
2422
2476
  certifyDecisionFromProviderCall,
2423
2477
  computeInputHash,
@@ -2425,6 +2479,7 @@ export {
2425
2479
  createClient,
2426
2480
  createSnapshot,
2427
2481
  exportCer,
2482
+ exportVerifiableRedacted,
2428
2483
  fetchNodeKeys,
2429
2484
  getAttestationReceipt,
2430
2485
  hasAttestation,