witnora 0.18.13 → 0.18.15

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/gateway.js CHANGED
@@ -136,7 +136,9 @@ export async function upgradeCustomerGatewayRuntime(options) {
136
136
  const current = parseConfig(configRaw);
137
137
  if (current.projectId !== options.authorization.projectId || current.server !== options.authorization.server)
138
138
  throw new Error("Existing Gateway project/server binding does not match this authorized Runtime upgrade.");
139
- const generatedClient = clientRaw === gatewayClient(current)
139
+ const exactCurrentClient = clientRaw === gatewayClient(current);
140
+ const generatedClient = exactCurrentClient
141
+ || (current.agentIdentity?.externalId !== current.connectionName && clientRaw === gatewayClient(current, current.connectionName))
140
142
  || (!current.runtimeWorker && (clientRaw === recordedGatewayClient(current)
141
143
  || clientRaw === recordedGatewayClient({ ...current, agentIdentity: undefined })));
142
144
  if (!generatedClient || readmeRaw !== gatewayReadme(current))
@@ -162,7 +164,8 @@ export async function upgradeCustomerGatewayRuntime(options) {
162
164
  || createHash("sha256").update(probeBytes).digest("hex") !== current.runtimeWorker.probeModuleSha256) {
163
165
  throw new Error("Existing generated Runtime modules were modified; refusing to overwrite them.");
164
166
  }
165
- if (sameRuntimeGeneration(current.runtimeWorker, next.runtimeWorker)
167
+ if (exactCurrentClient
168
+ && sameRuntimeGeneration(current.runtimeWorker, next.runtimeWorker)
166
169
  && JSON.stringify(current.agentIdentity) === JSON.stringify(next.agentIdentity)) {
167
170
  return { config: current, generatedFiles: [], changed: false, rollback: async () => undefined };
168
171
  }
@@ -549,7 +552,7 @@ export async function runCustomerGateway(options) {
549
552
  keyRing,
550
553
  gatewayToken: secrets.gatewayToken,
551
554
  storageDirectory: dataDirectory,
552
- agentExternalId: config.connectionName,
555
+ agentExternalId: config.agentIdentity?.externalId ?? config.connectionName,
553
556
  host: process.env.WITNORA_GATEWAY_HOST?.trim() || config.host,
554
557
  port: gatewayPort(process.env.WITNORA_GATEWAY_PORT, config.port),
555
558
  environment: "customer-owned",
@@ -705,10 +708,10 @@ export async function createConfiguredWorkflowHarness(input) {
705
708
  readOutcome: async ({ resourceId, actions, receipts }) => input.managed.readLocalSandboxRuntimeWatchOutcome({
706
709
  path: join(input.directory, "data", "runtime-sandbox", "fixture", "audit.jsonl"),
707
710
  resourceId,
708
- actions: actions.map((action) => ({
709
- id: action.id,
710
- executionSessionId: receipts.find((receipt) => receipt.actionId === action.id)?.receipt?.core?.executionSessionId ?? "",
711
- })),
711
+ actions: actions.map((action) => {
712
+ const executionSessionId = receipts.find((receipt) => receipt.actionId === action.id)?.receipt?.core?.executionSessionId;
713
+ return { id: action.id, ...(executionSessionId ? { executionSessionId } : {}) };
714
+ }),
712
715
  }),
713
716
  })
714
717
  : undefined;
@@ -1680,11 +1683,11 @@ function localSandboxOrigin(value) {
1680
1683
  return false;
1681
1684
  }
1682
1685
  }
1683
- function gatewayClient(config) {
1686
+ function gatewayClient(config, localSandboxAgentId = config.agentIdentity?.externalId ?? config.connectionName) {
1684
1687
  const requestHelper = `async function actionRequest(path, init = {}) {\n const headers = new Headers(init.headers);\n headers.set("authorization", \`Bearer \${await token()}\`);\n if (init.body) headers.set("content-type", "application/json");\n const response = await fetch(\`\${baseUrl}\${path}\`, { ...init, headers });\n const result = await response.json().catch(() => ({}));\n if (!response.ok) throw new Error(result.error ?? \`Witnora Gateway returned HTTP \${response.status}.\`);\n return result;\n}\n`;
1685
1688
  const actionMethods = ` proposeAction(proposal, idempotencyKey = proposal?.externalId) {\n if (typeof idempotencyKey !== "string" || !idempotencyKey) throw new Error("Witnora action proposal requires an idempotency key or externalId.");\n return actionRequest("/v1/actions", { method: "POST", body: JSON.stringify({ proposal, idempotencyKey }) });\n },\n getAction(actionId) {\n if (!/^[A-Za-z0-9._:-]+$/.test(actionId)) throw new Error("Witnora actionId contains unsupported characters.");\n return actionRequest(\`/v1/actions/\${encodeURIComponent(actionId)}\`);\n },\n issueExecutionGrant(actionId, grant, idempotencyKey = \`grant:\${actionId}\`) {\n if (!/^[A-Za-z0-9._:-]+$/.test(actionId)) throw new Error("Witnora actionId contains unsupported characters.");\n return actionRequest(\`/v1/actions/\${encodeURIComponent(actionId)}/execution-grant\`, { method: "POST", body: JSON.stringify({ grant, idempotencyKey }) });\n },\n`;
1686
1689
  const localSandboxMethod = config.runtimeWorker?.adapterId === LOCAL_SANDBOX_ADAPTER_ID && config.runtimeWorker.mandateId && config.runtimeWorker.sandboxPrincipalId
1687
- ? ` async proposeLocalSandboxUpdate({ resourceId, status = "UPDATED", externalId = \`runtime-sandbox-\${crypto.randomUUID()}\`, agentBuildId = "witnora-local-sandbox-task@1.0.0" }) {\n if (!/^[A-Za-z0-9._:-]+$/.test(resourceId)) throw new Error("Local sandbox resourceId contains unsupported characters.");\n const approvedParameters = { resourceId, status };\n const digest = Buffer.from(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(agentBuildId))).toString("hex");\n const proposal = {\n externalId, agentId: "${config.connectionName}", principal: { id: "${config.runtimeWorker.sandboxPrincipalId}", version: "sandbox-v1" },\n actionType: "UPDATE", targetSystem: "WitnoraLocalSandbox", requestedPermissions: [], sensitive: true, expectedState: approvedParameters,\n mandateId: "${config.runtimeWorker.mandateId}", requireMandate: true,\n executionIntent: { adapterId: "${LOCAL_SANDBOX_ADAPTER_ID}", adapterVersionConstraint: "^${LOCAL_SANDBOX_ADAPTER_VERSION}", allowedOrigins: ["${config.runtimeWorker.sandboxOrigin}"], approvedParameters, outcomePredicate: { type: "state_subset", expected: approvedParameters }, agentBuildId, agentBuildDigest: digest, allowedOperation: "UPDATE", allowedResource: \`mock-state/\${resourceId}\` },\n };\n return this.proposeAction(proposal, externalId);\n },\n`
1690
+ ? ` async proposeLocalSandboxUpdate({ resourceId, status = "UPDATED", externalId = \`runtime-sandbox-\${crypto.randomUUID()}\`, agentBuildId = "witnora-local-sandbox-task@1.0.0" }) {\n if (!/^[A-Za-z0-9._:-]+$/.test(resourceId)) throw new Error("Local sandbox resourceId contains unsupported characters.");\n const approvedParameters = { resourceId, status };\n const digest = Buffer.from(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(agentBuildId))).toString("hex");\n const proposal = {\n externalId, agentId: "${localSandboxAgentId}", principal: { id: "${config.runtimeWorker.sandboxPrincipalId}", version: "sandbox-v1" },\n actionType: "UPDATE", targetSystem: "WitnoraLocalSandbox", requestedPermissions: [], sensitive: true, expectedState: approvedParameters,\n mandateId: "${config.runtimeWorker.mandateId}", requireMandate: true,\n executionIntent: { adapterId: "${LOCAL_SANDBOX_ADAPTER_ID}", adapterVersionConstraint: "^${LOCAL_SANDBOX_ADAPTER_VERSION}", allowedOrigins: ["${config.runtimeWorker.sandboxOrigin}"], approvedParameters, outcomePredicate: { type: "state_subset", expected: approvedParameters }, agentBuildId, agentBuildDigest: digest, allowedOperation: "UPDATE", allowedResource: \`mock-state/\${resourceId}\` },\n };\n return this.proposeAction(proposal, externalId);\n },\n`
1688
1691
  : "";
1689
1692
  const realPathSandboxMethod = config.runtimeWorker?.adapterId === LOCAL_SANDBOX_ADAPTER_ID && config.runtimeWorker.mandateId && config.runtimeWorker.sandboxPrincipalId
1690
1693
  ? ` async proposeRealPathSandboxSimulation({ integrationId, resourceId, status = "SUBMITTED", externalId = \`real-path-sandbox-\${crypto.randomUUID()}\`, agentBuildId = "witnora-real-path-sandbox@1.0.0" }) {\n if (!/^[A-Za-z0-9._:-]+$/.test(integrationId) || !/^[A-Za-z0-9._:-]+$/.test(resourceId)) throw new Error("Real-path integrationId and resourceId must be identifiers.");\n const harness = JSON.parse(await readFile(new URL("./workflow-harness.json", import.meta.url), "utf8"));\n const matches = Array.isArray(harness.realPathActivations) ? harness.realPathActivations.filter((item) => item?.integrationId === integrationId) : [];\n if (matches.length !== 1) throw new Error("Real-path sandbox simulation requires one exact active Harness integration.");\n const activation = matches[0];\n if (activation.environment !== "sandbox" || !Array.isArray(activation.actionPathIds) || activation.actionPathIds.length !== 1) throw new Error("Real-path sandbox simulation requires one exact sandbox action path.");\n const approvedParameters = { resourceId, status };\n const digest = Buffer.from(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(agentBuildId))).toString("hex");\n const proposal = {\n externalId, agentId: activation.agentId, principal: { id: "${config.runtimeWorker.sandboxPrincipalId}", version: "sandbox-v1" },\n actionType: "UPDATE", targetSystem: "WitnoraLocalSandbox", requestedPermissions: [], sensitive: true, expectedState: approvedParameters,\n businessTaskBinding: { taskContractId: activation.taskContractId, taskContractDigestSha256: activation.taskContractDigestSha256, actionPathId: activation.actionPathIds[0], environment: "sandbox", realPathIntegrationId: activation.integrationId, realPathIntegrationDigestSha256: activation.integrationDigestSha256 },\n mandateId: "${config.runtimeWorker.mandateId}", requireMandate: true,\n executionIntent: { adapterId: "${LOCAL_SANDBOX_ADAPTER_ID}", adapterVersionConstraint: "^${LOCAL_SANDBOX_ADAPTER_VERSION}", allowedOrigins: ["${config.runtimeWorker.sandboxOrigin}"], approvedParameters, outcomePredicate: { type: "state_subset", expected: approvedParameters }, agentBuildId, agentBuildDigest: digest, allowedOperation: "UPDATE", allowedResource: \`mock-state/\${resourceId}\` },\n };\n return this.proposeAction(proposal, externalId);\n },\n`
@@ -1 +1 @@
1
- {"version":3,"file":"collector-gateway.d.ts","sourceRoot":"","sources":["../../../../agentcert-sdk/src/collector-gateway.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"collector-gateway.d.ts","sourceRoot":"","sources":["../../../../agentcert-sdk/src/collector-gateway.ts"],"names":[],"mappings":"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"}
@@ -116,8 +116,9 @@ export async function startCustomerOwnedCollectorGateway(options) {
116
116
  }
117
117
  const hostedProposal = runtimeBinding ? { ...proposal, localRuntimeBinding: runtimeBinding } : proposal;
118
118
  const action = await options.client.proposeAction(hostedProposal, identifier(body.idempotencyKey, "idempotencyKey"));
119
- if (options.actionWorker)
119
+ if (options.actionWorker && action.externalId === proposal.externalId) {
120
120
  await options.actionWorker.track({ actionId: identifier(action.id, "actionId"), proposal });
121
+ }
121
122
  return json(response, 202, action);
122
123
  }
123
124
  const actionRoute = url.pathname.match(/^\/v1\/actions\/([A-Za-z0-9._:-]+)$/);
@@ -4,14 +4,17 @@ export interface FailureRuntimeWatchCase {
4
4
  id: string;
5
5
  projectId: string;
6
6
  status: "FIX_VERIFIED" | "RUNTIME_PROTECTED" | "REGRESSION_DETECTED" | string;
7
+ updatedAt?: string;
7
8
  definition: HostedFailureDefinition;
8
9
  discovery?: {
9
10
  discoveryKey?: string;
10
11
  };
11
12
  candidate?: {
12
13
  agentVersion: string;
14
+ recordedAt?: string;
13
15
  };
14
16
  runtimeWatch?: {
17
+ activatedAt?: string;
15
18
  receiptIds?: string[];
16
19
  latest?: {
17
20
  receiptIds?: string[];
@@ -21,6 +24,8 @@ export interface FailureRuntimeWatchCase {
21
24
  export interface FailureRuntimeWatchAction {
22
25
  id: string;
23
26
  status: string;
27
+ updatedAt?: string;
28
+ verificationSuccess?: boolean;
24
29
  expectedState?: Record<string, unknown>;
25
30
  businessTaskBinding?: {
26
31
  taskContractId?: string;
@@ -41,6 +46,7 @@ export interface FailureRuntimeWatchReceipt {
41
46
  executionSessionId?: string;
42
47
  };
43
48
  };
49
+ discoveryBoundary?: "SIGNED_VERIFIED_ACTION";
44
50
  }
45
51
  export interface FailureRuntimeWatchOutcome {
46
52
  classification: "HEALTHY" | "REGRESSION" | "INSUFFICIENT_EVIDENCE" | "CONNECTION_UNAVAILABLE" | "SCHEMA_DIGEST_DRIFT";
@@ -67,7 +73,7 @@ export interface FailureRuntimeWatchStatusInput {
67
73
  export interface FailureRuntimeWatchHostedClient {
68
74
  listFailureCases(): Promise<FailureRuntimeWatchCase[]>;
69
75
  listActions(): Promise<FailureRuntimeWatchAction[]>;
70
- listReceipts(): Promise<FailureRuntimeWatchReceipt[]>;
76
+ listReceipts(actions?: FailureRuntimeWatchAction[]): Promise<FailureRuntimeWatchReceipt[]>;
71
77
  uploadObservation(input: HostedFailureExperimentInput & {
72
78
  observedAt: string;
73
79
  }): Promise<unknown>;
@@ -131,7 +137,7 @@ export declare function readLocalSandboxRuntimeWatchOutcome(input: {
131
137
  resourceId: string;
132
138
  actions: Array<{
133
139
  id: string;
134
- executionSessionId: string;
140
+ executionSessionId?: string;
135
141
  }>;
136
142
  now?: () => Date;
137
143
  }): Promise<FailureRuntimeWatchOutcome>;
@@ -1 +1 @@
1
- {"version":3,"file":"failure-runtime-watch.d.ts","sourceRoot":"","sources":["../../../../onegent-runtime/src/failure-runtime-watch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"failure-runtime-watch.d.ts","sourceRoot":"","sources":["../../../../onegent-runtime/src/failure-runtime-watch.ts"],"names":[],"mappings":"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"}
@@ -8,10 +8,25 @@ export function createFailureRuntimeWatchHostedClient(options) {
8
8
  const apiKey = required(options.apiKey, "apiKey");
9
9
  const requestFetch = options.fetch ?? fetch;
10
10
  const projectUrl = `${baseUrl}/v1/projects/${encodeURIComponent(projectId)}`;
11
+ const receiptCache = new Map();
11
12
  return {
12
13
  listFailureCases: async () => list(await hostedJson(requestFetch, `${projectUrl}/failure-cases`, apiKey), "failureCases"),
13
14
  listActions: async () => list(await hostedJson(requestFetch, `${projectUrl}/actions`, apiKey), "actions"),
14
- listReceipts: async () => list(await hostedJson(requestFetch, `${projectUrl}/receipts`, apiKey), "receipts"),
15
+ listReceipts: async (actions = []) => {
16
+ const eligible = actions.filter((action) => action.status === "VERIFIED"
17
+ && action.verificationSuccess === true
18
+ && action.businessTaskBinding?.environment === "sandbox");
19
+ const discovered = await Promise.all(eligible.map(async (action) => {
20
+ const cached = receiptCache.get(action.id);
21
+ if (cached && cached.actionUpdatedAt === action.updatedAt)
22
+ return cached.receipts;
23
+ const detail = await hostedJson(requestFetch, `${projectUrl}/actions/${encodeURIComponent(required(action.id, "actionId"))}`, apiKey);
24
+ const receipts = signedVerifiedActionReceipt(detail);
25
+ receiptCache.set(action.id, { actionUpdatedAt: action.updatedAt, receipts });
26
+ return receipts;
27
+ }));
28
+ return discovered.flat();
29
+ },
15
30
  uploadObservation: async (input) => uploadFailureExperiment(input, { baseUrl, projectId, apiKey, fetch: requestFetch }),
16
31
  updateStatus: async (failureCaseId, input) => hostedJson(requestFetch, `${projectUrl}/failure-cases/${encodeURIComponent(required(failureCaseId, "failureCaseId"))}/runtime-watch-status`, apiKey, { method: "POST", body: JSON.stringify(input) }),
17
32
  };
@@ -92,7 +107,17 @@ export class ManagedFailureRuntimeWatch {
92
107
  let actions;
93
108
  let receipts;
94
109
  try {
95
- [actions, receipts] = await Promise.all([this.#client.listActions(), this.#client.listReceipts()]);
110
+ actions = await this.#client.listActions();
111
+ const candidateBindings = new Set(candidates.map((failureCase) => bindingKey(failureCase.definition)));
112
+ receipts = await this.#client.listReceipts(actions.filter((action) => {
113
+ const binding = action.businessTaskBinding;
114
+ return Boolean(binding?.taskContractId && binding.actionPathId && binding.environment
115
+ && candidateBindings.has(bindingKey({
116
+ taskContractId: binding.taskContractId,
117
+ actionPathId: binding.actionPathId,
118
+ environment: binding.environment,
119
+ })));
120
+ }));
96
121
  }
97
122
  catch {
98
123
  const detail = "Runtime Watch could not load new Action and Receipt metadata from Witnora.";
@@ -132,7 +157,8 @@ export class ManagedFailureRuntimeWatch {
132
157
  for (const failureCase of eligible) {
133
158
  const checkedAt = this.#now().toISOString();
134
159
  const nextCheckAt = new Date(Date.parse(checkedAt) + this.#intervalMs).toISOString();
135
- const checkpoint = await this.#checkpoints.load(failureCase.id) ?? {
160
+ const storedCheckpoint = await this.#checkpoints.load(failureCase.id);
161
+ const checkpoint = storedCheckpoint ?? {
136
162
  processedReceiptIds: failureCase.runtimeWatch?.receiptIds ?? failureCase.runtimeWatch?.latest?.receiptIds ?? [],
137
163
  updatedAt: checkedAt,
138
164
  };
@@ -144,6 +170,8 @@ export class ManagedFailureRuntimeWatch {
144
170
  lastCheckedAt: checkedAt,
145
171
  nextCheckAt,
146
172
  });
173
+ if (!storedCheckpoint)
174
+ await this.#checkpoints.save(failureCase.id, checkpoint);
147
175
  continue;
148
176
  }
149
177
  const resourceId = pending[0].resourceId;
@@ -236,9 +264,9 @@ export async function readLocalSandboxRuntimeWatchOutcome(input) {
236
264
  }
237
265
  throw error;
238
266
  }
239
- const expected = new Map(input.actions.map((action) => [`${action.id}\0${action.executionSessionId}`, action]));
240
- if (expected.size !== input.actions.length || !input.resourceId || [...expected.values()].some((action) => !action.id || !action.executionSessionId)) {
241
- return deferred("INSUFFICIENT_EVIDENCE", attempts, observedAt(), "The covered Action and execution-session bindings are incomplete.");
267
+ const expected = new Map(input.actions.map((action) => [action.id, action]));
268
+ if (expected.size !== input.actions.length || !input.resourceId || [...expected.values()].some((action) => !action.id)) {
269
+ return deferred("INSUFFICIENT_EVIDENCE", attempts, observedAt(), "The covered Action bindings are incomplete.");
242
270
  }
243
271
  const commits = new Map();
244
272
  for (const line of source.split(/\r?\n/u)) {
@@ -257,16 +285,21 @@ export async function readLocalSandboxRuntimeWatchOutcome(input) {
257
285
  if (!record) {
258
286
  return deferred("SCHEMA_DIGEST_DRIFT", attempts, observedAt(), "A committed local sandbox result is missing an allowlisted field.");
259
287
  }
260
- const key = `${record.actionId}\0${record.executionSessionId}`;
261
- if (record.resourceId !== input.resourceId || !expected.has(key))
288
+ const expectedAction = expected.get(record.actionId);
289
+ if (record.resourceId !== input.resourceId || !expectedAction)
290
+ continue;
291
+ if (expectedAction.executionSessionId && expectedAction.executionSessionId !== record.executionSessionId)
262
292
  continue;
263
293
  const digest = createHash("sha256").update(JSON.stringify(record.observedState)).digest("hex");
264
294
  if (digest !== record.stateSha256) {
265
295
  return deferred("SCHEMA_DIGEST_DRIFT", attempts, observedAt(), "A covered local sandbox result failed its state digest check.");
266
296
  }
267
- const existing = commits.get(key);
297
+ const existing = commits.get(record.actionId);
298
+ if (existing && existing.executionSessionId !== record.executionSessionId) {
299
+ return deferred("INSUFFICIENT_EVIDENCE", attempts, observedAt(), "A covered Action has more than one execution-session result.");
300
+ }
268
301
  if (!existing || record.at > existing.at)
269
- commits.set(key, { at: record.at });
302
+ commits.set(record.actionId, { at: record.at, executionSessionId: record.executionSessionId });
270
303
  }
271
304
  if (commits.size !== expected.size) {
272
305
  return deferred("INSUFFICIENT_EVIDENCE", attempts, observedAt(), "Not every covered Action has a digest-verified committed result.");
@@ -309,9 +342,14 @@ function isRecord(value) {
309
342
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
310
343
  }
311
344
  function coveredOutcomes(failureCase, actions, receipts) {
312
- const receiptsByAction = new Map(receipts.filter((receipt) => receipt.currentStatus === "ACTIVE"
313
- && receipt.receipt.core.enforcementLevel === "ENFORCED"
314
- && (receipt.receipt.core.evidenceStrength === "OUTCOME_VERIFIED" || receipt.receipt.core.evidenceStrength === "INDEPENDENTLY_REVIEWED"))
345
+ const watchStartedAt = timestamp(failureCase.runtimeWatch?.activatedAt
346
+ ?? failureCase.candidate?.recordedAt
347
+ ?? failureCase.updatedAt);
348
+ const receiptsByAction = new Map(receipts.filter((receipt) => {
349
+ const receiptCreatedAt = timestamp(receipt.createdAt);
350
+ return eligibleReceipt(receipt)
351
+ && (!watchStartedAt || (receiptCreatedAt !== undefined && receiptCreatedAt >= watchStartedAt));
352
+ })
315
353
  .map((receipt) => [receipt.actionId, receipt]));
316
354
  return actions.flatMap((action) => {
317
355
  const binding = action.businessTaskBinding;
@@ -326,9 +364,7 @@ function coveredOutcomes(failureCase, actions, receipts) {
326
364
  }).sort((left, right) => left.receipt.createdAt.localeCompare(right.receipt.createdAt));
327
365
  }
328
366
  function coveredBindingKeys(actions, receipts) {
329
- const coveredActionIds = new Set(receipts.filter((receipt) => receipt.currentStatus === "ACTIVE"
330
- && receipt.receipt.core.enforcementLevel === "ENFORCED"
331
- && (receipt.receipt.core.evidenceStrength === "OUTCOME_VERIFIED" || receipt.receipt.core.evidenceStrength === "INDEPENDENTLY_REVIEWED"))
367
+ const coveredActionIds = new Set(receipts.filter(eligibleReceipt)
332
368
  .map((receipt) => receipt.actionId));
333
369
  return new Set(actions.flatMap((action) => {
334
370
  const binding = action.businessTaskBinding;
@@ -348,6 +384,40 @@ function unique(values) { return [...new Set(values)]; }
348
384
  function bindingKey(value) {
349
385
  return `${value.taskContractId}\0${value.actionPathId}\0${value.environment}`;
350
386
  }
387
+ function eligibleReceipt(receipt) {
388
+ return receipt.discoveryBoundary === "SIGNED_VERIFIED_ACTION"
389
+ || (receipt.currentStatus === "ACTIVE"
390
+ && receipt.receipt.core.enforcementLevel === "ENFORCED"
391
+ && (receipt.receipt.core.evidenceStrength === "OUTCOME_VERIFIED"
392
+ || receipt.receipt.core.evidenceStrength === "INDEPENDENTLY_REVIEWED"));
393
+ }
394
+ function signedVerifiedActionReceipt(value) {
395
+ const receiptId = value.receiptId;
396
+ const actionId = value.id;
397
+ const signatureCount = value.receiptSignatureCount;
398
+ const createdAt = typeof value.updatedAt === "string" ? value.updatedAt : value.createdAt;
399
+ if (value.status !== "VERIFIED"
400
+ || value.verificationSuccess !== true
401
+ || typeof receiptId !== "string" || !receiptId
402
+ || typeof actionId !== "string" || !actionId
403
+ || !Number.isSafeInteger(signatureCount) || signatureCount < 1
404
+ || typeof createdAt !== "string" || Number.isNaN(Date.parse(createdAt)))
405
+ return [];
406
+ return [{
407
+ id: receiptId,
408
+ actionId,
409
+ currentStatus: "DISCOVERED",
410
+ createdAt: new Date(createdAt).toISOString(),
411
+ receipt: { core: {} },
412
+ discoveryBoundary: "SIGNED_VERIFIED_ACTION",
413
+ }];
414
+ }
415
+ function timestamp(value) {
416
+ if (!value)
417
+ return undefined;
418
+ const parsed = Date.parse(value);
419
+ return Number.isNaN(parsed) ? undefined : parsed;
420
+ }
351
421
  async function hostedJson(requestFetch, url, apiKey, init = {}) {
352
422
  const headers = new Headers(init.headers);
353
423
  headers.set("authorization", `Bearer ${apiKey}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "witnora",
3
- "version": "0.18.13",
3
+ "version": "0.18.15",
4
4
  "description": "Independent assurance for covered agent action paths across models and frameworks.",
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN LICENSE",