@absolutejs/voice 0.0.22-beta.258 → 0.0.22-beta.259

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.
@@ -77,6 +77,44 @@ export type VoiceDataControlReport = {
77
77
  providerKeys: VoiceDataControlProviderKeySurface[];
78
78
  zeroRetentionAvailable: boolean;
79
79
  };
80
+ export type VoiceDataControlAssertionInput = {
81
+ maxDeletionDeleted?: number;
82
+ maxMissingConfiguredStorage?: number;
83
+ maxMissingSelfHostedStorage?: number;
84
+ maxRetentionDeleted?: number;
85
+ minAuditExportEvents?: number;
86
+ minConfiguredStorage?: number;
87
+ minProviderKeys?: number;
88
+ requiredControls?: VoiceDataControlStorageSurface['control'][];
89
+ requiredDeletionScopes?: VoiceDataRetentionScope[];
90
+ requiredProviderKeys?: string[];
91
+ requiredRetentionScopes?: VoiceDataRetentionScope[];
92
+ requiredStorage?: string[];
93
+ requireAuditExport?: boolean;
94
+ requireDeletionDryRun?: boolean;
95
+ requireDeletionProof?: boolean;
96
+ requireRedaction?: boolean;
97
+ requireRetentionDryRun?: boolean;
98
+ requireSelfHostedStorage?: boolean;
99
+ requireZeroRetentionAvailable?: boolean;
100
+ };
101
+ export type VoiceDataControlAssertionReport = {
102
+ auditExportEvents: number;
103
+ configuredStorage: string[];
104
+ controls: VoiceDataControlStorageSurface['control'][];
105
+ deletionDeleted: number;
106
+ deletionDryRun?: boolean;
107
+ deletionScopes: VoiceDataRetentionScope[];
108
+ issues: string[];
109
+ ok: boolean;
110
+ providerKeys: string[];
111
+ redactionEnabled: boolean;
112
+ retentionDeleted: number;
113
+ retentionDryRun: boolean;
114
+ retentionScopes: VoiceDataRetentionScope[];
115
+ selfHostedConfiguredStorage: string[];
116
+ zeroRetentionAvailable: boolean;
117
+ };
80
118
  export type VoiceDataControlRoutesOptions = VoiceDataRetentionStores & {
81
119
  audit?: VoiceAuditEventStore;
82
120
  auditActor?: VoiceAuditActor;
@@ -91,6 +129,8 @@ export type VoiceDataControlRoutesOptions = VoiceDataRetentionStores & {
91
129
  };
92
130
  export declare const applyVoiceDataRetentionPolicy: (options: VoiceDataRetentionPolicy) => Promise<VoiceDataRetentionReport>;
93
131
  export declare const buildVoiceDataRetentionPlan: (options: Omit<VoiceDataRetentionPolicy, "dryRun">) => Promise<VoiceDataRetentionReport>;
132
+ export declare const evaluateVoiceDataControlEvidence: (report: VoiceDataControlReport, input?: VoiceDataControlAssertionInput) => VoiceDataControlAssertionReport;
133
+ export declare const assertVoiceDataControlEvidence: (report: VoiceDataControlReport, input?: VoiceDataControlAssertionInput) => VoiceDataControlAssertionReport;
94
134
  export declare const createVoiceZeroRetentionPolicy: (options: VoiceDataRetentionStores & {
95
135
  audit?: VoiceAuditEventStore;
96
136
  auditActor?: VoiceAuditActor;
package/dist/index.d.ts CHANGED
@@ -21,8 +21,8 @@ export type { VoiceProofTrendAssertionInput, VoiceProofTrendAssertionReport, Voi
21
21
  export { buildVoiceLiveOpsControlState, createVoiceLiveOpsController, createVoiceLiveOpsRoutes, createVoiceMemoryLiveOpsControlStore, getVoiceLiveOpsControlStatus, VOICE_LIVE_OPS_ACTIONS } from './liveOps';
22
22
  export type { VoiceLiveOpsAction, VoiceLiveOpsActionInput, VoiceLiveOpsActionResult, VoiceLiveOpsControllerOptions, VoiceLiveOpsControlState, VoiceLiveOpsControlStatus, VoiceLiveOpsControlStore, VoiceLiveOpsRoutesOptions } from './liveOps';
23
23
  export { buildVoiceDeliveryRuntimeReport, createVoiceDeliveryRuntime, createVoiceDeliveryRuntimePresetConfig, createVoiceDeliveryRuntimeRoutes, renderVoiceDeliveryRuntimeHTML } from './deliveryRuntime';
24
- export { applyVoiceDataRetentionPolicy, buildVoiceDataControlReport, buildVoiceDataRetentionPlan, createVoiceDataControlRoutes, createVoiceZeroRetentionPolicy, renderVoiceDataControlHTML, renderVoiceDataControlMarkdown, voiceComplianceRedactionDefaults } from './dataControl';
25
- export type { VoiceDataControlProviderKeySurface, VoiceDataControlReport, VoiceDataControlRoutesOptions, VoiceDataControlStorageSurface, VoiceDataRetentionPolicy, VoiceDataRetentionReport, VoiceDataRetentionScope, VoiceDataRetentionScopeReport, VoiceDataRetentionStores } from './dataControl';
24
+ export { applyVoiceDataRetentionPolicy, assertVoiceDataControlEvidence, buildVoiceDataControlReport, buildVoiceDataRetentionPlan, createVoiceDataControlRoutes, createVoiceZeroRetentionPolicy, evaluateVoiceDataControlEvidence, renderVoiceDataControlHTML, renderVoiceDataControlMarkdown, voiceComplianceRedactionDefaults } from './dataControl';
25
+ export type { VoiceDataControlAssertionInput, VoiceDataControlAssertionReport, VoiceDataControlProviderKeySurface, VoiceDataControlReport, VoiceDataControlRoutesOptions, VoiceDataControlStorageSurface, VoiceDataRetentionPolicy, VoiceDataRetentionReport, VoiceDataRetentionScope, VoiceDataRetentionScopeReport, VoiceDataRetentionStores } from './dataControl';
26
26
  export type { VoiceDemoReadyReport, VoiceDemoReadyRoutesOptions, VoiceDemoReadySection, VoiceDemoReadyStatus } from './demoReadyRoutes';
27
27
  export type { VoiceDeliverySinkDescriptor, VoiceDeliverySinkDescriptorInput, VoiceDeliverySinkKind, VoiceDeliverySinkPairOptions, VoiceDeliverySinkReport, VoiceDeliverySinkRoutesOptions, VoiceTraceDeliverySinkSurface } from './deliverySinkRoutes';
28
28
  export type { VoiceOpsActionAuditRecord, VoiceOpsActionAuditRoutesOptions, VoiceOpsActionHistoryEntry, VoiceOpsActionHistoryReport } from './opsActionAuditRoutes';
package/dist/index.js CHANGED
@@ -13422,6 +13422,127 @@ var defaultProviderKeys = [
13422
13422
  }
13423
13423
  ];
13424
13424
  var resolveDataControlRedaction = (redact) => redact === false ? undefined : redact === true || redact === undefined ? voiceComplianceRedactionDefaults : redact;
13425
+ var uniqueSorted = (values) => Array.from(new Set(values)).sort();
13426
+ var findMissing = (values, required) => {
13427
+ if (!required?.length) {
13428
+ return [];
13429
+ }
13430
+ const valueSet = new Set(values);
13431
+ return required.filter((value) => !valueSet.has(value));
13432
+ };
13433
+ var evaluateVoiceDataControlEvidence = (report, input = {}) => {
13434
+ const issues = [];
13435
+ const configuredStorage = report.storage.filter((surface) => surface.configured).map((surface) => surface.name);
13436
+ const selfHostedConfiguredStorage = report.storage.filter((surface) => surface.configured && surface.selfHosted).map((surface) => surface.name);
13437
+ const controls = uniqueSorted(report.storage.filter((surface) => surface.configured).map((surface) => surface.control));
13438
+ const retentionScopes = uniqueSorted(report.retentionPlan.scopes.map((scope) => scope.scope));
13439
+ const deletionScopes = uniqueSorted(report.deletionProof?.scopes.map((scope) => scope.scope) ?? []);
13440
+ const providerKeys = uniqueSorted(report.providerKeys.map((key) => key.name.toLowerCase()));
13441
+ const auditExportEvents = report.auditExport?.events.length ?? 0;
13442
+ const deletionDeleted = report.deletionProof?.deletedCount ?? 0;
13443
+ const maxRetentionDeleted = input.maxRetentionDeleted;
13444
+ const maxDeletionDeleted = input.maxDeletionDeleted;
13445
+ const requireAuditExport = input.requireAuditExport ?? true;
13446
+ const requireDeletionDryRun = input.requireDeletionDryRun ?? true;
13447
+ const requireDeletionProof = input.requireDeletionProof ?? false;
13448
+ const requireRedaction = input.requireRedaction ?? true;
13449
+ const requireRetentionDryRun = input.requireRetentionDryRun ?? true;
13450
+ const requireSelfHostedStorage = input.requireSelfHostedStorage ?? true;
13451
+ const requireZeroRetentionAvailable = input.requireZeroRetentionAvailable ?? true;
13452
+ if (requireRedaction && !report.redaction.enabled) {
13453
+ issues.push("Expected data-control redaction to be enabled.");
13454
+ }
13455
+ if (requireZeroRetentionAvailable && !report.zeroRetentionAvailable) {
13456
+ issues.push("Expected zero-retention policy recipe to be available.");
13457
+ }
13458
+ if (requireAuditExport && !report.auditExport) {
13459
+ issues.push("Expected redacted audit export to be available.");
13460
+ }
13461
+ if (input.minAuditExportEvents !== undefined && auditExportEvents < input.minAuditExportEvents) {
13462
+ issues.push(`Expected at least ${String(input.minAuditExportEvents)} audit export events, found ${String(auditExportEvents)}.`);
13463
+ }
13464
+ if (requireRetentionDryRun && !report.retentionPlan.dryRun) {
13465
+ issues.push("Expected retention plan to run in dry-run mode.");
13466
+ }
13467
+ if (maxRetentionDeleted !== undefined && report.retentionPlan.deletedCount > maxRetentionDeleted) {
13468
+ issues.push(`Expected retention plan to delete at most ${String(maxRetentionDeleted)} records, found ${String(report.retentionPlan.deletedCount)}.`);
13469
+ }
13470
+ if (requireDeletionProof && !report.deletionProof) {
13471
+ issues.push("Expected deletion proof to be present.");
13472
+ }
13473
+ if (report.deletionProof && requireDeletionDryRun && !report.deletionProof.dryRun) {
13474
+ issues.push("Expected deletion proof to run in dry-run mode.");
13475
+ }
13476
+ if (maxDeletionDeleted !== undefined && deletionDeleted > maxDeletionDeleted) {
13477
+ issues.push(`Expected deletion proof to delete at most ${String(maxDeletionDeleted)} records, found ${String(deletionDeleted)}.`);
13478
+ }
13479
+ if (input.minConfiguredStorage !== undefined && configuredStorage.length < input.minConfiguredStorage) {
13480
+ issues.push(`Expected at least ${String(input.minConfiguredStorage)} configured storage surfaces, found ${String(configuredStorage.length)}.`);
13481
+ }
13482
+ if (requireSelfHostedStorage) {
13483
+ const nonSelfHostedConfigured = configuredStorage.length - selfHostedConfiguredStorage.length;
13484
+ if (nonSelfHostedConfigured > (input.maxMissingSelfHostedStorage ?? 0)) {
13485
+ issues.push(`Expected configured storage to be self-hosted, found ${String(nonSelfHostedConfigured)} non-self-hosted surfaces.`);
13486
+ }
13487
+ }
13488
+ const missingConfiguredStorage = findMissing(configuredStorage, input.requiredStorage);
13489
+ if (missingConfiguredStorage.length > (input.maxMissingConfiguredStorage ?? 0)) {
13490
+ issues.push(`Missing configured storage surfaces: ${missingConfiguredStorage.join(", ")}.`);
13491
+ }
13492
+ for (const control of findMissing(controls, input.requiredControls)) {
13493
+ issues.push(`Missing configured storage control: ${control}.`);
13494
+ }
13495
+ for (const scope of findMissing(retentionScopes, input.requiredRetentionScopes)) {
13496
+ issues.push(`Missing retention scope: ${scope}.`);
13497
+ }
13498
+ for (const scope of input.requiredRetentionScopes ?? []) {
13499
+ const retentionScope = report.retentionPlan.scopes.find((candidate) => candidate.scope === scope);
13500
+ if (retentionScope?.skippedReason) {
13501
+ issues.push(`Retention scope ${scope} was skipped: ${retentionScope.skippedReason}.`);
13502
+ }
13503
+ }
13504
+ for (const scope of findMissing(deletionScopes, input.requiredDeletionScopes)) {
13505
+ issues.push(`Missing deletion-proof scope: ${scope}.`);
13506
+ }
13507
+ for (const scope of input.requiredDeletionScopes ?? []) {
13508
+ const deletionScope = report.deletionProof?.scopes.find((candidate) => candidate.scope === scope);
13509
+ if (deletionScope?.skippedReason) {
13510
+ issues.push(`Deletion-proof scope ${scope} was skipped: ${deletionScope.skippedReason}.`);
13511
+ }
13512
+ }
13513
+ for (const provider of input.requiredProviderKeys ?? []) {
13514
+ if (!providerKeys.includes(provider.toLowerCase())) {
13515
+ issues.push(`Missing provider-key guidance: ${provider}.`);
13516
+ }
13517
+ }
13518
+ if (input.minProviderKeys !== undefined && providerKeys.length < input.minProviderKeys) {
13519
+ issues.push(`Expected at least ${String(input.minProviderKeys)} provider-key guidance entries, found ${String(providerKeys.length)}.`);
13520
+ }
13521
+ return {
13522
+ auditExportEvents,
13523
+ configuredStorage: configuredStorage.sort(),
13524
+ controls,
13525
+ deletionDeleted,
13526
+ deletionDryRun: report.deletionProof?.dryRun,
13527
+ deletionScopes,
13528
+ issues,
13529
+ ok: issues.length === 0,
13530
+ providerKeys,
13531
+ redactionEnabled: report.redaction.enabled,
13532
+ retentionDeleted: report.retentionPlan.deletedCount,
13533
+ retentionDryRun: report.retentionPlan.dryRun,
13534
+ retentionScopes,
13535
+ selfHostedConfiguredStorage: selfHostedConfiguredStorage.sort(),
13536
+ zeroRetentionAvailable: report.zeroRetentionAvailable
13537
+ };
13538
+ };
13539
+ var assertVoiceDataControlEvidence = (report, input = {}) => {
13540
+ const assertion = evaluateVoiceDataControlEvidence(report, input);
13541
+ if (!assertion.ok) {
13542
+ throw new Error(`Voice data-control evidence assertion failed: ${assertion.issues.join(" ")}`);
13543
+ }
13544
+ return assertion;
13545
+ };
13425
13546
  var createVoiceZeroRetentionPolicy = (options) => ({
13426
13547
  ...options,
13427
13548
  beforeOrAt: options.beforeOrAt ?? Date.now(),
@@ -22686,7 +22807,7 @@ var statusRank = {
22686
22807
  var escapeHtml36 = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
22687
22808
  var roundMetric3 = (value) => Math.round(value * 1e4) / 1e4;
22688
22809
  var rate3 = (count, total) => count / Math.max(1, total);
22689
- var uniqueSorted = (values) => [
22810
+ var uniqueSorted2 = (values) => [
22690
22811
  ...new Set(values.filter((value) => typeof value === "string"))
22691
22812
  ].sort();
22692
22813
  var percentile3 = (values, rank) => {
@@ -22869,7 +22990,7 @@ var buildVoiceProviderSloReport = async (options = {}) => {
22869
22990
  var evaluateVoiceProviderSloEvidence = (report, input = {}) => {
22870
22991
  const issues = [];
22871
22992
  const kindReports = Object.values(report.kinds);
22872
- const providers = uniqueSorted(kindReports.flatMap((kind) => kind.providers));
22993
+ const providers = uniqueSorted2(kindReports.flatMap((kind) => kind.providers));
22873
22994
  const kinds = providerKinds.filter((kind) => report.kinds[kind].events > 0);
22874
22995
  const fallbacks = kindReports.reduce((total, kind) => total + kind.fallbacks, 0);
22875
22996
  const timeouts = kindReports.reduce((total, kind) => total + kind.timeouts, 0);
@@ -23590,7 +23711,7 @@ var hasPayloadValue = (payload, key, values) => {
23590
23711
  return typeof value === "string" && values.has(value);
23591
23712
  };
23592
23713
  var countIntegrationDeliveryStatus = (events, status) => events.filter((event) => event.deliveryStatus === status).length;
23593
- var uniqueSorted2 = (values) => [
23714
+ var uniqueSorted3 = (values) => [
23594
23715
  ...new Set(values.filter((value) => typeof value === "string"))
23595
23716
  ].sort();
23596
23717
  var pushMissingValuesIssue = (input) => {
@@ -23769,11 +23890,11 @@ var buildVoiceOperationsRecord = async (options) => {
23769
23890
  var evaluateVoiceOperationsRecordGuardrails = (record, input = {}) => {
23770
23891
  const issues = [];
23771
23892
  const decisions = record.guardrails.decisions;
23772
- const proofs = uniqueSorted2(decisions.map((decision) => decision.proof));
23773
- const ruleIds = uniqueSorted2(decisions.flatMap((decision) => decision.findings.map((finding) => finding.ruleId)));
23774
- const stages = uniqueSorted2(decisions.map((decision) => decision.stage));
23775
- const statuses = uniqueSorted2(decisions.map((decision) => decision.status));
23776
- const toolNames = uniqueSorted2(decisions.map((decision) => decision.toolName));
23893
+ const proofs = uniqueSorted3(decisions.map((decision) => decision.proof));
23894
+ const ruleIds = uniqueSorted3(decisions.flatMap((decision) => decision.findings.map((finding) => finding.ruleId)));
23895
+ const stages = uniqueSorted3(decisions.map((decision) => decision.stage));
23896
+ const statuses = uniqueSorted3(decisions.map((decision) => decision.status));
23897
+ const toolNames = uniqueSorted3(decisions.map((decision) => decision.toolName));
23777
23898
  const minDecisions = input.minDecisions ?? 1;
23778
23899
  if (record.guardrails.total < minDecisions) {
23779
23900
  issues.push(`Expected at least ${String(minDecisions)} guardrail decisions, found ${String(record.guardrails.total)}.`);
@@ -31026,6 +31147,7 @@ export {
31026
31147
  evaluateVoiceObservabilityExportReplayEvidence,
31027
31148
  evaluateVoiceObservabilityExportDeliveryEvidence,
31028
31149
  evaluateVoiceGuardrailPolicy,
31150
+ evaluateVoiceDataControlEvidence,
31029
31151
  evaluateVoiceCampaignReadinessEvidence,
31030
31152
  evaluateVoiceCampaignDialerProofEvidence,
31031
31153
  evaluateVoiceAgentSquadContractEvidence,
@@ -31357,6 +31479,7 @@ export {
31357
31479
  assertVoiceObservabilityExportRecord,
31358
31480
  assertVoiceObservabilityExportDeliveryEvidence,
31359
31481
  assertVoiceLatencySLOGate,
31482
+ assertVoiceDataControlEvidence,
31360
31483
  assertVoiceCampaignReadinessEvidence,
31361
31484
  assertVoiceCampaignDialerProofEvidence,
31362
31485
  assertVoiceAgentSquadContractEvidence,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.258",
3
+ "version": "0.0.22-beta.259",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",