@jungjaehoon/mama-os 0.24.1 → 0.25.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.
Files changed (113) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +9 -6
  3. package/dist/agent/agent-loop.d.ts.map +1 -1
  4. package/dist/agent/agent-loop.js +8 -0
  5. package/dist/agent/agent-loop.js.map +1 -1
  6. package/dist/agent/code-act/constants.js +2 -2
  7. package/dist/agent/code-act/host-bridge.d.ts.map +1 -1
  8. package/dist/agent/code-act/host-bridge.js +37 -4
  9. package/dist/agent/code-act/host-bridge.js.map +1 -1
  10. package/dist/agent/code-act/type-definition-generator.d.ts.map +1 -1
  11. package/dist/agent/code-act/type-definition-generator.js +2 -4
  12. package/dist/agent/code-act/type-definition-generator.js.map +1 -1
  13. package/dist/agent/context-compile-service.d.ts +2 -0
  14. package/dist/agent/context-compile-service.d.ts.map +1 -1
  15. package/dist/agent/context-compile-service.js +26 -7
  16. package/dist/agent/context-compile-service.js.map +1 -1
  17. package/dist/agent/gateway-tool-executor.d.ts +2 -0
  18. package/dist/agent/gateway-tool-executor.d.ts.map +1 -1
  19. package/dist/agent/gateway-tool-executor.js +312 -18
  20. package/dist/agent/gateway-tool-executor.js.map +1 -1
  21. package/dist/agent/gateway-tools.md +4 -3
  22. package/dist/agent/tool-registry.d.ts.map +1 -1
  23. package/dist/agent/tool-registry.js +9 -3
  24. package/dist/agent/tool-registry.js.map +1 -1
  25. package/dist/agent/types.d.ts +27 -6
  26. package/dist/agent/types.d.ts.map +1 -1
  27. package/dist/agent/types.js.map +1 -1
  28. package/dist/api/operator-tasks-handler.d.ts.map +1 -1
  29. package/dist/api/operator-tasks-handler.js +23 -1
  30. package/dist/api/operator-tasks-handler.js.map +1 -1
  31. package/dist/cli/commands/start.d.ts +7 -3
  32. package/dist/cli/commands/start.d.ts.map +1 -1
  33. package/dist/cli/commands/start.js +113 -65
  34. package/dist/cli/commands/start.js.map +1 -1
  35. package/dist/cli/runtime/agent-loop-init.d.ts +2 -0
  36. package/dist/cli/runtime/agent-loop-init.d.ts.map +1 -1
  37. package/dist/cli/runtime/agent-loop-init.js +37 -12
  38. package/dist/cli/runtime/agent-loop-init.js.map +1 -1
  39. package/dist/cli/runtime/api-routes-init.js +3 -3
  40. package/dist/cli/runtime/api-routes-init.js.map +1 -1
  41. package/dist/cli/runtime/temporal-init.d.ts +28 -0
  42. package/dist/cli/runtime/temporal-init.d.ts.map +1 -0
  43. package/dist/cli/runtime/temporal-init.js +74 -0
  44. package/dist/cli/runtime/temporal-init.js.map +1 -0
  45. package/dist/db/migrations/operator-task-temporal.d.ts +8 -0
  46. package/dist/db/migrations/operator-task-temporal.d.ts.map +1 -0
  47. package/dist/db/migrations/operator-task-temporal.js +209 -0
  48. package/dist/db/migrations/operator-task-temporal.js.map +1 -0
  49. package/dist/envelope/enforcer.d.ts.map +1 -1
  50. package/dist/envelope/enforcer.js +6 -6
  51. package/dist/envelope/enforcer.js.map +1 -1
  52. package/dist/multi-agent/dashboard-agent-persona.d.ts.map +1 -1
  53. package/dist/multi-agent/dashboard-agent-persona.js +9 -4
  54. package/dist/multi-agent/dashboard-agent-persona.js.map +1 -1
  55. package/dist/operator/action-verifier.d.ts +23 -0
  56. package/dist/operator/action-verifier.d.ts.map +1 -1
  57. package/dist/operator/action-verifier.js +76 -0
  58. package/dist/operator/action-verifier.js.map +1 -1
  59. package/dist/operator/board-reconcile.d.ts.map +1 -1
  60. package/dist/operator/board-reconcile.js +3 -0
  61. package/dist/operator/board-reconcile.js.map +1 -1
  62. package/dist/operator/board-slot-instructions.d.ts +3 -3
  63. package/dist/operator/board-slot-instructions.d.ts.map +1 -1
  64. package/dist/operator/board-slot-instructions.js +17 -8
  65. package/dist/operator/board-slot-instructions.js.map +1 -1
  66. package/dist/operator/briefs.d.ts.map +1 -1
  67. package/dist/operator/briefs.js +3 -0
  68. package/dist/operator/briefs.js.map +1 -1
  69. package/dist/operator/task-ledger.d.ts +134 -8
  70. package/dist/operator/task-ledger.d.ts.map +1 -1
  71. package/dist/operator/task-ledger.js +1181 -74
  72. package/dist/operator/task-ledger.js.map +1 -1
  73. package/dist/operator/task-temporal.d.ts +21 -0
  74. package/dist/operator/task-temporal.d.ts.map +1 -0
  75. package/dist/operator/task-temporal.js +111 -0
  76. package/dist/operator/task-temporal.js.map +1 -0
  77. package/dist/operator/temporal-effect.d.ts +62 -0
  78. package/dist/operator/temporal-effect.d.ts.map +1 -0
  79. package/dist/operator/temporal-effect.js +71 -0
  80. package/dist/operator/temporal-effect.js.map +1 -0
  81. package/dist/operator/temporal-reconcile.d.ts +48 -0
  82. package/dist/operator/temporal-reconcile.d.ts.map +1 -0
  83. package/dist/operator/temporal-reconcile.js +215 -0
  84. package/dist/operator/temporal-reconcile.js.map +1 -0
  85. package/dist/operator/temporal-runtime.d.ts +54 -0
  86. package/dist/operator/temporal-runtime.d.ts.map +1 -0
  87. package/dist/operator/temporal-runtime.js +110 -0
  88. package/dist/operator/temporal-runtime.js.map +1 -0
  89. package/dist/operator/temporal-worker.d.ts +19 -0
  90. package/dist/operator/temporal-worker.d.ts.map +1 -0
  91. package/dist/operator/temporal-worker.js +105 -0
  92. package/dist/operator/temporal-worker.js.map +1 -0
  93. package/dist/operator/worker-run.d.ts +6 -2
  94. package/dist/operator/worker-run.d.ts.map +1 -1
  95. package/dist/operator/worker-run.js +14 -0
  96. package/dist/operator/worker-run.js.map +1 -1
  97. package/dist/operator/workorder-consumer.d.ts +27 -10
  98. package/dist/operator/workorder-consumer.d.ts.map +1 -1
  99. package/dist/operator/workorder-consumer.js +195 -14
  100. package/dist/operator/workorder-consumer.js.map +1 -1
  101. package/dist/operator/workorder-hooks.d.ts +3 -0
  102. package/dist/operator/workorder-hooks.d.ts.map +1 -1
  103. package/dist/operator/workorder-hooks.js +23 -0
  104. package/dist/operator/workorder-hooks.js.map +1 -1
  105. package/dist/operator/workorder-publishers.d.ts +10 -1
  106. package/dist/operator/workorder-publishers.d.ts.map +1 -1
  107. package/dist/operator/workorder-publishers.js +40 -3
  108. package/dist/operator/workorder-publishers.js.map +1 -1
  109. package/package.json +1 -1
  110. package/public/ui/assets/{index-OSgiwL24.js → index-BDXDGEV6.js} +15 -15
  111. package/public/ui/assets/index-po2tN0xq.css +1 -0
  112. package/public/ui/index.html +2 -2
  113. package/public/ui/assets/index-CKOJQYXA.css +0 -1
