@undefineds.co/linx 0.2.13 → 0.2.14

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.
@@ -1,6 +1,8 @@
1
1
  import { setTimeout as delay } from 'node:timers/promises';
2
2
  import { getDefaultPodDataSession } from '../pod-data-session.js';
3
- import { AS_ACTOR, AS_ANNOUNCE, AS_OBJECT, buildApprovalDocumentUrl, DCT_CREATED, ODRL_ACTION, ODRL_POLICY, ODRL_TARGET, RDF_TYPE, UDFS_ACTION, UDFS_ACTOR, UDFS_ACTOR_ROLE, UDFS_APPROVAL_REQUEST, UDFS_ASSIGNED_TO, UDFS_AUDIT_ENTRY, UDFS_AUTONOMY_GRANT, UDFS_CONTEXT, UDFS_DECISION_BY, UDFS_DECISION_ROLE, UDFS_EFFECT, UDFS_ON_BEHALF_OF, UDFS_POLICY_VERSION, UDFS_REASON, UDFS_RESOLVED_AT, UDFS_REVOKED_AT, UDFS_RISK, UDFS_RISK_CEILING, UDFS_SESSION, UDFS_STATUS, UDFS_TOOL_CALL_ID, UDFS_TOOL_NAME, buildApprovalResourceUrl, buildAuditDocumentUrl, buildAuditResourceUrl, buildGrantResourceUrl, buildInboxResourceUrl, firstIri, firstLiteral, iri, listTurtleResources, listTurtleResourcesRecursive, literal, parseManagedTurtleBlocks, readTurtleResource, subjectIdFromResourceUrl, upsertManagedTurtleBlock, } from '../pi-adapter/pod-native.js';
3
+ import { AS, ODRL, UDFS } from '@undefineds.co/models/namespaces';
4
+ import { ApprovalVocab, AuditVocab, GrantVocab, InboxNotificationVocab } from '@undefineds.co/models/vocab/sidecar';
5
+ import { buildApprovalDocumentUrl, RDF_TYPE, buildApprovalResourceUrl, buildAuditDocumentUrl, buildAuditResourceUrl, buildGrantResourceUrl, buildInboxResourceUrl, firstIri, firstLiteral, iri, listTurtleResources, listTurtleResourcesRecursive, literal, parseManagedTurtleBlocks, readTurtleResource, subjectIdFromResourceUrl, upsertManagedTurtleBlock, } from '../pi-adapter/pod-native.js';
4
6
  const WATCH_CHAT_ID = 'linx-watch';
5
7
  const WATCH_AGENT_ID = 'linx-watch-assistant';
6
8
  const REMOTE_APPROVAL_POLICY_VERSION = 'linx-watch-remote-approval/v1';
@@ -108,16 +110,6 @@ function buildRequestMessage(request) {
108
110
  }
109
111
  return request.message;
110
112
  }
