@jungjaehoon/mama-os 0.31.5 → 0.32.1

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 (219) hide show
  1. package/dist/agent/agent-loop.d.ts +5 -1
  2. package/dist/agent/agent-loop.d.ts.map +1 -1
  3. package/dist/agent/agent-loop.js +117 -50
  4. package/dist/agent/agent-loop.js.map +1 -1
  5. package/dist/agent/claude-cli-wrapper.d.ts +2 -17
  6. package/dist/agent/claude-cli-wrapper.d.ts.map +1 -1
  7. package/dist/agent/claude-cli-wrapper.js.map +1 -1
  8. package/dist/agent/code-act/completed-terminal-result.d.ts +5 -0
  9. package/dist/agent/code-act/completed-terminal-result.d.ts.map +1 -0
  10. package/dist/agent/code-act/completed-terminal-result.js +83 -0
  11. package/dist/agent/code-act/completed-terminal-result.js.map +1 -0
  12. package/dist/agent/code-act/host-bridge.d.ts +1 -0
  13. package/dist/agent/code-act/host-bridge.d.ts.map +1 -1
  14. package/dist/agent/code-act/host-bridge.js +101 -97
  15. package/dist/agent/code-act/host-bridge.js.map +1 -1
  16. package/dist/agent/code-act/run-context-registry.d.ts +36 -0
  17. package/dist/agent/code-act/run-context-registry.d.ts.map +1 -0
  18. package/dist/agent/code-act/run-context-registry.js +143 -0
  19. package/dist/agent/code-act/run-context-registry.js.map +1 -0
  20. package/dist/agent/gateway-tool-catalog.d.ts +14 -0
  21. package/dist/agent/gateway-tool-catalog.d.ts.map +1 -0
  22. package/dist/agent/gateway-tool-catalog.js +41 -0
  23. package/dist/agent/gateway-tool-catalog.js.map +1 -0
  24. package/dist/agent/gateway-tool-executor.d.ts +12 -1
  25. package/dist/agent/gateway-tool-executor.d.ts.map +1 -1
  26. package/dist/agent/gateway-tool-executor.js +212 -18
  27. package/dist/agent/gateway-tool-executor.js.map +1 -1
  28. package/dist/agent/gateway-tools.md +5 -7
  29. package/dist/agent/model-runner.d.ts +6 -18
  30. package/dist/agent/model-runner.d.ts.map +1 -1
  31. package/dist/agent/model-runner.js +3 -1
  32. package/dist/agent/model-runner.js.map +1 -1
  33. package/dist/agent/persistent-cli-adapter.d.ts +3 -10
  34. package/dist/agent/persistent-cli-adapter.d.ts.map +1 -1
  35. package/dist/agent/persistent-cli-adapter.js +73 -2
  36. package/dist/agent/persistent-cli-adapter.js.map +1 -1
  37. package/dist/agent/persistent-cli-process.d.ts +21 -16
  38. package/dist/agent/persistent-cli-process.d.ts.map +1 -1
  39. package/dist/agent/persistent-cli-process.js +275 -29
  40. package/dist/agent/persistent-cli-process.js.map +1 -1
  41. package/dist/agent/tool-registry.d.ts +6 -4
  42. package/dist/agent/tool-registry.d.ts.map +1 -1
  43. package/dist/agent/tool-registry.js +62 -30
  44. package/dist/agent/tool-registry.js.map +1 -1
  45. package/dist/agent/types.d.ts +62 -3
  46. package/dist/agent/types.d.ts.map +1 -1
  47. package/dist/agent/types.js +31 -1
  48. package/dist/agent/types.js.map +1 -1
  49. package/dist/api/graph-api-types.d.ts +8 -0
  50. package/dist/api/graph-api-types.d.ts.map +1 -1
  51. package/dist/api/graph-api.d.ts.map +1 -1
  52. package/dist/api/graph-api.js +14 -0
  53. package/dist/api/graph-api.js.map +1 -1
  54. package/dist/api/index.d.ts +10 -0
  55. package/dist/api/index.d.ts.map +1 -1
  56. package/dist/api/index.js +7 -16
  57. package/dist/api/index.js.map +1 -1
  58. package/dist/cli/commands/connector.d.ts +6 -1
  59. package/dist/cli/commands/connector.d.ts.map +1 -1
  60. package/dist/cli/commands/connector.js +61 -45
  61. package/dist/cli/commands/connector.js.map +1 -1
  62. package/dist/cli/commands/start.d.ts +16 -9
  63. package/dist/cli/commands/start.d.ts.map +1 -1
  64. package/dist/cli/commands/start.js +177 -91
  65. package/dist/cli/commands/start.js.map +1 -1
  66. package/dist/cli/config/types.d.ts.map +1 -1
  67. package/dist/cli/config/types.js +0 -4
  68. package/dist/cli/config/types.js.map +1 -1
  69. package/dist/cli/runtime/api-routes-init.d.ts +38 -1
  70. package/dist/cli/runtime/api-routes-init.d.ts.map +1 -1
  71. package/dist/cli/runtime/api-routes-init.js +150 -30
  72. package/dist/cli/runtime/api-routes-init.js.map +1 -1
  73. package/dist/cli/runtime/api-server-init.d.ts +4 -0
  74. package/dist/cli/runtime/api-server-init.d.ts.map +1 -1
  75. package/dist/cli/runtime/api-server-init.js +3 -1
  76. package/dist/cli/runtime/api-server-init.js.map +1 -1
  77. package/dist/cli/runtime/code-act-executor.d.ts +14 -0
  78. package/dist/cli/runtime/code-act-executor.d.ts.map +1 -0
  79. package/dist/cli/runtime/code-act-executor.js +103 -0
  80. package/dist/cli/runtime/code-act-executor.js.map +1 -0
  81. package/dist/cli/runtime/connector-bootstrap.d.ts +8 -0
  82. package/dist/cli/runtime/connector-bootstrap.d.ts.map +1 -0
  83. package/dist/cli/runtime/connector-bootstrap.js +14 -0
  84. package/dist/cli/runtime/connector-bootstrap.js.map +1 -0
  85. package/dist/cli/runtime/connector-init.d.ts +4 -1
  86. package/dist/cli/runtime/connector-init.d.ts.map +1 -1
  87. package/dist/cli/runtime/connector-init.js +2 -8
  88. package/dist/cli/runtime/connector-init.js.map +1 -1
  89. package/dist/cli/runtime/envelope-bootstrap.d.ts +2 -1
  90. package/dist/cli/runtime/envelope-bootstrap.d.ts.map +1 -1
  91. package/dist/cli/runtime/envelope-bootstrap.js +7 -15
  92. package/dist/cli/runtime/envelope-bootstrap.js.map +1 -1
  93. package/dist/connectors/index.d.ts +4 -1
  94. package/dist/connectors/index.d.ts.map +1 -1
  95. package/dist/connectors/index.js +3 -2
  96. package/dist/connectors/index.js.map +1 -1
  97. package/dist/connectors/private-connector-policy.d.ts +150 -0
  98. package/dist/connectors/private-connector-policy.d.ts.map +1 -0
  99. package/dist/connectors/private-connector-policy.js +289 -0
  100. package/dist/connectors/private-connector-policy.js.map +1 -0
  101. package/dist/connectors/private-prompt-overlay.d.ts +17 -0
  102. package/dist/connectors/private-prompt-overlay.d.ts.map +1 -0
  103. package/dist/connectors/private-prompt-overlay.js +156 -0
  104. package/dist/connectors/private-prompt-overlay.js.map +1 -0
  105. package/dist/db/migrations/operator-task-external-lifecycle.d.ts +8 -0
  106. package/dist/db/migrations/operator-task-external-lifecycle.d.ts.map +1 -0
  107. package/dist/db/migrations/operator-task-external-lifecycle.js +169 -0
  108. package/dist/db/migrations/operator-task-external-lifecycle.js.map +1 -0
  109. package/dist/envelope/enforcer.js +8 -7
  110. package/dist/envelope/enforcer.js.map +1 -1
  111. package/dist/envelope/reactive-config.d.ts.map +1 -1
  112. package/dist/envelope/reactive-config.js +2 -1
  113. package/dist/envelope/reactive-config.js.map +1 -1
  114. package/dist/envelope/tool-connector-scope.d.ts.map +1 -1
  115. package/dist/envelope/tool-connector-scope.js +4 -0
  116. package/dist/envelope/tool-connector-scope.js.map +1 -1
  117. package/dist/gateways/message-router.d.ts +11 -1
  118. package/dist/gateways/message-router.d.ts.map +1 -1
  119. package/dist/gateways/message-router.js +121 -41
  120. package/dist/gateways/message-router.js.map +1 -1
  121. package/dist/gateways/telegram-message-ledger.d.ts +8 -1
  122. package/dist/gateways/telegram-message-ledger.d.ts.map +1 -1
  123. package/dist/gateways/telegram-message-ledger.js +141 -24
  124. package/dist/gateways/telegram-message-ledger.js.map +1 -1
  125. package/dist/gateways/telegram.d.ts +2 -0
  126. package/dist/gateways/telegram.d.ts.map +1 -1
  127. package/dist/gateways/telegram.js +19 -12
  128. package/dist/gateways/telegram.js.map +1 -1
  129. package/dist/mcp/code-act-api-client.d.ts +12 -0
  130. package/dist/mcp/code-act-api-client.d.ts.map +1 -1
  131. package/dist/mcp/code-act-api-client.js.map +1 -1
  132. package/dist/mcp/code-act-server.js +9 -27
  133. package/dist/mcp/code-act-server.js.map +1 -1
  134. package/dist/mcp/code-act-terminal-transport.d.ts +27 -0
  135. package/dist/mcp/code-act-terminal-transport.d.ts.map +1 -1
  136. package/dist/mcp/code-act-terminal-transport.js +70 -7
  137. package/dist/mcp/code-act-terminal-transport.js.map +1 -1
  138. package/dist/multi-agent/agent-process-manager.d.ts +9 -1
  139. package/dist/multi-agent/agent-process-manager.d.ts.map +1 -1
  140. package/dist/multi-agent/agent-process-manager.js +48 -20
  141. package/dist/multi-agent/agent-process-manager.js.map +1 -1
  142. package/dist/multi-agent/dashboard-agent-persona.d.ts +3 -3
  143. package/dist/multi-agent/dashboard-agent-persona.d.ts.map +1 -1
  144. package/dist/multi-agent/dashboard-agent-persona.js +10 -13
  145. package/dist/multi-agent/dashboard-agent-persona.js.map +1 -1
  146. package/dist/multi-agent/memory-agent-persona.d.ts +1 -1
  147. package/dist/multi-agent/memory-agent-persona.d.ts.map +1 -1
  148. package/dist/multi-agent/memory-agent-persona.js +1 -1
  149. package/dist/multi-agent/wiki-agent-persona.d.ts +2 -2
  150. package/dist/multi-agent/wiki-agent-persona.js +2 -2
  151. package/dist/operator/board-slot-instructions.d.ts +1 -1
  152. package/dist/operator/board-slot-instructions.js +2 -2
  153. package/dist/operator/board-slot-instructions.js.map +1 -1
  154. package/dist/operator/briefs.d.ts +3 -0
  155. package/dist/operator/briefs.d.ts.map +1 -1
  156. package/dist/operator/briefs.js +64 -3
  157. package/dist/operator/briefs.js.map +1 -1
  158. package/dist/operator/console-brief.d.ts +6 -3
  159. package/dist/operator/console-brief.d.ts.map +1 -1
  160. package/dist/operator/console-brief.js +39 -9
  161. package/dist/operator/console-brief.js.map +1 -1
  162. package/dist/operator/external-lifecycle-candidates.d.ts +56 -0
  163. package/dist/operator/external-lifecycle-candidates.d.ts.map +1 -0
  164. package/dist/operator/external-lifecycle-candidates.js +415 -0
  165. package/dist/operator/external-lifecycle-candidates.js.map +1 -0
  166. package/dist/operator/external-lifecycle.d.ts +82 -0
  167. package/dist/operator/external-lifecycle.d.ts.map +1 -0
  168. package/dist/operator/external-lifecycle.js +27 -0
  169. package/dist/operator/external-lifecycle.js.map +1 -0
  170. package/dist/operator/file-coordination.d.ts +7 -0
  171. package/dist/operator/file-coordination.d.ts.map +1 -0
  172. package/dist/operator/file-coordination.js +84 -0
  173. package/dist/operator/file-coordination.js.map +1 -0
  174. package/dist/operator/operator-trigger-loop.d.ts +19 -4
  175. package/dist/operator/operator-trigger-loop.d.ts.map +1 -1
  176. package/dist/operator/operator-trigger-loop.js +151 -23
  177. package/dist/operator/operator-trigger-loop.js.map +1 -1
  178. package/dist/operator/pending-report-store.d.ts +62 -3
  179. package/dist/operator/pending-report-store.d.ts.map +1 -1
  180. package/dist/operator/pending-report-store.js +297 -40
  181. package/dist/operator/pending-report-store.js.map +1 -1
  182. package/dist/operator/report-carry-delivery.d.ts +35 -0
  183. package/dist/operator/report-carry-delivery.d.ts.map +1 -0
  184. package/dist/operator/report-carry-delivery.js +55 -0
  185. package/dist/operator/report-carry-delivery.js.map +1 -0
  186. package/dist/operator/report-carry.d.ts +50 -30
  187. package/dist/operator/report-carry.d.ts.map +1 -1
  188. package/dist/operator/report-carry.js +323 -71
  189. package/dist/operator/report-carry.js.map +1 -1
  190. package/dist/operator/report-run.d.ts.map +1 -1
  191. package/dist/operator/report-run.js +38 -97
  192. package/dist/operator/report-run.js.map +1 -1
  193. package/dist/operator/situation-report.d.ts +30 -11
  194. package/dist/operator/situation-report.d.ts.map +1 -1
  195. package/dist/operator/situation-report.js +42 -13
  196. package/dist/operator/situation-report.js.map +1 -1
  197. package/dist/operator/task-ledger.d.ts +101 -0
  198. package/dist/operator/task-ledger.d.ts.map +1 -1
  199. package/dist/operator/task-ledger.js +599 -124
  200. package/dist/operator/task-ledger.js.map +1 -1
  201. package/dist/operator/temporal-worker.js +1 -1
  202. package/dist/operator/worker-run.d.ts +1 -1
  203. package/dist/operator/worker-run.d.ts.map +1 -1
  204. package/dist/operator/worker-run.js +17 -5
  205. package/dist/operator/worker-run.js.map +1 -1
  206. package/dist/operator/workorder-consumer.d.ts +12 -1
  207. package/dist/operator/workorder-consumer.d.ts.map +1 -1
  208. package/dist/operator/workorder-consumer.js +133 -7
  209. package/dist/operator/workorder-consumer.js.map +1 -1
  210. package/dist/operator/workorder-hooks.d.ts +7 -2
  211. package/dist/operator/workorder-hooks.d.ts.map +1 -1
  212. package/dist/operator/workorder-hooks.js +22 -0
  213. package/dist/operator/workorder-hooks.js.map +1 -1
  214. package/dist/operator/workorder-publishers.d.ts +9 -2
  215. package/dist/operator/workorder-publishers.d.ts.map +1 -1
  216. package/dist/operator/workorder-publishers.js +167 -5
  217. package/dist/operator/workorder-publishers.js.map +1 -1
  218. package/package.json +2 -2
  219. package/scripts/generate-gateway-tools.ts +13 -3