@@ -74,6 +74,61 @@ const managed_agent_validation_js_1 = require("./managed-agent-validation.js");
74
74
  const delegation_executor_js_1 = require("./delegation-executor.js");
75
75
  const index_js_1 = require("../envelope/index.js");
76
76
  const wiki_publish_adapter_js_1 = require("../wiki-artifacts/wiki-publish-adapter.js");
77
+ function serializeTaskToolRecord(task) {
78
+ return {
79
+ ...task,
80
+ due_at: task.dueAt === null ? null : new Date(task.dueAt).toISOString(),
81
+ deadline_offset_minutes: task.deadlineOffsetMinutes,
82
+ temporal_epoch: task.temporalEpoch,
83
+ temporal_reconciled_occurrence_key: task.temporalReconciledOccurrenceKey,
84
+ last_temporal_checked_at: task.lastTemporalCheckedAt,
85
+ next_temporal_check_at: task.nextTemporalCheckAt,
86
+ last_temporal_attempt_id: task.lastTemporalAttemptId,
87
+ temporal_state: task.temporalState,
88
+ };
89
+ }
90
+ function temporalContextPacketBinding(context) {
91
+ return `temporal:${context.taskId}:${context.generationKey}`;
92
+ }
93
+ function bindTemporalContextPacketTask(context, task) {
94
+ if (typeof task !== 'string' || task.trim().length === 0) {
95
+ const error = new Error('task is required.');
96
+ error.code = 'context_compile_input_invalid';
97
+ throw error;
98
+ }
99
+ return `${temporalContextPacketBinding(context)}\n${task}`;
100
+ }
101
+ function temporalIdentifierRef(value) {
102
+ return `sha256:${(0, crypto_1.createHash)('sha256').update(value).digest('hex')}`;
103
+ }
104
+ function temporalPacketRawSourcesWithinBoundSource(context, sourceRefs) {
105
+ const rawRefs = sourceRefs.filter((value) => typeof value === 'object' &&
106
+ value !== null &&
107
+ !Array.isArray(value) &&
108
+ value.kind === 'raw');
109
+ if (!context.sourceChannel) {
110
+ return rawRefs.length === 0;
111
+ }
112
+ return rawRefs.every((ref) => {
113
+ const eventMatches = !context.sourceEventId ||
114
+ [ref.raw_id, ref.source_id].some((value) => typeof value === 'string' && temporalIdentifierRef(value) === context.sourceEventId);
115
+ const channelMatches = !context.sourceChannel ||
116
+ (typeof ref.connector === 'string' &&
117
+ typeof ref.channel_id === 'string' &&
118
+ temporalIdentifierRef(`${ref.connector}:${ref.channel_id}`) === context.sourceChannel);
119
+ return eventMatches && channelMatches;
120
+ });
121
+ }
122
+ function temporalPacketReferencesBoundSource(context, sourceRefs) {
123
+ const hasRawReference = sourceRefs.some((value) => typeof value === 'object' &&
124
+ value !== null &&
125
+ !Array.isArray(value) &&
126
+ value.kind === 'raw');
127
+ if (context.sourceEventId || context.sourceChannel) {
128
+ return hasRawReference && temporalPacketRawSourcesWithinBoundSource(context, sourceRefs);
129
+ }
130
+ return temporalPacketRawSourcesWithinBoundSource(context, sourceRefs);
131
+ }
77
132
  const { DebugLogger } = debugLogger;