111
- function buildRequestAuditContext(record, request) {
112
- return {
113
- kind: request.kind,
114
- message: buildRequestMessage(request),
115
- ...(request.kind === 'command-approval' && request.command ? { command: request.command } : {}),
116
- ...(request.kind === 'command-approval' && request.cwd ? { cwd: request.cwd } : {}),
117
- backend: record.backend,
118
- sessionId: record.id,
119
- };
120
- }
121
113
  function extractToolCallId(request) {
122
114
  if (!isRecord(request.raw)) {
123
115
  return crypto.randomUUID();
@@ -129,7 +121,7 @@ function extractToolCallId(request) {
129
121
  ?? crypto.randomUUID();
130
122
  }
131
123
  function encodeDecisionReason(decision, note) {
132
- return JSON.stringify({
124
+ return safeJsonStringify({
133
125
  decision,
134
126
  ...(note?.trim() ? { note: note.trim() } : {}),
135
127
  });
@@ -156,34 +148,25 @@ function parseDecisionReason(value) {
156
148
  return null;
157
149
  }
158
150
  }
159
- function parseRequestAuditContext(value) {
160
- if (typeof value !== 'string' || !value.trim()) {
161
- return null;
162
- }
151
+ async function warnOnly(runtime, task) {
163
152
  try {
164
- const parsed = JSON.parse(value);
165
- if (!isRecord(parsed)) {
166
- return null;
167
- }
168
- const kind = normalizeString(parsed.kind);
169
- const message = normalizeString(parsed.message);
170
- const sessionId = normalizeString(parsed.sessionId);
171
- if (!kind || !message || !sessionId) {
172
- return null;
153
+ await task();
154
+ }
155
+ catch (error) {
156
+ if (runtime.onWarning) {
157
+ runtime.onWarning(error);
158
+ return;
173
159
  }
174
- return {
175
- kind: kind,
176
- message,
177
- sessionId,
178
- ...(normalizeString(parsed.backend) ? { backend: normalizeString(parsed.backend) } : {}),
179
- ...(normalizeString(parsed.runtime) ? { runtime: normalizeString(parsed.runtime) } : {}),
180
- ...(normalizeString(parsed.toolName) ? { toolName: normalizeString(parsed.toolName) } : {}),
181
- ...(normalizeString(parsed.command) ? { command: normalizeString(parsed.command) } : {}),
182
- ...(normalizeString(parsed.cwd) ? { cwd: normalizeString(parsed.cwd) } : {}),
183
- };
160
+ const message = error instanceof Error ? error.message : String(error);
161
+ process.emitWarning(`LinX Pod sync failed: ${message}`);
162
+ }
163
+ }
164
+ function safeJsonStringify(value) {
165
+ try {
166
+ return JSON.stringify(value);
184
167
  }
185
168
  catch {
186
- return null;
169
+ return JSON.stringify({ error: 'unserializable_context' });
187
170
  }
188
171
  }
189
172
  function extractSessionId(sessionUri) {
@@ -206,22 +189,8 @@ function decisionFromApprovalRow(row) {
206
189
  }
207
190
  return 'accept';
208
191
  }
209
- function requestAuditForApproval(row, approvalUris, audits) {
210
- const uriSet = new Set(approvalUris);
211
- const matches = audits.filter((audit) => (audit.action === 'approval_requested'
212
- && ((audit.approval && uriSet.has(audit.approval))
213
- || (audit.session === row.session && audit.toolCallId === row.toolCallId))));
214
- matches.sort((left, right) => toIsoString(right.createdAt, '').localeCompare(toIsoString(left.createdAt, '')));
215
- return matches[0];
216
- }
217
- function normalizeApprovalSummary(row, audits) {
192
+ function normalizeApprovalSummary(row) {
218
193
  const createdAt = toIsoString(row.createdAt, new Date(0).toISOString());
219
- const approvalUris = [
220
- buildApprovalUriForDate(row.session, row.id, new Date(createdAt)),
221
- buildApprovalUri(row.session, row.id),
222
- ];
223
- const requestAudit = requestAuditForApproval(row, approvalUris, audits);
224
- const requestContext = parseRequestAuditContext(requestAudit?.context);
225
194
  const sessionUri = row.session;
226
195
  const decision = decisionFromApprovalRow(row);
227
196
  return {
@@ -232,9 +201,7 @@ function normalizeApprovalSummary(row, audits) {
232
201
  toolName: row.toolName,
233
202
  risk: normalizeString(row.risk) ?? 'medium',
234
203
  status: normalizeString(row.status) ?? 'pending',
235
- message: requestContext?.message ?? row.toolName,
236
- ...(requestContext?.command ? { command: requestContext.command } : {}),
237
- ...(requestContext?.cwd ? { cwd: requestContext.cwd } : {}),
204
+ message: formatApprovalMessage(row),
238
205
  ...(normalizeString(row.assignedTo) ? { assignedTo: normalizeString(row.assignedTo) } : {}),
239
206
  ...(normalizeString(row.decisionBy) ? { decisionBy: normalizeString(row.decisionBy) } : {}),
240
207
  ...(decision ? { decision } : {}),
@@ -242,6 +209,18 @@ function normalizeApprovalSummary(row, audits) {
242
209
  ...(row.resolvedAt ? { resolvedAt: toIsoString(row.resolvedAt, createdAt) } : {}),
243
210
  };
244
211
  }
212
+ function formatApprovalMessage(row) {
213
+ if (row.toolName === 'commandExecution') {
214
+ return 'Command execution approval';
215
+ }
216
+ if (row.toolName === 'fileChange') {
217
+ return 'File change approval';
218
+ }
219
+ if (row.toolName === 'permissionRequest') {
220
+ return 'Permission approval';
221
+ }
222
+ return row.toolName;
223
+ }
245
224
  function formatSummaryHeadline(summary) {
246
225
  return `${summary.id} | ${summary.status} | ${summary.risk} | session=${summary.sessionId}`;
247
226
  }
@@ -357,22 +336,22 @@ async function writeApprovalRow(webId, fetcher, row) {
357
336
  await upsertManagedTurtleBlock(fetcher, documentUrl, {
358
337
  subject: subjectUrl,
359
338
  triples: [
360
- { predicate: RDF_TYPE, object: iri(UDFS_APPROVAL_REQUEST) },
361
- { predicate: UDFS_SESSION, object: iri(row.session) },
362
- { predicate: UDFS_TOOL_CALL_ID, object: literal(row.toolCallId) },
363
- { predicate: UDFS_TOOL_NAME, object: literal(row.toolName) },
364
- { predicate: ODRL_TARGET, object: iri(row.target) },
365
- { predicate: ODRL_ACTION, object: iri(row.action) },
366
- { predicate: UDFS_RISK, object: literal(row.risk) },
367
- { predicate: UDFS_STATUS, object: literal(row.status) },
368
- ...(row.assignedTo ? [{ predicate: UDFS_ASSIGNED_TO, object: iri(row.assignedTo) }] : []),
369
- ...(row.decisionBy ? [{ predicate: UDFS_DECISION_BY, object: iri(row.decisionBy) }] : []),
370
- ...(row.decisionRole ? [{ predicate: UDFS_DECISION_ROLE, object: literal(row.decisionRole) }] : []),
371
- ...(row.onBehalfOf ? [{ predicate: UDFS_ON_BEHALF_OF, object: iri(row.onBehalfOf) }] : []),
372
- ...(row.reason ? [{ predicate: UDFS_REASON, object: literal(row.reason) }] : []),
373
- ...(row.policyVersion ? [{ predicate: UDFS_POLICY_VERSION, object: literal(row.policyVersion) }] : []),
374
- { predicate: DCT_CREATED, object: literal(toIsoString(row.createdAt, new Date().toISOString())) },
375
- ...(row.resolvedAt ? [{ predicate: UDFS_RESOLVED_AT, object: literal(toIsoString(row.resolvedAt, new Date().toISOString())) }] : []),
339
+ { predicate: RDF_TYPE, object: iri(UDFS.ApprovalRequest) },
340
+ { predicate: ApprovalVocab.session, object: iri(row.session) },
341
+ { predicate: ApprovalVocab.toolCallId, object: literal(row.toolCallId) },
342
+ { predicate: ApprovalVocab.toolName, object: literal(row.toolName) },
343
+ { predicate: ApprovalVocab.target, object: iri(row.target) },
344
+ { predicate: ApprovalVocab.action, object: iri(row.action) },
345
+ { predicate: ApprovalVocab.risk, object: literal(row.risk) },
346
+ { predicate: ApprovalVocab.status, object: literal(row.status) },
347
+ ...(row.assignedTo ? [{ predicate: ApprovalVocab.assignedTo, object: iri(row.assignedTo) }] : []),
348
+ ...(row.decisionBy ? [{ predicate: ApprovalVocab.decisionBy, object: iri(row.decisionBy) }] : []),
349
+ ...(row.decisionRole ? [{ predicate: ApprovalVocab.decisionRole, object: literal(row.decisionRole) }] : []),
350
+ ...(row.onBehalfOf ? [{ predicate: ApprovalVocab.onBehalfOf, object: iri(row.onBehalfOf) }] : []),
351
+ ...(row.reason ? [{ predicate: ApprovalVocab.reason, object: literal(row.reason) }] : []),
352
+ ...(row.policyVersion ? [{ predicate: ApprovalVocab.policyVersion, object: literal(row.policyVersion) }] : []),
353
+ { predicate: ApprovalVocab.createdAt, object: literal(toIsoString(row.createdAt, new Date().toISOString())) },
354
+ ...(row.resolvedAt ? [{ predicate: ApprovalVocab.resolvedAt, object: literal(toIsoString(row.resolvedAt, new Date().toISOString())) }] : []),
376
355
  ],
377
356
  });
378
357
  }
@@ -398,17 +377,18 @@ async function writeAuditRow(webId, fetcher, row) {
398
377
  await upsertManagedTurtleBlock(fetcher, documentUrl, {
399
378
  subject: subjectUrl,
400
379
  triples: [
401
- { predicate: RDF_TYPE, object: iri(UDFS_AUDIT_ENTRY) },
402
- { predicate: UDFS_ACTION, object: literal(row.action) },
403
- { predicate: UDFS_ACTOR, object: iri(row.actor) },
404
- { predicate: UDFS_ACTOR_ROLE, object: literal(row.actorRole) },
405
- ...(row.onBehalfOf ? [{ predicate: UDFS_ON_BEHALF_OF, object: iri(row.onBehalfOf) }] : []),
406
- ...(row.session ? [{ predicate: UDFS_SESSION, object: iri(row.session) }] : []),
407
- ...(row.toolCallId ? [{ predicate: UDFS_TOOL_CALL_ID, object: literal(row.toolCallId) }] : []),
408
- ...(row.approval ? [{ predicate: 'https://undefineds.co/ns#approval', object: iri(row.approval) }] : []),
409
- ...(row.context ? [{ predicate: UDFS_CONTEXT, object: literal(row.context) }] : []),
410
- ...(row.policyVersion ? [{ predicate: UDFS_POLICY_VERSION, object: literal(row.policyVersion) }] : []),
411
- { predicate: DCT_CREATED, object: literal(toIsoString(row.createdAt, new Date().toISOString())) },
380
+ { predicate: RDF_TYPE, object: iri(UDFS.AuditEntry) },
381
+ { predicate: AuditVocab.action, object: literal(row.action) },
382
+ { predicate: AuditVocab.actor, object: iri(row.actor) },
383
+ { predicate: AuditVocab.actorRole, object: literal(row.actorRole) },
384
+ ...(row.onBehalfOf ? [{ predicate: AuditVocab.onBehalfOf, object: iri(row.onBehalfOf) }] : []),
385
+ ...(row.session ? [{ predicate: AuditVocab.session, object: iri(row.session) }] : []),
386
+ ...(row.entry ? [{ predicate: AuditVocab.entry, object: iri(row.entry) }] : []),
387
+ ...(row.toolCallId ? [{ predicate: AuditVocab.toolCallId, object: literal(row.toolCallId) }] : []),
388
+ ...(row.toolName ? [{ predicate: AuditVocab.toolName, object: literal(row.toolName) }] : []),
389
+ ...(row.approval ? [{ predicate: AuditVocab.approval, object: iri(row.approval) }] : []),
390
+ ...(row.policyVersion ? [{ predicate: AuditVocab.policyVersion, object: literal(row.policyVersion) }] : []),
391
+ { predicate: AuditVocab.createdAt, object: literal(toIsoString(row.createdAt, new Date().toISOString())) },
412
392
  ],
413
393
  });
414
394
  }
@@ -445,17 +425,17 @@ async function writeGrantRow(webId, fetcher, row) {
445
425
  await upsertManagedTurtleBlock(fetcher, documentUrl, {
446
426
  subject: subjectUrl,
447
427
  triples: [
448
- { predicate: RDF_TYPE, object: iri(ODRL_POLICY) },
449
- { predicate: RDF_TYPE, object: iri(UDFS_AUTONOMY_GRANT) },
450
- { predicate: ODRL_TARGET, object: iri(target) },
451
- { predicate: ODRL_ACTION, object: iri(action) },
452
- { predicate: UDFS_EFFECT, object: literal(effect) },
453
- ...(normalizeString(row.riskCeiling) ? [{ predicate: UDFS_RISK_CEILING, object: literal(normalizeString(row.riskCeiling)) }] : []),
454
- { predicate: UDFS_DECISION_BY, object: iri(decisionBy) },
455
- { predicate: UDFS_DECISION_ROLE, object: literal(decisionRole) },
456
- ...(normalizeString(row.onBehalfOf) ? [{ predicate: UDFS_ON_BEHALF_OF, object: iri(normalizeString(row.onBehalfOf)) }] : []),
457
- { predicate: DCT_CREATED, object: literal(toIsoString(row.createdAt, new Date().toISOString())) },
458
- ...(normalizeString(row.revokedAt) ? [{ predicate: UDFS_REVOKED_AT, object: literal(normalizeString(row.revokedAt)) }] : []),
428
+ { predicate: RDF_TYPE, object: iri(ODRL.Policy) },
429
+ { predicate: RDF_TYPE, object: iri(UDFS.AutonomyGrant) },
430
+ { predicate: GrantVocab.target, object: iri(target) },
431
+ { predicate: GrantVocab.action, object: iri(action) },
432
+ { predicate: GrantVocab.effect, object: literal(effect) },
433
+ ...(normalizeString(row.riskCeiling) ? [{ predicate: GrantVocab.riskCeiling, object: literal(normalizeString(row.riskCeiling)) }] : []),
434
+ { predicate: GrantVocab.decisionBy, object: iri(decisionBy) },
435
+ { predicate: GrantVocab.decisionRole, object: literal(decisionRole) },
436
+ ...(normalizeString(row.onBehalfOf) ? [{ predicate: GrantVocab.onBehalfOf, object: iri(normalizeString(row.onBehalfOf)) }] : []),
437
+ { predicate: GrantVocab.createdAt, object: literal(toIsoString(row.createdAt, new Date().toISOString())) },
438
+ ...(normalizeString(row.revokedAt) ? [{ predicate: GrantVocab.revokedAt, object: literal(normalizeString(row.revokedAt)) }] : []),
459
439
  ],
460
440
  });
461
441
  }
@@ -464,22 +444,22 @@ async function writeInboxNotificationRow(webId, fetcher, row) {
464
444
  await upsertManagedTurtleBlock(fetcher, url, {
465
445
  subject: url,
466
446
  triples: [
467
- { predicate: RDF_TYPE, object: iri(AS_ANNOUNCE) },
468
- ...(row.actor ? [{ predicate: AS_ACTOR, object: iri(row.actor) }] : []),
469
- { predicate: AS_OBJECT, object: iri(row.object) },
470
- { predicate: DCT_CREATED, object: literal(toIsoString(row.createdAt, new Date().toISOString())) },
447
+ { predicate: RDF_TYPE, object: iri(AS.Announce) },
448
+ ...(row.actor ? [{ predicate: InboxNotificationVocab.actor, object: iri(row.actor) }] : []),
449
+ { predicate: InboxNotificationVocab.object, object: iri(row.object) },
450
+ { predicate: InboxNotificationVocab.createdAt, object: literal(toIsoString(row.createdAt, new Date().toISOString())) },
471
451
  ],
472
452
  });
473
453
  }
474
454
  function approvalRowFromPredicates(url, predicates) {
475
- const session = firstIri(predicates, UDFS_SESSION);
476
- const toolCallId = firstLiteral(predicates, UDFS_TOOL_CALL_ID);
477
- const toolName = firstLiteral(predicates, UDFS_TOOL_NAME);
478
- const target = firstIri(predicates, ODRL_TARGET);
479
- const action = firstIri(predicates, ODRL_ACTION);
480
- const risk = firstLiteral(predicates, UDFS_RISK);
481
- const status = firstLiteral(predicates, UDFS_STATUS);
482
- const createdAt = firstLiteral(predicates, DCT_CREATED);
455
+ const session = firstIri(predicates, ApprovalVocab.session);
456
+ const toolCallId = firstLiteral(predicates, ApprovalVocab.toolCallId);
457
+ const toolName = firstLiteral(predicates, ApprovalVocab.toolName);
458
+ const target = firstIri(predicates, ApprovalVocab.target);
459
+ const action = firstIri(predicates, ApprovalVocab.action);
460
+ const risk = firstLiteral(predicates, ApprovalVocab.risk);
461
+ const status = firstLiteral(predicates, ApprovalVocab.status);
462
+ const createdAt = firstLiteral(predicates, ApprovalVocab.createdAt);
483
463
  if (!session || !toolCallId || !toolName || !target || !action || !risk || !status || !createdAt) {
484
464
  return null;
485
465
  }
@@ -492,21 +472,21 @@ function approvalRowFromPredicates(url, predicates) {
492
472
  action,
493
473
  risk,
494
474
  status,
495
- assignedTo: firstIri(predicates, UDFS_ASSIGNED_TO),
496
- decisionBy: firstIri(predicates, UDFS_DECISION_BY),
497
- decisionRole: firstLiteral(predicates, UDFS_DECISION_ROLE),
498
- onBehalfOf: firstIri(predicates, UDFS_ON_BEHALF_OF),
499
- reason: firstLiteral(predicates, UDFS_REASON),
500
- policyVersion: firstLiteral(predicates, UDFS_POLICY_VERSION),
475
+ assignedTo: firstIri(predicates, ApprovalVocab.assignedTo),
476
+ decisionBy: firstIri(predicates, ApprovalVocab.decisionBy),
477
+ decisionRole: firstLiteral(predicates, ApprovalVocab.decisionRole),
478
+ onBehalfOf: firstIri(predicates, ApprovalVocab.onBehalfOf),
479
+ reason: firstLiteral(predicates, ApprovalVocab.reason),
480
+ policyVersion: firstLiteral(predicates, ApprovalVocab.policyVersion),
501
481
  createdAt,
502
- resolvedAt: firstLiteral(predicates, UDFS_RESOLVED_AT),
482
+ resolvedAt: firstLiteral(predicates, ApprovalVocab.resolvedAt),
503
483
  };
504
484
  }
505
485
  function auditRowFromPredicates(url, predicates) {
506
- const action = firstLiteral(predicates, UDFS_ACTION);
507
- const actor = firstIri(predicates, UDFS_ACTOR);
508
- const actorRole = firstLiteral(predicates, UDFS_ACTOR_ROLE);
509
- const createdAt = firstLiteral(predicates, DCT_CREATED);
486
+ const action = firstLiteral(predicates, AuditVocab.action);
487
+ const actor = firstIri(predicates, AuditVocab.actor);
488
+ const actorRole = firstLiteral(predicates, AuditVocab.actorRole);
489
+ const createdAt = firstLiteral(predicates, AuditVocab.createdAt);
510
490
  if (!action || !actor || !actorRole || !createdAt) {
511
491
  return null;
512
492
  }
@@ -515,22 +495,23 @@ function auditRowFromPredicates(url, predicates) {
515
495
  action,
516
496
  actor,
517
497
  actorRole,
518
- onBehalfOf: firstIri(predicates, UDFS_ON_BEHALF_OF),
519
- session: firstIri(predicates, UDFS_SESSION),
520
- toolCallId: firstLiteral(predicates, UDFS_TOOL_CALL_ID),
521
- approval: firstIri(predicates, 'https://undefineds.co/ns#approval'),
522
- context: firstLiteral(predicates, UDFS_CONTEXT),
523
- policyVersion: firstLiteral(predicates, UDFS_POLICY_VERSION),
498
+ onBehalfOf: firstIri(predicates, AuditVocab.onBehalfOf),
499
+ session: firstIri(predicates, AuditVocab.session),
500
+ entry: firstIri(predicates, AuditVocab.entry),
501
+ toolCallId: firstLiteral(predicates, AuditVocab.toolCallId),
502
+ toolName: firstLiteral(predicates, AuditVocab.toolName),
503
+ approval: firstIri(predicates, AuditVocab.approval),
504
+ policyVersion: firstLiteral(predicates, AuditVocab.policyVersion),
524
505
  createdAt,
525
506
  };
526
507
  }
527
508
  function grantRowFromPredicates(url, predicates) {
528
- const target = firstIri(predicates, ODRL_TARGET);
529
- const action = firstIri(predicates, ODRL_ACTION);
530
- const effect = firstLiteral(predicates, UDFS_EFFECT);
531
- const decisionBy = firstIri(predicates, UDFS_DECISION_BY);
532
- const decisionRole = firstLiteral(predicates, UDFS_DECISION_ROLE);
533
- const createdAt = firstLiteral(predicates, DCT_CREATED);
509
+ const target = firstIri(predicates, GrantVocab.target);
510
+ const action = firstIri(predicates, GrantVocab.action);
511
+ const effect = firstLiteral(predicates, GrantVocab.effect);
512
+ const decisionBy = firstIri(predicates, GrantVocab.decisionBy);
513
+ const decisionRole = firstLiteral(predicates, GrantVocab.decisionRole);
514
+ const createdAt = firstLiteral(predicates, GrantVocab.createdAt);
534
515
  if (!target || !action || !effect || !decisionBy || !decisionRole || !createdAt) {
535
516
  return null;
536
517
  }
@@ -539,12 +520,12 @@ function grantRowFromPredicates(url, predicates) {
539
520
  target,
540
521
  action,
541
522
  effect,
542
- riskCeiling: firstLiteral(predicates, UDFS_RISK_CEILING),
523
+ riskCeiling: firstLiteral(predicates, GrantVocab.riskCeiling),
543
524
  decisionBy,
544
525
  decisionRole,
545
- onBehalfOf: firstIri(predicates, UDFS_ON_BEHALF_OF),
526
+ onBehalfOf: firstIri(predicates, GrantVocab.onBehalfOf),
546
527
  createdAt,
547
- revokedAt: firstLiteral(predicates, UDFS_REVOKED_AT),
528
+ revokedAt: firstLiteral(predicates, GrantVocab.revokedAt),
548
529
  };
549
530
  }
550
531
  export async function createRemoteWatchApproval(options) {
@@ -564,7 +545,7 @@ export async function createRemoteWatchApproval(options) {
564
545
  risk: buildRisk(options.request),
565
546
  ...(options.request.kind === 'command-approval' && options.request.command ? { command: options.request.command } : {}),
566
547
  ...(options.request.kind === 'command-approval' && options.request.cwd ? { cwd: options.request.cwd } : {}),
567
- context: buildRequestAuditContext(options.record, options.request),
548
+ entry: sessionUri,
568
549
  }),
569
550
  runtime: activeRuntime,
570
551
  });
@@ -586,14 +567,7 @@ export async function createRemoteApproval(options) {
586
567
  const assignedTo = subject.assignedTo ?? webId;
587
568
  const onBehalfOf = subject.onBehalfOf ?? webId;
588
569
  const policyVersion = subject.policyVersion ?? REMOTE_APPROVAL_POLICY_VERSION;
589
- const requestContext = request.context ?? {
590
- kind: request.kind,
591
- message: request.message,
592
- sessionId: extractSessionId(sessionUri),
593
- toolName: request.toolName,
594
- ...(request.command ? { command: request.command } : {}),
595
- ...(request.cwd ? { cwd: request.cwd } : {}),
596
- };
570
+ const requestEntry = request.entry ?? approvalUri;
597
571
  await store.insertApproval({
598
572
  id: approvalId,
599
573
  session: sessionUri,
@@ -607,25 +581,27 @@ export async function createRemoteApproval(options) {
607
581
  policyVersion,
608
582
  createdAt: now,
609
583
  });
610
- await store.insertAudit({
584
+ const requestAudit = {
611
585
  id: crypto.randomUUID(),
612
586
  action: 'approval_requested',
613
587
  actor: subject.actorUri,
614
588
  actorRole: 'secretary',
615
589
  onBehalfOf,
616
590
  session: sessionUri,
591
+ entry: requestEntry,
617
592
  toolCallId: request.toolCallId,
593
+ toolName: request.toolName,
618
594
  approval: approvalUri,
619
- context: JSON.stringify(requestContext),
620
595
  policyVersion,
621
596
  createdAt: now,
622
- });
623
- await store.insertInboxNotification({
597
+ };
598
+ await warnOnly(activeRuntime, () => store.insertAudit(requestAudit));
599
+ await warnOnly(activeRuntime, () => store.insertInboxNotification({
624
600
  id: crypto.randomUUID(),
625
601
  actor: subject.actorUri,
626
602
  object: approvalUri,
627
603
  createdAt: now,
628
- }).catch(() => undefined);
604
+ }));
629
605
  return normalizeApprovalSummary({
630
606
  id: approvalId,
631
607
  session: sessionUri,
@@ -638,19 +614,7 @@ export async function createRemoteApproval(options) {
638
614
  assignedTo,
639
615
  policyVersion,
640
616
  createdAt: now,
641
- }, [{
642
- id: crypto.randomUUID(),
643
- action: 'approval_requested',
644
- actor: subject.actorUri,
645
- actorRole: 'secretary',
646
- onBehalfOf,
647
- session: sessionUri,
648
- toolCallId: request.toolCallId,
649
- approval: approvalUri,
650
- context: JSON.stringify(requestContext),
651
- policyVersion,
652
- createdAt: now,
653
- }]);
617
+ });
654
618
  });
655
619
  }
656
620
  export async function waitForRemoteWatchApproval(options) {
@@ -737,12 +701,9 @@ export async function listRemoteWatchApprovals(options = {}) {
737
701
  const activeRuntime = options.runtime ?? await createDefaultRuntime();
738
702
  const requestedStatus = options.status ?? 'pending';
739
703
  return withRemoteApprovalStore(activeRuntime, async ({ store, webId }) => {
740
- const [approvals, audits] = await Promise.all([
741
- store.listApprovals(),
742
- store.listAudits(),
743
- ]);
704
+ const approvals = await store.listApprovals();
744
705
  return approvals
745
- .map((row) => normalizeApprovalSummary(row, audits))
706
+ .map((row) => normalizeApprovalSummary(row))
746
707
  .filter((summary) => !summary.assignedTo || summary.assignedTo === webId)
747
708
  .filter((summary) => requestedStatus === 'all' || summary.status === requestedStatus)
748
709
  .sort((left, right) => right.createdAt.localeCompare(left.createdAt));
@@ -757,8 +718,7 @@ export async function resolveRemoteWatchApproval(options) {
757
718
  throw new Error(`Remote approval not found: ${options.approvalId}`);
758
719
  }
759
720
  if (row.status !== 'pending') {
760
- const audits = await store.listAudits();
761
- return normalizeApprovalSummary(row, audits);
721
+ return normalizeApprovalSummary(row);
762
722
  }
763
723
  const now = activeRuntime.now();
764
724
  const approvalCreatedAt = new Date(toIsoString(row.createdAt, now.toISOString()));
@@ -774,22 +734,20 @@ export async function resolveRemoteWatchApproval(options) {
774
734
  reason: encodeDecisionReason(options.decision, options.note),
775
735
  resolvedAt: now,
776
736
  });
777
- await store.insertAudit({
737
+ await warnOnly(activeRuntime, () => store.insertAudit({
778
738
  id: crypto.randomUUID(),
779
739
  action: nextStatus === 'approved' ? 'approval_approved' : 'approval_rejected',
780
740
  actor: webId,
781
741
  actorRole: 'human',
782
742
  onBehalfOf: webId,
783
743
  session: row.session,
744
+ entry: approvalUri,
784
745
  toolCallId: row.toolCallId,
746
+ toolName: row.toolName,
785
747
  approval: approvalUri,
786
- context: JSON.stringify({
787
- decision: options.decision,
788
- ...(options.note?.trim() ? { note: options.note.trim() } : {}),
789
- }),
790
748
  policyVersion: REMOTE_APPROVAL_POLICY_VERSION,
791
749
  createdAt: now,
792
- });
750
+ }));
793
751
  if (options.decision === 'accept_for_session') {
794
752
  const grantId = crypto.randomUUID();
795
753
  await store.insertGrant({
@@ -803,19 +761,19 @@ export async function resolveRemoteWatchApproval(options) {
803
761
  onBehalfOf: webId,
804
762
  createdAt: now,
805
763
  });
806
- await store.insertInboxNotification({
764
+ await warnOnly(activeRuntime, () => store.insertInboxNotification({
807
765
  id: crypto.randomUUID(),
808
766
  actor: webId,
809
767
  object: buildGrantUri(row.session, grantId),
810
768
  createdAt: now,
811
- }).catch(() => undefined);
769
+ }));
812
770
  }
813
- await store.insertInboxNotification({
771
+ await warnOnly(activeRuntime, () => store.insertInboxNotification({
814
772
  id: crypto.randomUUID(),
815
773
  actor: webId,
816
774
  object: approvalUri,
817
775
  createdAt: now,
818
- }).catch(() => undefined);
776
+ }));
819
777
  const nextRow = {
820
778
  ...row,
821
779
  status: nextStatus,
@@ -825,15 +783,13 @@ export async function resolveRemoteWatchApproval(options) {
825
783
  reason: encodeDecisionReason(options.decision, options.note),
826
784
  resolvedAt: now,
827
785
  };
828
- const audits = await store.listAudits();
829
- return normalizeApprovalSummary(nextRow, audits);
786
+ return normalizeApprovalSummary(nextRow);
830
787
  });
831
788
  }
832
789
  export const __podApprovalInternal = {
833
790
  createAbortError,
834
791
  createDefaultRuntime,
835
792
  buildActionUri,
836
- buildRequestAuditContext,
837
793
  buildRisk,
838
794
  buildToolName,
839
795
  createNativeRemoteApprovalStore,
@@ -844,6 +800,5 @@ export const __podApprovalInternal = {
844
800
  isRemoteApprovalAbortError,
845
801
  normalizeApprovalSummary,
846
802
  parseDecisionReason,
847
- parseRequestAuditContext,
848
803
  };
849
804
  //# sourceMappingURL=pod-approval.js.map