@@ -68,6 +68,7 @@ const image_translation_tools_js_1 = require("./image-translation-tools.js");
68
68
  const attachment_text_extractor_js_1 = require("./attachment-text-extractor.js");
69
69
  const untrusted_content_js_1 = require("../utils/untrusted-content.js");
70
70
  const types_js_1 = require("./types.js");
71
+ const external_lifecycle_candidates_js_1 = require("../operator/external-lifecycle-candidates.js");
71
72
  const sqlite_js_1 = __importDefault(require("../sqlite.js"));
72
73
  const mama_tool_handlers_js_1 = require("./mama-tool-handlers.js");
73
74
  const role_manager_js_1 = require("./role-manager.js");
@@ -77,6 +78,12 @@ const index_js_1 = require("../envelope/index.js");
77
78
  const wiki_publish_adapter_js_1 = require("../wiki-artifacts/wiki-publish-adapter.js");
78
79
  const changes_projection_js_1 = require("../operator/changes-projection.js");
79
80
  const read_js_1 = require("../evidence/read.js");
81
+ const private_connector_policy_js_1 = require("../connectors/private-connector-policy.js");
82
+ const DEFAULT_PRIVATE_CONNECTOR_POLICY = (0, private_connector_policy_js_1.resolvePrivateConnectorPolicy)({
83
+ ok: true,
84
+ config: {},
85
+ enabledNames: [],
86
+ });
80
87
  function serializeTaskToolRecord(task) {
81
88
  return {
82
89
  ...task,
@@ -360,6 +367,7 @@ class GatewayToolExecutor {
360
367
  slackGateway = null;
361
368
  telegramGateway = null;
362
369
  roleManager;
370
+ privateConnectorPolicy;
363
371
  executionContextStorage = new async_hooks_1.AsyncLocalStorage();
364
372
  envelopeEnforcer = new index_js_1.EnvelopeEnforcer();
365
373
  channelGrantProvider;
@@ -592,6 +600,8 @@ class GatewayToolExecutor {
592
600
  this.wikiPublishAdapter = options.wikiPublishAdapter ?? null;
593
601
  // Pass rolesConfig from config.yaml to RoleManager
594
602
  this.roleManager = (0, role_manager_js_1.getRoleManager)(options.rolesConfig ? { rolesConfig: options.rolesConfig } : undefined);
603
+ this.privateConnectorPolicy =
604
+ options.privateConnectorPolicy ?? DEFAULT_PRIVATE_CONNECTOR_POLICY;
595
605
  if (options.mamaApi) {
596
606
  this.mamaApi = options.mamaApi;
597
607
  }
@@ -721,26 +731,34 @@ class GatewayToolExecutor {
721
731
  * @returns Object with allowed status and optional error message
722
732
  */
723
733
  checkToolPermission(toolName) {
724
- // If no context set, allow all tools (backward compatibility)
725
734
  const context = this.getActiveContext();
726
- if (!context) {
727
- if (toolName === 'code_act') {
728
- return {
729
- allowed: false,
730
- error: 'Permission denied: code_act requires an active agent role',
731
- };
732
- }
733
- return { allowed: true };
735
+ if (!context && toolName === 'code_act') {
736
+ return {
737
+ allowed: false,
738
+ error: 'Permission denied: code_act requires an active agent role',
739
+ };
734
740
  }
735
- const role = context.role;
741
+ const role = context
742
+ ? this.projectPrivateAgentContext(context).role
743
+ : this.privateConnectorPolicy.projectRole('legacy-unbound', { allowedTools: ['*'] });
736
744
  if (!this.roleManager.isToolAllowed(role, toolName)) {
737
745
  return {
738
746
  allowed: false,
739
- error: `Permission denied: ${toolName} is not allowed for role "${context.roleName}"`,
747
+ error: `Permission denied: ${toolName} is not allowed for role "${context?.roleName ?? 'legacy-unbound'}"`,
740
748
  };
741
749
  }
742
750
  return { allowed: true };
743
751
  }
752
+ projectPrivateAgentContext(context) {
753
+ const surface = (0, private_connector_policy_js_1.resolvePrivatePrincipalSurface)({ agentContext: context });
754
+ const role = this.privateConnectorPolicy.projectRole(surface, context.role);
755
+ return {
756
+ ...context,
757
+ role,
758
+ capabilities: this.roleManager.getCapabilities(role),
759
+ limitations: this.roleManager.getLimitations(role),
760
+ };
761
+ }
744
762
  /**
745
763
  * Check if a path is allowed for the current context
746
764
  * @param path - File path to check
@@ -955,7 +973,7 @@ class GatewayToolExecutor {
955
973
  toolName === 'context_compile' ||
956
974
  toolName === 'code_act';
957
975
  auditResult = shouldSanitizeAuditFailure
958
- ? sanitizeGatewayFailureResult(rawResult, Boolean(activeCtx.temporalWorkContext))
976
+ ? sanitizeGatewayFailureResult(rawResult, Boolean(activeCtx.temporalWorkContext), toolName === 'code_act')
959
977
  : rawResult;
960
978
  result = activeCtx.temporalWorkContext ? auditResult : rawResult;
961
979
  const rawResultRecord = rawResult;
@@ -1004,6 +1022,35 @@ class GatewayToolExecutor {
1004
1022
  }
1005
1023
  return result;
1006
1024
  }
1025
+ /**
1026
+ * External lifecycle decisions are only valid while the host-created model run that owns the
1027
+ * claimed board attempt is still running. Tool input cannot name either authority.
1028
+ */
1029
+ async requireExternalLifecycleModelRun(attemptId) {
1030
+ const modelRunId = this.getExecutionState().modelRunId;
1031
+ if (typeof modelRunId !== 'string' ||
1032
+ modelRunId.trim().length === 0 ||
1033
+ modelRunId.trim() !== modelRunId) {
1034
+ throw new types_js_1.AgentError('External lifecycle authority requires a current host-issued model run', 'WORKORDER_SUPERSEDED', undefined, false);
1035
+ }
1036
+ const api = await this.initializeMAMAApi();
1037
+ if (!api.getModelRun) {
1038
+ throw new types_js_1.AgentError('External lifecycle model-run authority is unavailable', 'WORKORDER_SUPERSEDED', undefined, false);
1039
+ }
1040
+ let modelRun;
1041
+ try {
1042
+ modelRun = await api.getModelRun(modelRunId);
1043
+ }
1044
+ catch (error) {
1045
+ throw new types_js_1.AgentError('External lifecycle model-run authority could not be verified', 'WORKORDER_SUPERSEDED', error instanceof Error ? error : undefined, false);
1046
+ }
1047
+ if (!modelRun ||
1048
+ modelRun.status !== 'running' ||
1049
+ modelRun.input_refs?.workorderAttemptId !== attemptId) {
1050
+ throw new types_js_1.AgentError('External lifecycle authority is no longer current for this claimed attempt', 'WORKORDER_SUPERSEDED', undefined, false);
1051
+ }
1052
+ return modelRunId;
1053
+ }
1007
1054
  async beginTraceIfNeeded(ctx, gatewayCallId) {
1008
1055
  if (ctx.modelRunId) {
1009
1056
  const api = await this.initializeMAMAApi();
@@ -1445,7 +1492,7 @@ class GatewayToolExecutor {
1445
1492
  async executeWithEnvelopeAndPermissions(toolName, input, gatewayCallId) {
1446
1493
  this.getExecutionState().signal?.throwIfAborted();
1447
1494
  if (!VALID_TOOLS.includes(toolName)) {
1448
- throw new types_js_1.AgentError(`Unknown tool: ${toolName}. Valid tools: ${VALID_TOOLS.join(', ')}`, 'UNKNOWN_TOOL', undefined, false);
1495
+ throw new types_js_1.AgentError(`Unknown tool: ${toolName}`, 'UNKNOWN_TOOL', undefined, false);
1449
1496
  }
1450
1497
  if (toolName.startsWith('drive_') &&
1451
1498
  this.getExecutionState().agentContext?.roleName !== 'owner_console') {
@@ -2063,6 +2110,84 @@ class GatewayToolExecutor {
2063
2110
  };
2064
2111
  }
2065
2112
  }
2113
+ case 'task_external_bind': {
2114
+ if (!this.taskLedger) {
2115
+ return { success: false, error: 'Task ledger not configured' };
2116
+ }
2117
+ const state = this.getExecutionState();
2118
+ const attemptId = state.workorderAttemptId;
2119
+ if (attemptId === undefined || !Number.isSafeInteger(attemptId) || attemptId <= 0) {
2120
+ throw new types_js_1.AgentError('task_external_bind requires a trusted claimed board attempt', 'WORKORDER_SUPERSEDED', undefined, false);
2121
+ }
2122
+ try {
2123
+ (0, external_lifecycle_candidates_js_1.validateExternalLifecycleDecision)('binding', input);
2124
+ }
2125
+ catch (error) {
2126
+ throw new types_js_1.AgentError(error instanceof Error ? error.message : 'task_external_bind input is invalid', 'TOOL_ERROR', error instanceof Error ? error : undefined, false);
2127
+ }
2128
+ const modelRunId = await this.requireExternalLifecycleModelRun(attemptId);
2129
+ let candidate;
2130
+ try {
2131
+ candidate = this.taskLedger.loadBoardCandidate(attemptId, input.candidate_id, 'binding');
2132
+ }
2133
+ catch (error) {
2134
+ throw new types_js_1.AgentError(error instanceof Error
2135
+ ? error.message
2136
+ : 'task_external_bind candidate is unavailable', 'WORKORDER_SUPERSEDED', error instanceof Error ? error : undefined, false);
2137
+ }
2138
+ const receipt = this.taskLedger.applyExternalBindingDecision(attemptId, input, {
2139
+ runId: modelRunId,
2140
+ workOrderAttemptId: attemptId,
2141
+ causeEventIds: [candidate.eventId],
2142
+ });
2143
+ return {
2144
+ success: true,
2145
+ receipt: {
2146
+ taskId: receipt.taskId,
2147
+ workorderAttemptId: receipt.workOrderAttemptId,
2148
+ outcome: receipt.outcome,
2149
+ },
2150
+ };
2151
+ }
2152
+ case 'task_lifecycle_reconcile': {
2153
+ if (!this.taskLedger) {
2154
+ return { success: false, error: 'Task ledger not configured' };
2155
+ }
2156
+ const state = this.getExecutionState();
2157
+ const attemptId = state.workorderAttemptId;
2158
+ if (attemptId === undefined || !Number.isSafeInteger(attemptId) || attemptId <= 0) {
2159
+ throw new types_js_1.AgentError('task_lifecycle_reconcile requires a trusted claimed board attempt', 'WORKORDER_SUPERSEDED', undefined, false);
2160
+ }
2161
+ try {
2162
+ (0, external_lifecycle_candidates_js_1.validateExternalLifecycleDecision)('lifecycle', input);
2163
+ }
2164
+ catch (error) {
2165
+ throw new types_js_1.AgentError(error instanceof Error ? error.message : 'task_lifecycle_reconcile input is invalid', 'TOOL_ERROR', error instanceof Error ? error : undefined, false);
2166
+ }
2167
+ const modelRunId = await this.requireExternalLifecycleModelRun(attemptId);
2168
+ let candidate;
2169
+ try {
2170
+ candidate = this.taskLedger.loadBoardCandidate(attemptId, input.candidate_id, 'lifecycle');
2171
+ }
2172
+ catch (error) {
2173
+ throw new types_js_1.AgentError(error instanceof Error
2174
+ ? error.message
2175
+ : 'task_lifecycle_reconcile candidate is unavailable', 'WORKORDER_SUPERSEDED', error instanceof Error ? error : undefined, false);
2176
+ }
2177
+ const receipt = this.taskLedger.applyExternalLifecycleDecision(attemptId, input, {
2178
+ runId: modelRunId,
2179
+ workOrderAttemptId: attemptId,
2180
+ causeEventIds: [candidate.eventId],
2181
+ });
2182
+ return {
2183
+ success: true,
2184
+ receipt: {
2185
+ taskId: receipt.taskId,
2186
+ workorderAttemptId: receipt.workOrderAttemptId,
2187
+ outcome: receipt.outcome,
2188
+ },
2189
+ };
2190
+ }
2066
2191
  case 'task_create': {
2067
2192
  if (!this.taskLedger) {
2068
2193
  return { success: false, error: 'Task ledger not configured' };
@@ -2075,6 +2200,7 @@ class GatewayToolExecutor {
2075
2200
  // else's work with it.
2076
2201
  this.taskLedger.create(input, {
2077
2202
  runId: this.getExecutionState().modelRunId ?? null,
2203
+ workOrderAttemptId: this.getExecutionState().workorderAttemptId,
2078
2204
  causeEventIds: this.getExecutionState().causeEventIds,
2079
2205
  causeKind: this.getExecutionState().source === 'operator' ? 'clock' : 'owner_message',
2080
2206
  })),
@@ -2092,6 +2218,7 @@ class GatewayToolExecutor {
2092
2218
  }
2093
2219
  const updated = this.taskLedger.update(id, patch, {
2094
2220
  runId: this.getExecutionState().modelRunId ?? null,
2221
+ workOrderAttemptId: this.getExecutionState().workorderAttemptId,
2095
2222
  // The batch this run was handed. A bounded run's changes rest on the delta it
2096
2223
  // was given, and the system knew that before the run began - so there is
2097
2224
  // nothing to ask the agent for.
@@ -2847,14 +2974,17 @@ class GatewayToolExecutor {
2847
2974
  const { CodeActSandbox, CodeActToolPolicyValidationError, CODE_ACT_MUTATION_COMMITTED_AFTER_ABORT, CODE_ACT_MUTATION_OUTCOME_UNKNOWN, HostBridge, projectCodeActToolPolicy, } = await import('./code-act/index.js');
2848
2975
  const sandbox = new CodeActSandbox();
2849
2976
  const state = this.getExecutionState();
2850
- const contextTier = state.agentContext?.tier;
2977
+ const projectedAgentContext = state.agentContext
2978
+ ? this.projectPrivateAgentContext(state.agentContext)
2979
+ : undefined;
2980
+ const contextTier = projectedAgentContext?.tier;
2851
2981
  const tier = contextTier === undefined ? 1 : contextTier;
2852
2982
  let policy;
2853
2983
  try {
2854
2984
  policy = projectCodeActToolPolicy({
2855
2985
  tier,
2856
- roleName: state.agentContext?.roleName,
2857
- role: state.agentContext?.role,
2986
+ roleName: projectedAgentContext?.roleName,
2987
+ role: projectedAgentContext?.role,
2858
2988
  disallowedTools: state.disallowedGatewayTools,
2859
2989
  requestedAllowedTools: input.allowedTools,
2860
2990
  requestedBlockedTools: input.blockedTools,
@@ -2878,6 +3008,10 @@ class GatewayToolExecutor {
2878
3008
  }
2879
3009
  const nestedExecutionContext = {
2880
3010
  ...state,
3011
+ // Preserve the registry-supplied principal object as provenance. The
3012
+ // policy above and every nested final authorization re-project it from
3013
+ // the immutable boot snapshot; replacing the object would blur which
3014
+ // trusted context the keyed call actually carried.
2881
3015
  agentContext: state.agentContext ?? undefined,
2882
3016
  executionSurface: 'code_act',
2883
3017
  parentToolName: 'code_act',
@@ -2888,12 +3022,24 @@ class GatewayToolExecutor {
2888
3022
  // result !== undefined - host-bridge.ts:1049; the pre-call fire at :1037 is skipped).
2889
3023
  // Ride in the result message so downstream audits (report-run summarizeReportToolUse)
2890
3024
  // can classify nested gather/write without code_act becoming an opaque blob.
3025
+ const hostToolExecutions = [];
2891
3026
  const hostToolsInvoked = [];
3027
+ const successfulHostToolNames = new Set();
2892
3028
  bridge.onToolUse = (toolName, _toolInput, result) => {
2893
3029
  if (result === undefined) {
2894
3030
  return;
2895
3031
  }
2896
- hostToolsInvoked.push(toolName);
3032
+ const resultRecord = result;
3033
+ const success = resultRecord.success === true;
3034
+ hostToolExecutions.push({
3035
+ name: toolName,
3036
+ success,
3037
+ ...(typeof resultRecord.code === 'string' ? { code: resultRecord.code } : {}),
3038
+ });
3039
+ if (success && !successfulHostToolNames.has(toolName)) {
3040
+ successfulHostToolNames.add(toolName);
3041
+ hostToolsInvoked.push(toolName);
3042
+ }
2897
3043
  // Board/card text is written by people outside this system and now reaches the
2898
3044
  // report lane, whose composed text is delivered to the owner verbatim by host
2899
3045
  // code with no intervening model. Deriving this from the connector map keeps a
@@ -2911,9 +3057,15 @@ class GatewayToolExecutor {
2911
3057
  if (result.error?.code && terminalMutationCodes.has(result.error.code)) {
2912
3058
  return {
2913
3059
  success: false,
3060
+ value: result.value,
3061
+ logs: result.logs,
3062
+ error: result.error.message,
2914
3063
  code: result.error.code,
2915
3064
  retryable: false,
2916
3065
  abort: true,
3066
+ metrics: result.metrics,
3067
+ hostToolExecutions,
3068
+ hostToolsInvoked,
2917
3069
  message: `Code-Act error: ${result.error.message}`,
2918
3070
  };
2919
3071
  }
@@ -2925,6 +3077,12 @@ class GatewayToolExecutor {
2925
3077
  });
2926
3078
  return {
2927
3079
  success: result.success,
3080
+ value: result.value,
3081
+ logs: result.logs,
3082
+ ...(result.error?.message ? { error: result.error.message } : {}),
3083
+ metrics: result.metrics,
3084
+ hostToolExecutions,
3085
+ hostToolsInvoked,
2928
3086
  message: result.success
2929
3087
  ? usedUntrustedExternalEvidence
2930
3088
  ? (0, untrusted_content_js_1.wrapUntrustedContent)('external-evidence-code-act', successfulMessage)
@@ -3318,20 +3476,56 @@ function gatewayFailureRef(value, temporal) {
3318
3476
  const label = temporal ? 'temporal_tool_failed' : 'gateway_tool_failed';
3319
3477
  return `${label};sha256=${digest};length=${value.length}`;
3320
3478
  }
3321
- function sanitizeGatewayFailureResult(result, temporal) {
3479
+ function sanitizeGatewayFailureResult(result, temporal, preserveCodeActAudit = false) {
3322
3480
  const failure = getFailureMessage(result);
3323
3481
  if (!failure) {
3324
3482
  return result;
3325
3483
  }
3326
3484
  const record = result;
3485
+ const hostToolExecutions = preserveCodeActAudit
3486
+ ? normalizeHostToolExecutionAudit(record.hostToolExecutions)
3487
+ : [];
3488
+ const hostToolsInvoked = [
3489
+ ...new Set(hostToolExecutions.filter((execution) => execution.success).map((execution) => execution.name)),
3490
+ ];
3327
3491
  return {
3328
3492
  success: false,
3329
3493
  error: gatewayFailureRef(failure, temporal),
3330
3494
  ...(typeof record.code === 'string' ? { code: record.code } : {}),
3331
3495
  ...(record.retryable === false ? { retryable: false } : {}),
3332
3496
  ...(record.abort === true ? { abort: true } : {}),
3497
+ ...(preserveCodeActAudit ? { hostToolExecutions, hostToolsInvoked } : {}),
3333
3498
  };
3334
3499
  }
3500
+ function normalizeHostToolExecutionAudit(value) {
3501
+ if (!Array.isArray(value)) {
3502
+ return [];
3503
+ }
3504
+ const executions = [];
3505
+ let droppedCount = 0;
3506
+ for (const entry of value) {
3507
+ if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) {
3508
+ droppedCount += 1;
3509
+ continue;
3510
+ }
3511
+ const record = entry;
3512
+ if (typeof record.name !== 'string' || typeof record.success !== 'boolean') {
3513
+ droppedCount += 1;
3514
+ continue;
3515
+ }
3516
+ executions.push({
3517
+ name: record.name,
3518
+ success: record.success,
3519
+ ...(typeof record.code === 'string' ? { code: record.code } : {}),
3520
+ });
3521
+ }
3522
+ if (droppedCount > 0) {
3523
+ securityLogger.warn('[code-act] dropped malformed host-tool audit entries', {
3524
+ droppedCount,
3525
+ });
3526
+ }
3527
+ return executions;
3528
+ }
3335
3529
  function sanitizeGatewayError(error, temporal) {
3336
3530
  const message = error instanceof Error ? error.message : String(error);
3337
3531
  if (error instanceof types_js_1.AgentError) {