78
133
  const securityLogger = new DebugLogger('SecurityAudit');
79
134
  const TRUTHY_ENV_VALUES = new Set(['1', 'true', 'yes', 'on']);
@@ -114,6 +169,48 @@ const MEMORY_SCOPE_AUDIT_TOOLS = new Set([
114
169
  'mama_add',
115
170
  'mama_ingest',
116
171
  ]);
172
+ const TEMPORAL_WRITE_TOOLS = new Set([
173
+ 'mama_save',
174
+ 'context_compile',
175
+ 'mama_update',
176
+ 'mama_add',
177
+ 'mama_ingest',
178
+ 'report_publish',
179
+ 'report_request',
180
+ 'workorder_request',
181
+ 'wiki_publish',
182
+ 'obsidian',
183
+ 'task_create',
184
+ 'task_update',
185
+ 'contract_no_update',
186
+ 'task_temporal_reconcile',
187
+ 'Write',
188
+ 'Bash',
189
+ 'discord_send',
190
+ 'slack_send',
191
+ 'telegram_send',
192
+ 'webchat_send',
193
+ 'delegate',
194
+ 'os_add_bot',
195
+ 'os_set_permissions',
196
+ 'os_set_model',
197
+ 'os_restart_bot',
198
+ 'os_stop_bot',
199
+ 'agent_update',
200
+ 'agent_create',
201
+ 'viewer_navigate',
202
+ 'viewer_notify',
203
+ 'save_integration_token',
204
+ 'browser_navigate',
205
+ 'browser_screenshot',
206
+ 'browser_click',
207
+ 'browser_type',
208
+ 'browser_scroll',
209
+ 'browser_evaluate',
210
+ 'browser_pdf',
211
+ 'browser_close',
212
+ 'agent_test',
213
+ ]);
117
214
  const MEMORY_READ_PERMISSION_BEFORE_ENVELOPE_TOOLS = new Set([
118
215
  'mama_save',
119
216
  'mama_search',
@@ -284,6 +381,7 @@ class GatewayToolExecutor {
284
381
  envelopeIssuanceMode;
285
382
  metricsStore;
286
383
  contextCompileService;
384
+ temporalContextPacketLookup;
287
385
  currentContext = null;
288
386
  memoryAgentProcessManager = null;
289
387
  agentProcessManager = null;
@@ -378,6 +476,8 @@ class GatewayToolExecutor {
378
476
  sourceMessageRef: executionContext?.sourceMessageRef,
379
477
  modelRunId: executionContext?.modelRunId ?? null,
380
478
  gatewayCallId: executionContext?.gatewayCallId,
479
+ workorderAttemptId: executionContext?.workorderAttemptId,
480
+ temporalWorkContext: executionContext?.temporalWorkContext,
381
481
  signal: executionContext?.signal,
382
482
  parentToolName: executionContext?.parentToolName,
383
483
  backgroundTasks: executionContext?.backgroundTasks,
@@ -412,6 +512,10 @@ class GatewayToolExecutor {
412
512
  sourceMessageRef: active.sourceMessageRef ?? fallback.sourceMessageRef,
413
513
  modelRunId: active.modelRunId ?? fallback.modelRunId,
414
514
  gatewayCallId: active.gatewayCallId ?? fallback.gatewayCallId,
515
+ // Never merged from fallback - attempt identity is issued for one claimed run only.
516
+ workorderAttemptId: active.workorderAttemptId,
517
+ // Never merged from fallback - temporal authority belongs to one claimed run only.
518
+ temporalWorkContext: active.temporalWorkContext,
415
519
  signal: active.signal,
416
520
  parentToolName: active.parentToolName ?? fallback.parentToolName,
417
521
  backgroundTasks: active.backgroundTasks ?? fallback.backgroundTasks,
@@ -448,6 +552,23 @@ class GatewayToolExecutor {
448
552
  const activeContext = this.normalizeExecutionContext(executionContext);
449
553
  return this.executionContextStorage.run(activeContext, fn);
450
554
  }
555
+ requireActiveTemporalAuthority(toolName) {
556
+ const context = this.getExecutionState().temporalWorkContext;
557
+ if (toolName === 'task_temporal_reconcile' && !context) {
558
+ throw new types_js_1.AgentError('task_temporal_reconcile requires an active host-issued temporal work context', 'WORKORDER_SUPERSEDED', undefined, false);
559
+ }
560
+ if (!context)
561
+ return null;
562
+ if (!this.taskLedger) {
563
+ throw new types_js_1.AgentError('Temporal work authority cannot be checked because the task ledger is unavailable', 'WORKORDER_SUPERSEDED', undefined, false);
564
+ }
565
+ try {
566
+ return this.taskLedger.assertTemporalWorkContextActive(context);
567
+ }
568
+ catch {
569
+ throw new types_js_1.AgentError('Temporal workorder authority is no longer active', 'WORKORDER_SUPERSEDED', undefined, false);
570
+ }
571
+ }
451
572
  setCurrentAgentContext(agentId, source, channelId) {
452
573
  this.currentAgentId = agentId;
453
574
  this.currentSource = source;
@@ -599,6 +720,20 @@ class GatewayToolExecutor {
599
720
  this.envelopeIssuanceMode = options.envelopeIssuanceMode ?? 'enabled';
600
721
  this.metricsStore = options.metricsStore ?? null;
601
722
  this.contextCompileService = options.contextCompileService;
723
+ this.temporalContextPacketLookup =
724
+ options.temporalContextPacketLookup ??
725
+ (async (input) => {
726
+ const packet = (0, mama_core_1.getContextPacketForTrustedUse)(await getContextPacketLookupAdapter(), input);
727
+ if (!packet)
728
+ return null;
729
+ return {
730
+ packet_id: packet.packet_id,
731
+ task: packet.task,
732
+ packet_json: packet.packet_json,
733
+ source_refs: packet.source_refs,
734
+ created_at: packet.created_at,
735
+ };
736
+ });
602
737
  this.wikiPublishAdapter = options.wikiPublishAdapter ?? null;
603
738
  this.browserTool = (0, browser_tool_js_1.getBrowserTool)({
604
739
  screenshotDir: (0, path_1.join)(process.env.HOME || '', '.mama', 'workspace', 'media', 'outbound'),
@@ -798,10 +933,8 @@ class GatewayToolExecutor {
798
933
  this.logEnvelopeActivity(ctx, 'envelope_violation', toolName, err.message);
799
934
  const denial = {
800
935
  success: false,
801
- error: err.message,
936
+ error: `[${err.code}] Envelope policy denied this tool call`,
802
937
  code: err.code,
803
- envelope_hash: ctx.envelope.envelope_hash,
804
- ...err.metadata,
805
938
  };
806
939
  return denial;
807
940
  }
@@ -893,43 +1026,79 @@ class GatewayToolExecutor {
893
1026
  const gatewayCallId = baseCtx.gatewayCallId ?? `gw_${(0, crypto_1.randomUUID)().replace(/-/g, '')}`;
894
1027
  const ctx = { ...baseCtx, gatewayCallId };
895
1028
  const effectiveInput = this.applyEnvelopeScopedReadDefaults(toolName, input, ctx);
896
- const scopeAudit = this.computeScopeAuditFields(toolName, effectiveInput, ctx);
1029
+ const computedScopeAudit = this.computeScopeAuditFields(toolName, effectiveInput, ctx);
1030
+ const scopeAudit = ctx.temporalWorkContext
1031
+ ? {
1032
+ requestedScopes: null,
1033
+ envelopeScopesSnapshot: null,
1034
+ mismatch: computedScopeAudit.mismatch,
1035
+ }
1036
+ : {
1037
+ ...computedScopeAudit,
1038
+ requestedScopes: digestRequestedScopesForAudit(computedScopeAudit.requestedScopes),
1039
+ };
1040
+ if (ctx.temporalWorkContext && TEMPORAL_WRITE_TOOLS.has(toolName)) {
1041
+ await this.executionContextStorage.run(ctx, async () => {
1042
+ this.requireActiveTemporalAuthority(toolName);
1043
+ });
1044
+ }
897
1045
  const traceState = await this.beginTraceIfNeeded(ctx, gatewayCallId);
898
1046
  const activeCtx = traceState ? { ...ctx, modelRunId: traceState.modelRunId } : ctx;
899
1047
  let result;
1048
+ let auditResult;
900
1049
  try {
901
- result = await this.executionContextStorage.run(activeCtx, () => this.executeWithEnvelopeAndPermissions(toolName, effectiveInput, gatewayCallId));
1050
+ const rawResult = await this.executionContextStorage.run(activeCtx, () => this.executeWithEnvelopeAndPermissions(toolName, effectiveInput, gatewayCallId));
1051
+ if (activeCtx.temporalWorkContext &&
1052
+ toolName !== 'task_temporal_reconcile' &&
1053
+ toolName !== 'code_act') {
1054
+ await this.executionContextStorage.run(activeCtx, async () => {
1055
+ this.requireActiveTemporalAuthority(toolName);
1056
+ });
1057
+ }
1058
+ const shouldSanitizeAuditFailure = Boolean(activeCtx.temporalWorkContext) ||
1059
+ toolName === 'context_compile' ||
1060
+ toolName === 'code_act';
1061
+ auditResult = shouldSanitizeAuditFailure
1062
+ ? sanitizeGatewayFailureResult(rawResult, Boolean(activeCtx.temporalWorkContext))
1063
+ : rawResult;
1064
+ result = activeCtx.temporalWorkContext ? auditResult : rawResult;
902
1065
  activeCtx.signal?.throwIfAborted();
903
1066
  }
904
1067
  catch (error) {
905
- await this.appendToolTraceIfNeeded(traceState, activeCtx, toolName, undefined, Date.now() - startedAt, gatewayCallId, error).catch((appendError) => {
1068
+ const shouldSanitizeAuditFailure = Boolean(activeCtx.temporalWorkContext) ||
1069
+ toolName === 'context_compile' ||
1070
+ toolName === 'code_act';
1071
+ const auditError = shouldSanitizeAuditFailure
1072
+ ? sanitizeGatewayError(error, Boolean(activeCtx.temporalWorkContext))
1073
+ : error;
1074
+ await this.appendToolTraceIfNeeded(traceState, activeCtx, toolName, undefined, Date.now() - startedAt, gatewayCallId, auditError).catch((appendError) => {
906
1075
  securityLogger.warn('[model-run] failed to append failed tool trace before finalization', appendError);
907
1076
  });
908
- await this.failDirectModelRunIfNeeded(traceState, toolName, error).catch((finalizationError) => {
1077
+ await this.failDirectModelRunIfNeeded(traceState, toolName, auditError).catch((finalizationError) => {
909
1078
  securityLogger.warn('[model-run] failed to finalize failed direct model run', finalizationError);
910
1079
  });
911
- this.logGatewayToolCall(activeCtx, toolName, undefined, Date.now() - startedAt, scopeAudit, gatewayCallId, error);
1080
+ this.logGatewayToolCall(activeCtx, toolName, undefined, Date.now() - startedAt, scopeAudit, gatewayCallId, auditError);
912
1081
  if (scopeAudit.mismatch) {
913
1082
  this.alarmScopeMismatch(activeCtx, toolName);
914
1083
  }
915
- throw error;
1084
+ throw activeCtx.temporalWorkContext ? auditError : error;
916
1085
  }
917
1086
  try {
918
1087
  try {
919
- await this.appendToolTraceIfNeeded(traceState, activeCtx, toolName, result, Date.now() - startedAt, gatewayCallId);
1088
+ await this.appendToolTraceIfNeeded(traceState, activeCtx, toolName, auditResult, Date.now() - startedAt, gatewayCallId);
920
1089
  }
921
1090
  finally {
922
- await this.completeDirectModelRunIfNeeded(traceState, toolName, result);
1091
+ await this.completeDirectModelRunIfNeeded(traceState, toolName, auditResult);
923
1092
  }
924
1093
  }
925
1094
  catch (postRunError) {
926
- this.logGatewayToolCall(activeCtx, toolName, result, Date.now() - startedAt, scopeAudit, gatewayCallId, postRunError);
1095
+ this.logGatewayToolCall(activeCtx, toolName, auditResult, Date.now() - startedAt, scopeAudit, gatewayCallId, postRunError);
927
1096
  if (scopeAudit.mismatch) {
928
1097
  this.alarmScopeMismatch(activeCtx, toolName);
929
1098
  }
930
1099
  throw postRunError;
931
1100
  }
932
- this.logGatewayToolCall(activeCtx, toolName, result, Date.now() - startedAt, scopeAudit, gatewayCallId);
1101
+ this.logGatewayToolCall(activeCtx, toolName, auditResult, Date.now() - startedAt, scopeAudit, gatewayCallId);
933
1102
  if (scopeAudit.mismatch) {
934
1103
  this.alarmScopeMismatch(activeCtx, toolName);
935
1104
  }
@@ -1277,6 +1446,9 @@ class GatewayToolExecutor {
1277
1446
  gateway_call_id: gatewayCallId,
1278
1447
  ...(resultCode ? { code: resultCode } : {}),
1279
1448
  ...(ctx?.parentToolName ? { parent: ctx.parentToolName } : {}),
1449
+ ...(ctx?.workorderAttemptId !== undefined
1450
+ ? { workorder_attempt_id: ctx.workorderAttemptId }
1451
+ : {}),
1280
1452
  },
1281
1453
  });
1282
1454
  }
@@ -1337,6 +1509,7 @@ class GatewayToolExecutor {
1337
1509
  };
1338
1510
  }
1339
1511
  }
1512
+ this.requireActiveTemporalAuthority(toolName);
1340
1513
  const envelopeDenied = this.enforceEnvelopeForToolCall(toolName, input);
1341
1514
  if (envelopeDenied) {
1342
1515
  return envelopeDenied;
@@ -1752,6 +1925,14 @@ class GatewayToolExecutor {
1752
1925
  if (!slotsInput || typeof slotsInput !== 'object') {
1753
1926
  throw new types_js_1.AgentError('report_publish requires slots object', 'TOOL_ERROR', undefined, false);
1754
1927
  }
1928
+ if (this.getExecutionState().temporalWorkContext) {
1929
+ const slotNames = Object.keys(slotsInput);
1930
+ if (slotNames.length !== 1 ||
1931
+ slotNames[0] !== 'pipeline' ||
1932
+ typeof slotsInput.pipeline !== 'string') {
1933
+ throw new types_js_1.AgentError('Temporal report_publish accepts exactly the host-derived pipeline slot', 'TOOL_ERROR', undefined, false);
1934
+ }
1935
+ }
1755
1936
  // Stage-2 shadow seam: a per-run capture override takes precedence
1756
1937
  // over the global singleton (capture runs never touch the live store).
1757
1938
  const activePublisher = this.getExecutionState().reportPublisherOverride ?? this.reportPublisher;
@@ -1926,16 +2107,29 @@ class GatewayToolExecutor {
1926
2107
  if (!this.taskLedger) {
1927
2108
  return { success: false, error: 'Task ledger not configured' };
1928
2109
  }
2110
+ const temporalContext = this.getExecutionState().temporalWorkContext;
2111
+ if (temporalContext) {
2112
+ const boundTask = this.taskLedger.getById(temporalContext.taskId);
2113
+ if (!boundTask) {
2114
+ throw new types_js_1.AgentError('Host-bound temporal owner task is unavailable', 'WORKORDER_SUPERSEDED', undefined, false);
2115
+ }
2116
+ return {
2117
+ success: true,
2118
+ tasks: [serializeTaskToolRecord(boundTask)],
2119
+ };
2120
+ }
1929
2121
  const listInput = input;
1930
2122
  return {
1931
2123
  success: true,
1932
- tasks: this.taskLedger.list({
2124
+ tasks: this.taskLedger
2125
+ .list({
1933
2126
  status: listInput.status,
1934
2127
  channel: listInput.channel,
1935
2128
  search: listInput.search,
1936
2129
  limit: listInput.limit,
1937
2130
  order: listInput.order ?? 'deadline_priority',
1938
- }),
2131
+ })
2132
+ .map(serializeTaskToolRecord),
1939
2133
  };
1940
2134
  }
1941
2135
  case 'task_create': {
@@ -1944,7 +2138,7 @@ class GatewayToolExecutor {
1944
2138
  }
1945
2139
  return {
1946
2140
  success: true,
1947
- task: this.taskLedger.create(input),
2141
+ task: serializeTaskToolRecord(this.taskLedger.create(input)),
1948
2142
  };
1949
2143
  }
1950
2144
  case 'task_update': {
@@ -1959,7 +2153,59 @@ class GatewayToolExecutor {
1959
2153
  }
1960
2154
  return {
1961
2155
  success: true,
1962
- task: this.taskLedger.update(id, patch),
2156
+ task: serializeTaskToolRecord(this.taskLedger.update(id, patch)),
2157
+ };
2158
+ }
2159
+ case 'task_temporal_reconcile': {
2160
+ if (!this.taskLedger) {
2161
+ return { success: false, error: 'Task ledger not configured' };
2162
+ }
2163
+ const context = this.getExecutionState().temporalWorkContext;
2164
+ if (!context) {
2165
+ throw new types_js_1.AgentError('task_temporal_reconcile requires trusted temporal context', 'WORKORDER_SUPERSEDED', undefined, false);
2166
+ }
2167
+ const contextPacketId = input.context_packet_id;
2168
+ if (typeof contextPacketId !== 'string' || contextPacketId.trim().length === 0) {
2169
+ throw new types_js_1.AgentError('task_temporal_reconcile requires a fresh context_packet_id', 'TOOL_ERROR', undefined, false);
2170
+ }
2171
+ const executionState = this.getExecutionState();
2172
+ if (!executionState.envelope || !executionState.modelRunId) {
2173
+ throw new types_js_1.AgentError('task_temporal_reconcile evidence requires an active envelope and model run', 'TOOL_ERROR', undefined, false);
2174
+ }
2175
+ const packet = await this.temporalContextPacketLookup({
2176
+ packetId: contextPacketId,
2177
+ envelopeHash: executionState.envelope.envelope_hash,
2178
+ callerModelRunId: executionState.modelRunId,
2179
+ });
2180
+ if (!packet || packet.packet_id !== contextPacketId) {
2181
+ throw new types_js_1.AgentError('task_temporal_reconcile context packet is unavailable', 'TOOL_ERROR', undefined, false);
2182
+ }
2183
+ const attempt = this.taskLedger.inspectTemporalAttempt(context.attemptId);
2184
+ if (!Number.isSafeInteger(packet.created_at) ||
2185
+ packet.created_at < attempt.workOrder.updatedAt) {
2186
+ throw new types_js_1.AgentError('task_temporal_reconcile context packet predates the active attempt', 'TOOL_ERROR', undefined, false);
2187
+ }
2188
+ const effectInput = input;
2189
+ if (effectInput.outcome !== 'deferred' &&
2190
+ (!Array.isArray(packet.source_refs) || packet.source_refs.length === 0)) {
2191
+ throw new types_js_1.AgentError('task_temporal_reconcile requires source-backed fresh evidence', 'TOOL_ERROR', undefined, false);
2192
+ }
2193
+ if (!packet.task.startsWith(`${temporalContextPacketBinding(context)}\n`) ||
2194
+ (effectInput.outcome === 'deferred'
2195
+ ? Array.isArray(packet.source_refs) &&
2196
+ packet.source_refs.length > 0 &&
2197
+ !temporalPacketReferencesBoundSource(context, packet.source_refs)
2198
+ : !temporalPacketReferencesBoundSource(context, packet.source_refs))) {
2199
+ throw new types_js_1.AgentError('task_temporal_reconcile context packet is not bound to the active task source', 'TOOL_ERROR', undefined, false);
2200
+ }
2201
+ const evidence = {
2202
+ contextPacketId,
2203
+ contextPacketSha256: (0, crypto_1.createHash)('sha256').update(packet.packet_json).digest('hex'),
2204
+ };
2205
+ const { context_packet_id: _contextPacketId, ...trustedEffectInput } = effectInput;
2206
+ return {
2207
+ success: true,
2208
+ receipt: this.taskLedger.applyTemporalEffect(context, trustedEffectInput, evidence),
1963
2209
  };
1964
2210
  }
1965
2211
  case 'schedule_upcoming': {
@@ -3423,13 +3669,26 @@ class GatewayToolExecutor {
3423
3669
  };
3424
3670
  }
3425
3671
  try {
3672
+ const temporalContext = ctx.temporalWorkContext;
3673
+ const effectiveInput = temporalContext
3674
+ ? { ...input, task: bindTemporalContextPacketTask(temporalContext, input.task) }
3675
+ : input;
3426
3676
  const result = await this.contextCompileService.compileAndPersistContext({
3427
3677
  caller: 'gateway',
3428
3678
  envelope: ctx.envelope,
3429
3679
  modelRunId: ctx.modelRunId ?? null,
3430
- input,
3680
+ input: effectiveInput,
3431
3681
  signal: ctx.signal,
3682
+ beforePersist: temporalContext
3683
+ ? () => {
3684
+ this.requireActiveTemporalAuthority('context_compile');
3685
+ }
3686
+ : undefined,
3432
3687
  });
3688
+ if (temporalContext &&
3689
+ !temporalPacketRawSourcesWithinBoundSource(temporalContext, result.packet.source_refs)) {
3690
+ throw new Error('context_compile packet exceeds the active temporal task source');
3691
+ }
3433
3692
  return {
3434
3693
  success: true,
3435
3694
  packet: result.packet,
@@ -3565,6 +3824,15 @@ function isMemoryScope(value) {
3565
3824
  function memoryScopeKey(scope) {
3566
3825
  return `${scope.kind}:${scope.id}`;
3567
3826
  }
3827
+ function digestRequestedScopesForAudit(scopes) {
3828
+ if (!scopes) {
3829
+ return null;
3830
+ }
3831
+ return scopes.map((scope) => ({
3832
+ kind: scope.kind,
3833
+ id: `sha256:${(0, crypto_1.createHash)('sha256').update(scope.id).digest('hex')}`,
3834
+ }));
3835
+ }
3568
3836
  function getFailureMessage(result) {
3569
3837
  if (!result || result.success !== false) {
3570
3838
  return undefined;
@@ -3573,4 +3841,30 @@ function getFailureMessage(result) {
3573
3841
  const message = record.error ?? record.message ?? 'Tool returned success:false';
3574
3842
  return String(message);
3575
3843
  }
3844
+ function gatewayFailureRef(value, temporal) {
3845
+ const digest = (0, crypto_1.createHash)('sha256').update(value).digest('hex');
3846
+ const label = temporal ? 'temporal_tool_failed' : 'gateway_tool_failed';
3847
+ return `${label};sha256=${digest};length=${value.length}`;
3848
+ }
3849
+ function sanitizeGatewayFailureResult(result, temporal) {
3850
+ const failure = getFailureMessage(result);
3851
+ if (!failure) {
3852
+ return result;
3853
+ }
3854
+ const record = result;
3855
+ return {
3856
+ success: false,
3857
+ error: gatewayFailureRef(failure, temporal),
3858
+ ...(typeof record.code === 'string' ? { code: record.code } : {}),
3859
+ };
3860
+ }
3861
+ function sanitizeGatewayError(error, temporal) {
3862
+ const message = error instanceof Error ? error.message : String(error);
3863
+ if (error instanceof types_js_1.AgentError) {
3864
+ return new types_js_1.AgentError(error.code === 'WORKORDER_SUPERSEDED'
3865
+ ? 'Temporal workorder authority is no longer active'
3866
+ : gatewayFailureRef(message, temporal), error.code, undefined, error.retryable);
3867
+ }
3868
+ return new Error(gatewayFailureRef(message, temporal));
3869
+ }
3576
3870
  //# sourceMappingURL=gateway-tool-executor.js.map