@sema-agent/client-core 0.99.0 → 0.101.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 (374) hide show
  1. package/CHANGELOG.md +572 -0
  2. package/README.md +174 -114
  3. package/dist/adapt/arms.js +109 -50
  4. package/dist/adapt/panelTasks.d.ts +2 -1
  5. package/dist/adapt/panelTasks.js +32 -9
  6. package/dist/adapt/textStream.d.ts +1 -1
  7. package/dist/adapt/textStream.js +58 -32
  8. package/dist/adapt/toolCards.js +9 -8
  9. package/dist/adapt.js +7 -1
  10. package/dist/adapter/activeRunSelfHeal.d.ts +31 -2
  11. package/dist/adapter/activeRunSelfHeal.js +162 -13
  12. package/dist/adapter/downstream/eventToSdkMessage.d.ts +25 -6
  13. package/dist/adapter/downstream/eventToSdkMessage.js +157 -20
  14. package/dist/adapter/downstream/terminalToSdkResult.d.ts +60 -1
  15. package/dist/adapter/downstream/terminalToSdkResult.js +219 -39
  16. package/dist/adapter/downstream/wiringManifestView.d.ts +3 -1
  17. package/dist/adapter/downstream/wiringManifestView.js +1 -0
  18. package/dist/adapter/runStream.d.ts +4 -4
  19. package/dist/adapter/runStream.js +184 -42
  20. package/dist/adapter/types.d.ts +2 -0
  21. package/dist/agentsWireCaps.d.ts +9 -7
  22. package/dist/agentsWireCaps.js +101 -17
  23. package/dist/approvalDecidedByCapability.js +2 -2
  24. package/dist/approvalFrameFamilies.d.ts +33 -0
  25. package/dist/approvalFrameFamilies.js +120 -0
  26. package/dist/approvalsStreamLiveCapability.js +2 -2
  27. package/dist/attachmentsWireCaps.js +41 -13
  28. package/dist/callerCwdCapability.js +2 -2
  29. package/dist/centerWiringCapability.js +2 -2
  30. package/dist/clockReading.d.ts +2 -0
  31. package/dist/clockReading.js +4 -0
  32. package/dist/cloudConfigWireCaps.d.ts +28 -5
  33. package/dist/cloudConfigWireCaps.js +334 -103
  34. package/dist/compactionStatus.d.ts +34 -0
  35. package/dist/compactionStatus.js +196 -0
  36. package/dist/coreValuePorts.d.ts +12 -2
  37. package/dist/coreValuePorts.js +9 -0
  38. package/dist/decideFailureNote.js +8 -6
  39. package/dist/decideReceipt.js +2 -2
  40. package/dist/deviceExecutorManagementCapability.js +2 -2
  41. package/dist/deviceFlowPolling.js +1 -1
  42. package/dist/disableSkillsWire.d.ts +1 -1
  43. package/dist/disableSkillsWire.js +4 -3
  44. package/dist/displayUntrusted.d.ts +1 -0
  45. package/dist/displayUntrusted.js +215 -13
  46. package/dist/engineAgentPanelStore.d.ts +7 -4
  47. package/dist/engineCapReader.js +1 -1
  48. package/dist/engineConfigDrift.js +1 -1
  49. package/dist/engineErrorCodes.d.ts +23 -6
  50. package/dist/engineErrorCodes.js +36 -11
  51. package/dist/engineGenerationConvergence.d.ts +39 -0
  52. package/dist/engineGenerationConvergence.js +95 -0
  53. package/dist/engineGenerationPort.d.ts +61 -0
  54. package/dist/engineGenerationPort.js +144 -0
  55. package/dist/engineHealthFacts.d.ts +23 -0
  56. package/dist/engineHealthFacts.js +92 -0
  57. package/dist/engineIdentity.d.ts +4 -0
  58. package/dist/engineIdentity.js +11 -0
  59. package/dist/engineNoticeCodes.d.ts +2 -5
  60. package/dist/engineRowRef.js +4 -0
  61. package/dist/engineSessionMessages.js +2 -2
  62. package/dist/engineToolDirectory.d.ts +3 -0
  63. package/dist/engineToolDirectory.js +6 -4
  64. package/dist/engineWireFor.d.ts +99 -0
  65. package/dist/engineWireFor.js +248 -6
  66. package/dist/engineWireTarget.d.ts +1 -0
  67. package/dist/engineWireTarget.js +8 -0
  68. package/dist/env/uiLanguage.js +1 -1
  69. package/dist/errorSupplementRoles.d.ts +3 -0
  70. package/dist/errorSupplementRoles.js +37 -0
  71. package/dist/eventLeg.d.ts +1 -7
  72. package/dist/eventLeg.js +7 -8
  73. package/dist/executionLaneCapability.js +2 -2
  74. package/dist/fileHistoryCaptureCapability.d.ts +0 -3
  75. package/dist/fileHistoryCaptureCapability.js +3 -7
  76. package/dist/finalVerifyWire.d.ts +6 -3
  77. package/dist/finalVerifyWire.js +6 -23
  78. package/dist/flagInput.d.ts +4 -0
  79. package/dist/flagInput.js +24 -0
  80. package/dist/fleet/fleetLedger.js +5 -2
  81. package/dist/fleet/fleetProjection.d.ts +1 -0
  82. package/dist/fleet/fleetProjection.js +15 -2
  83. package/dist/gateVocabulary.js +3 -0
  84. package/dist/generated/engineFactTables.d.ts +7 -2
  85. package/dist/generated/engineFactTables.js +79 -0
  86. package/dist/generated/engineNoticeTables.js +15 -0
  87. package/dist/generated/settingsSchemaActiveTiers.d.ts +1 -0
  88. package/dist/generated/settingsSchemaActiveTiers.js +14 -0
  89. package/dist/generated/settingsSchemaCallerTextEcho.d.ts +1 -0
  90. package/dist/generated/settingsSchemaCallerTextEcho.js +8 -0
  91. package/dist/generated/settingsSchemaControlAndBidi.d.ts +1 -0
  92. package/dist/generated/settingsSchemaControlAndBidi.js +8 -0
  93. package/dist/generated/settingsSchemaDefaultModel.d.ts +11 -0
  94. package/dist/generated/settingsSchemaDefaultModel.js +25 -0
  95. package/dist/generated/settingsSchemaFns.d.ts +66 -0
  96. package/dist/generated/settingsSchemaFns.js +38 -0
  97. package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -0
  98. package/dist/generated/settingsSchemaMcpRequestEntry.js +156 -0
  99. package/dist/generated/settingsSchemaSafetyMergeSpec.d.ts +1 -0
  100. package/dist/generated/settingsSchemaSafetyMergeSpec.js +95 -0
  101. package/dist/generated/settingsSchemaSettingsSources.d.ts +1 -0
  102. package/dist/generated/settingsSchemaSettingsSources.js +58 -0
  103. package/dist/generated/settingsSchemaTables.d.ts +3 -0
  104. package/dist/generated/settingsSchemaTables.js +18 -0
  105. package/dist/generated/settingsSchemaTypes.d.ts +28 -0
  106. package/dist/generated/settingsSchemaUrlPattern.d.ts +1 -0
  107. package/dist/generated/settingsSchemaUrlPattern.js +183 -0
  108. package/dist/headlessPermissionModeWire.d.ts +18 -2
  109. package/dist/headlessPermissionModeWire.js +30 -19
  110. package/dist/hitl/allowRuleShadow.js +9 -7
  111. package/dist/hitl/approvalCardReading.d.ts +3 -0
  112. package/dist/hitl/approvalCardReading.js +17 -0
  113. package/dist/hitl/approvalCardReasons.js +2 -2
  114. package/dist/hitl/approvalCompleteParked.js +1 -1
  115. package/dist/hitl/approvalDelivery.d.ts +87 -0
  116. package/dist/hitl/approvalDelivery.js +193 -0
  117. package/dist/hitl/approvalHolds.d.ts +14 -0
  118. package/dist/hitl/approvalHolds.js +41 -0
  119. package/dist/hitl/approvalResolution.d.ts +11 -0
  120. package/dist/hitl/approvalResolution.js +50 -11
  121. package/dist/hitl/askClassPair.d.ts +8 -2
  122. package/dist/hitl/askClassPair.js +31 -4
  123. package/dist/hitl/askParkAutoReopenBlock.d.ts +30 -0
  124. package/dist/hitl/askParkAutoReopenBlock.js +117 -0
  125. package/dist/hitl/askParkRowRouting.js +4 -1
  126. package/dist/hitl/attributionLadder.d.ts +62 -0
  127. package/dist/hitl/attributionLadder.js +138 -0
  128. package/dist/hitl/automaticAnswerVerdict.d.ts +6 -1
  129. package/dist/hitl/automaticAnswerVerdict.js +46 -11
  130. package/dist/hitl/crashConverged.js +2 -2
  131. package/dist/hitl/decisionConflict.d.ts +6 -2
  132. package/dist/hitl/decisionConflict.js +24 -9
  133. package/dist/hitl/decisionLedger.d.ts +55 -0
  134. package/dist/hitl/decisionLedger.js +156 -0
  135. package/dist/hitl/decisionRefusal.d.ts +21 -10
  136. package/dist/hitl/decisionRefusal.js +100 -55
  137. package/dist/hitl/decisionSend.d.ts +116 -0
  138. package/dist/hitl/decisionSend.js +563 -0
  139. package/dist/hitl/frameRouter.d.ts +1 -0
  140. package/dist/hitl/frameRouter.js +9 -2
  141. package/dist/hitl/hitlBridge.d.ts +18 -6
  142. package/dist/hitl/hitlBridge.js +59 -43
  143. package/dist/hitl/livePendingAsk.js +4 -3
  144. package/dist/hitl/noAllowCause.js +1 -1
  145. package/dist/hitl/parkResolver.js +3 -2
  146. package/dist/hitl/persistedRulesWire.js +1 -0
  147. package/dist/hitl/planReviewWire.d.ts +4 -0
  148. package/dist/hitl/planReviewWire.js +104 -106
  149. package/dist/hitl/resumeRunningCard.d.ts +3 -2
  150. package/dist/hitl/resumeRunningCard.js +17 -11
  151. package/dist/hitl/sessionPolicyDeliverable.d.ts +5 -2
  152. package/dist/hitl/sessionPolicyDeliverable.js +65 -35
  153. package/dist/hitl/sessionPolicyWire.d.ts +13 -3
  154. package/dist/hitl/sessionPolicyWire.js +81 -16
  155. package/dist/hitl/standingRows.js +1 -1
  156. package/dist/hitl/toolApprovalWire.d.ts +9 -10
  157. package/dist/hitl/toolApprovalWire.js +103 -151
  158. package/dist/hookMatcherVerdict.d.ts +2 -0
  159. package/dist/hookMatcherVerdict.js +12 -0
  160. package/dist/hooksCompactTransition.d.ts +19 -0
  161. package/dist/hooksCompactTransition.js +41 -0
  162. package/dist/hooksWireCaps.d.ts +1 -1
  163. package/dist/hooksWireCaps.js +202 -203
  164. package/dist/host.d.ts +1 -14
  165. package/dist/host.js +0 -8
  166. package/dist/hostCallbackGuard.d.ts +1 -0
  167. package/dist/hostCallbackGuard.js +1 -1
  168. package/dist/hostSettingsSource.d.ts +172 -0
  169. package/dist/hostSettingsSource.js +675 -0
  170. package/dist/hostTurnSettings.d.ts +114 -19
  171. package/dist/hostTurnSettings.js +966 -68
  172. package/dist/httpHookPolicy.d.ts +37 -0
  173. package/dist/httpHookPolicy.js +176 -0
  174. package/dist/humanTurn.d.ts +4 -2
  175. package/dist/humanTurn.js +40 -10
  176. package/dist/humanTurnRead.js +4 -3
  177. package/dist/humanTurnSentences.d.ts +10 -0
  178. package/dist/humanTurnSentences.js +74 -0
  179. package/dist/i18n/messages.en.d.ts +313 -0
  180. package/dist/i18n/messages.en.js +326 -13
  181. package/dist/i18n/messages.zh.js +341 -13
  182. package/dist/i18n/translate.js +3 -3
  183. package/dist/index.d.ts +85 -15
  184. package/dist/index.js +53 -12
  185. package/dist/inheritEnvCapability.d.ts +4 -1
  186. package/dist/inheritEnvCapability.js +38 -17
  187. package/dist/inheritEnvWire.d.ts +2 -1
  188. package/dist/inheritEnvWire.js +11 -5
  189. package/dist/injectionLaneNotice.d.ts +5 -0
  190. package/dist/injectionLaneNotice.js +46 -0
  191. package/dist/interactiveToolsWire.d.ts +4 -2
  192. package/dist/interactiveToolsWire.js +5 -5
  193. package/dist/jsonFaithful.d.ts +20 -0
  194. package/dist/jsonFaithful.js +152 -0
  195. package/dist/limitsWire.d.ts +7 -2
  196. package/dist/limitsWire.js +19 -13
  197. package/dist/liveInitToolFace.d.ts +6 -1
  198. package/dist/liveInitToolFace.js +5 -3
  199. package/dist/liveModelCatalog.d.ts +22 -0
  200. package/dist/liveModelCatalog.js +132 -18
  201. package/dist/mcpPanel.js +3 -1
  202. package/dist/mcpProbeCapability.js +2 -2
  203. package/dist/mcpReconnect.js +2 -2
  204. package/dist/mcpStatusSupersetKeys.d.ts +24 -0
  205. package/dist/mcpStatusSupersetKeys.js +45 -0
  206. package/dist/mcpToolToggles.d.ts +6 -0
  207. package/dist/mcpToolToggles.js +47 -0
  208. package/dist/mcpWireCaps.d.ts +48 -4
  209. package/dist/mcpWireCaps.js +338 -99
  210. package/dist/mcpWireTransport.d.ts +4 -0
  211. package/dist/mcpWireTransport.js +18 -0
  212. package/dist/memoryComplianceCapability.js +2 -2
  213. package/dist/memoryOriginCapability.js +2 -2
  214. package/dist/model/catalogDefault.d.ts +24 -0
  215. package/dist/model/catalogDefault.js +4 -0
  216. package/dist/model/liveCatalogShape.js +5 -4
  217. package/dist/model/modelsPolicy.js +4 -3
  218. package/dist/model/onboardJudgement.d.ts +1 -0
  219. package/dist/model/onboardJudgement.js +1 -1
  220. package/dist/model/subagentModelWord.js +2 -2
  221. package/dist/modelCapabilityProbe.d.ts +2 -1
  222. package/dist/modelCapabilityProbe.js +16 -15
  223. package/dist/modelIdentityResolvability.d.ts +12 -1
  224. package/dist/modelIdentityResolvability.js +69 -28
  225. package/dist/modsKernelIdentity.d.ts +10 -0
  226. package/dist/modsKernelIdentity.js +103 -0
  227. package/dist/modsKernelTransit.d.ts +8 -0
  228. package/dist/modsKernelTransit.js +6 -0
  229. package/dist/notifications.d.ts +30 -12
  230. package/dist/notifications.js +241 -53
  231. package/dist/outputStyleSeatCapability.js +2 -2
  232. package/dist/ownKey.d.ts +37 -0
  233. package/dist/ownKey.js +238 -2
  234. package/dist/panelReduce.d.ts +5 -0
  235. package/dist/panelReduce.js +45 -13
  236. package/dist/panelStateHolder.d.ts +1 -0
  237. package/dist/panelStateHolder.js +10 -1
  238. package/dist/peerFrames.d.ts +1 -1
  239. package/dist/peerFrames.js +6 -2
  240. package/dist/peerLaneCapability.js +2 -2
  241. package/dist/permissionModesCapability.js +4 -4
  242. package/dist/permissionRuleIssue.d.ts +2 -1
  243. package/dist/permissionRuleIssue.js +24 -21
  244. package/dist/permissionRulesWriteCapability.js +2 -2
  245. package/dist/permissionsAllowGrantCapability.js +2 -2
  246. package/dist/permissionsDeclaration.d.ts +43 -4
  247. package/dist/permissionsDeclaration.js +102 -35
  248. package/dist/pluginHooksWire.d.ts +20 -4
  249. package/dist/pluginHooksWire.js +101 -60
  250. package/dist/prepareRefusal.d.ts +9 -0
  251. package/dist/prepareRefusal.js +90 -0
  252. package/dist/printInitToolFace.js +2 -2
  253. package/dist/printModelStatus.js +1 -1
  254. package/dist/projectMemory.d.ts +32 -0
  255. package/dist/projectMemory.js +70 -0
  256. package/dist/promptBlockedCopy.d.ts +2 -1
  257. package/dist/promptBlockedCopy.js +2 -1
  258. package/dist/promptDelivery.d.ts +23 -3
  259. package/dist/promptDelivery.js +169 -30
  260. package/dist/providerRejection.d.ts +19 -1
  261. package/dist/providerRejection.js +75 -4
  262. package/dist/queuedDelivery.d.ts +48 -0
  263. package/dist/queuedDelivery.js +233 -0
  264. package/dist/reattachWindow.d.ts +94 -0
  265. package/dist/reattachWindow.js +127 -0
  266. package/dist/request/printNotification.d.ts +1 -1
  267. package/dist/request/printNotification.js +5 -1
  268. package/dist/request/submissionIdentity.d.ts +37 -0
  269. package/dist/request/submissionIdentity.js +65 -0
  270. package/dist/request/taskRequest.d.ts +22 -14
  271. package/dist/request/taskRequest.js +312 -202
  272. package/dist/resultFrameKeys.d.ts +1 -0
  273. package/dist/resultFrameKeys.js +4 -1
  274. package/dist/resumeRefusalCopy.d.ts +3 -1
  275. package/dist/resumeRefusalCopy.js +22 -4
  276. package/dist/retryStatus.d.ts +26 -0
  277. package/dist/retryStatus.js +133 -28
  278. package/dist/rewindArchiveCapability.js +2 -2
  279. package/dist/rewindEngineAction.d.ts +2 -0
  280. package/dist/rewindEngineAction.js +23 -1
  281. package/dist/rowKind.d.ts +36 -0
  282. package/dist/rowKind.js +97 -0
  283. package/dist/ruleCompileVerdict.d.ts +18 -0
  284. package/dist/ruleCompileVerdict.js +67 -2
  285. package/dist/ruleReadings.d.ts +58 -0
  286. package/dist/ruleReadings.js +132 -0
  287. package/dist/ruleRefusalSentence.d.ts +8 -0
  288. package/dist/ruleRefusalSentence.js +64 -0
  289. package/dist/runCancelContext.d.ts +0 -1
  290. package/dist/runCancelContext.js +1 -2
  291. package/dist/runTerminal.d.ts +5 -0
  292. package/dist/runTerminal.js +52 -17
  293. package/dist/sandboxWire.d.ts +3 -2
  294. package/dist/sandboxWire.js +59 -27
  295. package/dist/scenarioRefusal.d.ts +2 -1
  296. package/dist/scenarioRefusal.js +6 -6
  297. package/dist/scenarioSkills.d.ts +20 -0
  298. package/dist/scenarioSkills.js +72 -0
  299. package/dist/scenarioWire.d.ts +5 -2
  300. package/dist/scenarioWire.js +9 -9
  301. package/dist/sealedKeyCapability.js +2 -2
  302. package/dist/seam.d.ts +26 -9
  303. package/dist/seam.js +44 -4
  304. package/dist/seatContract.d.ts +62 -9
  305. package/dist/seatContract.js +70 -25
  306. package/dist/selfOrchestrationDenial.js +1 -1
  307. package/dist/sessionPolicyCapability.js +2 -2
  308. package/dist/sessionRulesChildrenReadLive.d.ts +6 -0
  309. package/dist/sessionRulesChildrenReadLive.js +5 -0
  310. package/dist/sessionRulesNamespaceFormsCapability.d.ts +12 -0
  311. package/dist/sessionRulesNamespaceFormsCapability.js +29 -0
  312. package/dist/sessionSyncFileHistoryCapability.js +2 -2
  313. package/dist/settingsCredentialKeyPaths.d.ts +8 -0
  314. package/dist/settingsCredentialKeyPaths.js +274 -0
  315. package/dist/settingsHooksSalvage.d.ts +1 -0
  316. package/dist/settingsHooksSalvage.js +7 -1
  317. package/dist/settingsLayerAdmission.d.ts +4 -0
  318. package/dist/settingsLayerAdmission.js +16 -0
  319. package/dist/skillToolListsCapability.js +6 -5
  320. package/dist/skillsWireCaps.d.ts +14 -3
  321. package/dist/skillsWireCaps.js +48 -18
  322. package/dist/slashCommandGate.d.ts +24 -0
  323. package/dist/slashCommandGate.js +74 -0
  324. package/dist/slashCommandTable.d.ts +14 -0
  325. package/dist/slashCommandTable.js +99 -0
  326. package/dist/sqlEngineCapability.js +2 -2
  327. package/dist/steerPriorityCapability.js +2 -2
  328. package/dist/storePostureCapability.js +2 -2
  329. package/dist/subagent/agentStateDetail.js +1 -1
  330. package/dist/subagent/engineDelegatedPrompt.d.ts +9 -0
  331. package/dist/subagent/engineDelegatedPrompt.js +38 -7
  332. package/dist/subagent/engineRowStopGate.js +2 -2
  333. package/dist/subagent/engineSubagentResume.js +3 -3
  334. package/dist/subagent/engineTaskHandleWire.d.ts +1 -0
  335. package/dist/subagent/engineTaskHandleWire.js +10 -0
  336. package/dist/subagentContentStore.d.ts +1 -0
  337. package/dist/subagentContentStore.js +135 -27
  338. package/dist/submitFailure.d.ts +8 -0
  339. package/dist/submitFailure.js +17 -0
  340. package/dist/supportFloor.d.ts +1 -0
  341. package/dist/supportFloor.js +7 -0
  342. package/dist/terminationIntent.d.ts +55 -0
  343. package/dist/terminationIntent.js +352 -0
  344. package/dist/toolHistoryMismatch.d.ts +8 -0
  345. package/dist/toolHistoryMismatch.js +37 -6
  346. package/dist/toolResult.d.ts +13 -3
  347. package/dist/toolResult.js +158 -9
  348. package/dist/toolResultContent.d.ts +13 -0
  349. package/dist/toolResultContent.js +82 -7
  350. package/dist/toolRoster.d.ts +18 -0
  351. package/dist/toolRoster.js +64 -0
  352. package/dist/toolsFlagNames.d.ts +8 -0
  353. package/dist/toolsFlagNames.js +110 -0
  354. package/dist/turnFailurePresentation.js +41 -96
  355. package/dist/usageLimitAutoResume.d.ts +74 -0
  356. package/dist/usageLimitAutoResume.js +227 -0
  357. package/dist/userAttachmentEnvelope.js +1 -1
  358. package/dist/userAttachmentSeat.js +5 -5
  359. package/dist/userInvokedSkillsCapability.js +2 -2
  360. package/dist/webSearchBackendCapability.js +2 -2
  361. package/dist/wireErrorTriage.js +99 -50
  362. package/dist/wireFailureShape.d.ts +25 -1
  363. package/dist/wireFailureShape.js +92 -5
  364. package/dist/wireRefusalCopy.d.ts +75 -18
  365. package/dist/wireRefusalCopy.js +532 -148
  366. package/dist/wiringFleetDoctor.d.ts +3 -0
  367. package/dist/wiringFleetDoctor.js +21 -0
  368. package/dist/workflow.d.ts +2 -1
  369. package/dist/workflow.js +38 -1
  370. package/dist/workflowClient.d.ts +2 -7
  371. package/dist/workflowsJournalCapability.js +2 -2
  372. package/dist/writeProtectionCapability.js +2 -2
  373. package/docs/INTEGRATION-CLIENTS.md +1013 -190
  374. package/package.json +15 -4
@@ -3,10 +3,11 @@ import { askParkRowArm } from './askParkRowRouting.js';
3
3
  import { parkGateArmOf } from './frameRouter.js';
4
4
  import { seatSessionRowOf } from './standingRows.js';
5
5
  import { hostLog } from '../host.js';
6
- import { guardedRead, readAskOrigin, readOwnDataNonEmptyString, readOwnDataValue, readOwnNonEmptyString } from '../ownKey.js';
6
+ import { appendOwnElement, guardedRead, readAskOrigin, readOwnDataNonEmptyString, readOwnDataValue, readOwnNonEmptyString } from '../ownKey.js';
7
+ import { ownReadingSlot } from '../engineWireFor.js';
7
8
  import { DEPLOYMENT_LIST_ASK_CLASSES, readAskClassPair } from './askClassPair.js';
8
9
  import { invokeHostCallbackIsolated } from '../hostCallbackGuard.js';
9
- import { approvalWindowKeysOf, readRequiresRealApproval } from './approvalCardReading.js';
10
+ import { approvalWindowKeysOf, readApprovalCardWord, readRequiresRealApproval } from './approvalCardReading.js';
10
11
  import { readAllowRuleShadowFromWire, retiredAllowRuleShadowKeyPresent, RETIRED_SHADOW_EVIDENCE_LABEL } from './allowRuleShadow.js';
11
12
  import { createSessionSlot, DEFAULT_SESSION_KEY } from '../sessionSlot.js';
12
13
  import { readEngineActiveBgTasks } from '../fleet/fleetLedger.js';
@@ -17,17 +18,18 @@ import { INTERRUPT_DENY_REASON, observeCancelByDeny, surfaceApprovalParking, sur
17
18
  import { approvalCallKey, liveFrameCallKey } from './gateIdentity.js';
18
19
  import { displayUntrusted } from '../displayUntrusted.js';
19
20
  import { frameBindingOf } from '../frameBinding.js';
20
- import { approvalDecisionHolds, approvalHoldFor, awaitApprovalHolder, claimApprovalCardFor, holdLiveCard, joinLiveCard, liveCardHoldOf, clearSettledApprovals, noteHolderSettledApproval, settledApprovalOf, settledForDurableLane, settledLiveCardOutcome } from './approvalHolds.js';
21
- import { joinedResolution, resolutionOfDecisionFailure } from './approvalResolution.js';
21
+ import { carriesAttributionKey, deliverWithAttributionLadder } from './attributionLadder.js';
22
+ import { deliverApprovalDecision, newSendTally } from './approvalDelivery.js';
23
+ import { approvalDecisionHolds, approvalHoldFor, awaitApprovalHolder, claimApprovalCardFor, enterLiveRespondPhase, holdLiveCard, joinLiveCard, liveCardHoldOf, clearSettledApprovals, noteHolderSettledApproval, settledApprovalOf, settledForDurableLane, settledLiveCardOutcome } from './approvalHolds.js';
24
+ import { directFailureVerdictOf, directSafetyStopOf, joinedResolution, resolutionOfDecisionFailure } from './approvalResolution.js';
22
25
  import { parkRowDeadlineState } from './parkExpiryJudgements.js';
23
26
  import { isApprovalMandateWord } from '../gateVocabulary.js';
24
- import { denyAttributionRefusalFromError } from '../wireRefusalCopy.js';
25
27
  import { approvalDecidedByAdmitted } from '../approvalDecidedByCapability.js';
26
28
  import { decideFailureNote } from '../decideFailureNote.js';
27
- import { wireFailureTextsOf } from '../wireFailureShape.js';
29
+ import { slotPresenceOf, wireFailureTextsOf } from '../wireFailureShape.js';
28
30
  import { DECIDE_WORKFLOW_REMEMBER_UNSUPPORTED } from '../engineErrorCodes.js';
29
31
  import { readDecideReceipt } from '../decideReceipt.js';
30
- import { RULE_OFFER_MATCHES, RULE_OFFER_BATCH_MEMBER_KINDS, RULE_OFFER_UNCOVERED_REASONS, RULE_OFFERS_ABSENCE_REASONS, ASK_ORIGINS, TOOL_APPROVAL_CARD_WORDS, } from '@sema-agent/sdk';
32
+ import { RULE_OFFER_MATCHES, RULE_OFFER_BATCH_MEMBER_KINDS, RULE_OFFER_UNCOVERED_REASONS, RULE_OFFERS_ABSENCE_REASONS, ASK_ORIGINS, } from '@sema-agent/sdk';
31
33
  export function toolNameIsFsWrite(name) {
32
34
  const n = name.replace(/[\s_-]+/g, '').toLowerCase();
33
35
  return (n === 'write' || n === 'filewrite' || n === 'edit' || n === 'fileedit' || n === 'multiedit' || n === 'notebookedit');
@@ -78,7 +80,7 @@ export function readApprovalDenySettledBy(decision) {
78
80
  catch {
79
81
  return undefined;
80
82
  }
81
- if (d === undefined || !('value' in d))
83
+ if (d === undefined || !Object.hasOwn(d, 'value'))
82
84
  return undefined;
83
85
  const v = d.value;
84
86
  return typeof v === 'string' && APPROVAL_DENY_SETTLED_BY_WORDS.includes(v)
@@ -417,6 +419,7 @@ async function presentFsApprovalAndDecide(deps, taskId, argsByCall, signal, foun
417
419
  }
418
420
  return { kind: 'unsettled', ...at, cause: 'interrupted' };
419
421
  case 'allow':
422
+ let rememberStop;
420
423
  try {
421
424
  let rememberRefused = false;
422
425
  const approveBody = answerPayloadFor(card, 'decide');
@@ -434,6 +437,11 @@ async function presentFsApprovalAndDecide(deps, taskId, argsByCall, signal, foun
434
437
  catch (e) {
435
438
  if (rememberRefusalOf(e) === undefined)
436
439
  throw e;
440
+ const verdict = directFailureVerdictOf(e, directSafetyStopOf(e));
441
+ if (verdict.yields) {
442
+ rememberStop = ownReadingSlot(verdict, 'directStop');
443
+ throw e;
444
+ }
437
445
  rememberRefused = true;
438
446
  logAfterDecided(`liveToolApprovalWire: decide(approve+remember) refused the remember part (${String(e)}) — falling back to plain approve`);
439
447
  }
@@ -450,61 +458,45 @@ async function presentFsApprovalAndDecide(deps, taskId, argsByCall, signal, foun
450
458
  return { kind: 'decided', ...at, decision: 'allow', ...(receipt !== undefined ? { receipt } : {}) };
451
459
  }
452
460
  catch (e) {
461
+ const directStop = rememberStop !== undefined && rememberStop.thrown === e ? rememberStop : directSafetyStopOf(e);
453
462
  const failureTexts = wireFailureTextsOf(e);
454
463
  hostLog('debug', `liveToolApprovalWire: decide(approve) failed: ${failureTexts.log}`);
455
- return resolutionOfDecisionFailure(e, { lane: 'decide', route: 'approval_decide', gatedCallId, detail: `decide(approve) failed: ${failureTexts.reason}${decideFailureNote(e, 'approve')}` });
464
+ return resolutionOfDecisionFailure(e, { lane: 'decide', route: 'approval_decide', gatedCallId, detail: `decide(approve) failed: ${failureTexts.reason}${decideFailureNote(e, 'approve')}`, ...(directStop !== undefined ? { directStop } : {}) });
456
465
  }
457
466
  case 'deny': {
458
467
  const denySettledByForWire = readApprovalDenySettledBy(card);
459
468
  const attributionKeys = decisionAttributionKeyOf(decidedByReading, denySettledByForWire);
460
469
  const denyReasonSnapshot = ((r) => (typeof r === 'string' ? r : undefined))(card.reason);
461
470
  let lastSendCarriedAttribution = false;
471
+ let ladderSafetyStop;
462
472
  try {
463
473
  const denyPayload = { decision: 'deny', reason: answerPayloadFor({ kind: 'deny', ...(denyReasonSnapshot !== undefined ? { reason: denyReasonSnapshot } : {}) }, 'decide').reason };
464
474
  const denyBody = { ...denyPayload, ...attributionKeys };
465
- let attributionDropped = false;
466
- let attributionRenamed = false;
475
+ const ladder = { lastCarried: carriesAttributionKey(attributionKeys), dropped: false, renamed: false };
467
476
  let raw;
468
- lastSendCarriedAttribution = carriesAttributionKey(attributionKeys);
477
+ lastSendCarriedAttribution = ladder.lastCarried;
469
478
  emitAnswerCommitted(callKey, 'decide', card, denyPayload);
470
479
  try {
471
- raw = await bridge.decideTool(denyBody, gatedCallId, decideOpts, pending);
480
+ raw = await deliverWithAttributionLadder(denyBody, (b) => bridge.decideTool(b, gatedCallId, decideOpts, pending), signal, ladder, (step) => {
481
+ hostLog('debug', step === 'renamed'
482
+ ? `liveToolApprovalWire: decide(deny) for task ${taskId} was refused because the settlement note was sent under a name ` +
483
+ 'this engine has retired — re-sending the SAME decision exactly once with that one key renamed to the name the refusal points to ' +
484
+ '(the refusal happened before the approval was judged, so nothing was consumed and this is a re-delivery, not a second act)'
485
+ : step === 'dropped'
486
+ ? `liveToolApprovalWire: decide(deny) for task ${taskId} was refused because the settlement note is not part of ` +
487
+ 'what this deployment signs — re-sending the SAME decision exactly once with that one key removed ' +
488
+ '(the refusal happened before the approval was judged, so nothing was consumed and this is a re-delivery, not a second act)'
489
+ : `liveToolApprovalWire: decide(deny) for task ${taskId} was refused again because the settlement note is not part of ` +
490
+ 'what this deployment signs — re-sending the SAME decision exactly once more with that key removed ' +
491
+ '(still before the approval was judged)');
492
+ }, { kind: 'direct', stopOf: directSafetyStopOf });
472
493
  }
473
- catch (first) {
474
- if (shouldResendWithoutAttribution(first, lastSendCarriedAttribution, signal)) {
475
- const withoutAttribution = withoutAttributionKey(denyBody);
476
- lastSendCarriedAttribution = false;
477
- hostLog('debug', `liveToolApprovalWire: decide(deny) for task ${taskId} was refused because the settlement note is not part of ` +
478
- 'what this deployment signs — re-sending the SAME decision exactly once with that one key removed ' +
479
- '(the refusal happened before the approval was judged, so nothing was consumed and this is a re-delivery, not a second act)');
480
- raw = await bridge.decideTool(withoutAttribution, gatedCallId, decideOpts, pending);
481
- attributionDropped = true;
482
- }
483
- else if (shouldResendUnderSuccessorKey(first, Object.hasOwn(denyBody, 'settledBy'), signal)) {
484
- const renamed = withAttributionKeyRenamed(denyBody);
485
- hostLog('debug', `liveToolApprovalWire: decide(deny) for task ${taskId} was refused because the settlement note was sent under a name ` +
486
- 'this engine has retired — re-sending the SAME decision exactly once with that one key renamed to the name the refusal points to ' +
487
- '(the refusal happened before the approval was judged, so nothing was consumed and this is a re-delivery, not a second act)');
488
- try {
489
- raw = await bridge.decideTool(renamed, gatedCallId, decideOpts, pending);
490
- attributionRenamed = true;
491
- }
492
- catch (second) {
493
- if (!shouldResendWithoutAttribution(second, true, signal))
494
- throw second;
495
- const renamedWithoutAttribution = withoutAttributionKey(renamed);
496
- lastSendCarriedAttribution = false;
497
- hostLog('debug', `liveToolApprovalWire: decide(deny) for task ${taskId} was refused again because the settlement note is not part of ` +
498
- 'what this deployment signs — re-sending the SAME decision exactly once more with that key removed ' +
499
- '(still before the approval was judged)');
500
- raw = await bridge.decideTool(renamedWithoutAttribution, gatedCallId, decideOpts, pending);
501
- attributionDropped = true;
502
- }
503
- }
504
- else {
505
- throw first;
506
- }
494
+ finally {
495
+ lastSendCarriedAttribution = ladder.lastCarried;
496
+ ladderSafetyStop = ladder.safetyStop;
507
497
  }
498
+ const attributionDropped = ladder.dropped;
499
+ const attributionRenamed = ladder.renamed;
508
500
  const receipt = readDecideReceipt(raw);
509
501
  const deny = denyFactsOf(denySettledByForWire, denyReasonSnapshot, attributionDropped, attributionRenamed);
510
502
  return {
@@ -516,6 +508,7 @@ async function presentFsApprovalAndDecide(deps, taskId, argsByCall, signal, foun
516
508
  };
517
509
  }
518
510
  catch (e) {
511
+ const directStop = ladderSafetyStop !== undefined && ladderSafetyStop.thrown === e ? ladderSafetyStop : directSafetyStopOf(e);
519
512
  const failureTexts = wireFailureTextsOf(e);
520
513
  hostLog('debug', `liveToolApprovalWire: decide(deny) failed: ${failureTexts.log}`);
521
514
  return resolutionOfDecisionFailure(e, {
@@ -524,6 +517,7 @@ async function presentFsApprovalAndDecide(deps, taskId, argsByCall, signal, foun
524
517
  gatedCallId,
525
518
  detail: `decide(deny) failed: ${failureTexts.reason}${decideFailureNote(e, 'deny')}`,
526
519
  attributionCarried: lastSendCarriedAttribution,
520
+ ...(directStop !== undefined ? { directStop } : {}),
527
521
  });
528
522
  }
529
523
  }
@@ -607,20 +601,7 @@ export function readApprovalMandate(v) {
607
601
  const raw = v.mandate;
608
602
  return isApprovalMandateWord(raw) ? raw : undefined;
609
603
  }
610
- const APPROVAL_CARD_WORD_SET = new Set(TOOL_APPROVAL_CARD_WORDS);
611
- export function readApprovalCardWord(carrier) {
612
- try {
613
- if (typeof carrier !== 'object' || carrier === null)
614
- return undefined;
615
- const d = Object.getOwnPropertyDescriptor(carrier, 'approvalCard');
616
- if (d === undefined || !('value' in d))
617
- return undefined;
618
- return APPROVAL_CARD_WORD_SET.has(d.value) ? d.value : undefined;
619
- }
620
- catch {
621
- return undefined;
622
- }
623
- }
604
+ export { readApprovalCardWord };
624
605
  export function toolPermissionRequestAskBits(card, requestId) {
625
606
  if (typeof card !== 'object' || card === null)
626
607
  return {};
@@ -872,39 +853,11 @@ function readPersistedRuleAnchors(v) {
872
853
  function isNonNegativeSafeInt(v) {
873
854
  return typeof v === 'number' && Number.isSafeInteger(v) && v >= 0;
874
855
  }
875
- function shouldResendWithoutAttribution(e, sentAttributionKey, signal) {
876
- if (!sentAttributionKey)
877
- return false;
878
- if (signal?.aborted === true)
879
- return false;
880
- return denyAttributionRefusalFromError(e, true)?.kind === 'not_in_proof';
881
- }
882
- function shouldResendUnderSuccessorKey(e, lastSendCarriedRetiredKey, signal) {
883
- if (!lastSendCarriedRetiredKey)
884
- return false;
885
- if (signal?.aborted === true)
886
- return false;
887
- return denyAttributionRefusalFromError(e, true)?.kind === 'retired_key';
888
- }
889
856
  export function decisionAttributionKeyOf(reading, denySettledBy) {
890
857
  if (denySettledBy !== 'policy')
891
858
  return {};
892
859
  return approvalDecidedByAdmitted(reading) ? { decidedBy: 'policy' } : { settledBy: 'policy' };
893
860
  }
894
- function carriesAttributionKey(body) {
895
- return Object.hasOwn(body, 'settledBy') || Object.hasOwn(body, 'decidedBy');
896
- }
897
- function withoutAttributionKey(body) {
898
- const { settledBy: _droppedSettledBy, decidedBy: _droppedDecidedBy, ...rest } = body;
899
- void _droppedSettledBy;
900
- void _droppedDecidedBy;
901
- return rest;
902
- }
903
- function withAttributionKeyRenamed(body) {
904
- const { settledBy, decidedBy: _replaced, ...rest } = body;
905
- void _replaced;
906
- return settledBy === undefined ? rest : { ...rest, decidedBy: settledBy };
907
- }
908
861
  function readDecidedByReadingOf(holder) {
909
862
  try {
910
863
  return readOwnDataValue(holder, 'approvalDecidedBy');
@@ -986,7 +939,7 @@ function probeCauseSentence(cause, withProse, lang) {
986
939
  const key = withProse
987
940
  ? withCode ? 'approval.probe.withProseCode' : 'approval.probe.withProse'
988
941
  : withCode ? 'approval.probe.noProseCode' : 'approval.probe.noProse';
989
- return renderMessage(withCode ? msg(key, { code }) : msg(key), lang);
942
+ return renderMessage(withCode ? msg(key, { code: displayUntrusted(code) }) : msg(key), lang);
990
943
  }
991
944
  catch {
992
945
  return undefined;
@@ -1005,7 +958,7 @@ function ownDataValue(v, key) {
1005
958
  return undefined;
1006
959
  try {
1007
960
  const d = Object.getOwnPropertyDescriptor(v, key);
1008
- return d !== undefined && 'value' in d ? d.value : undefined;
961
+ return d !== undefined && Object.hasOwn(d, 'value') ? d.value : undefined;
1009
962
  }
1010
963
  catch {
1011
964
  return undefined;
@@ -1021,9 +974,9 @@ function ownStringList(v) {
1021
974
  const out = [];
1022
975
  for (let i = 0; i < length; i++) {
1023
976
  const d = Object.getOwnPropertyDescriptor(v, i);
1024
- if (d === undefined || !('value' in d) || typeof d.value !== 'string' || d.value === '')
977
+ if (d === undefined || !Object.hasOwn(d, 'value') || typeof d.value !== 'string' || d.value === '')
1025
978
  return undefined;
1026
- out.push(d.value);
979
+ appendOwnElement(out, d.value);
1027
980
  }
1028
981
  return v.length === length ? Object.freeze(out) : undefined;
1029
982
  }
@@ -1132,18 +1085,8 @@ const UNREADABLE_EVIDENCE_KEYS = Object.freeze({
1132
1085
  ]),
1133
1086
  generic: Object.freeze([['ruleOffersAbsence', 'ruleOffersAbsence'], ['askClass', 'askClass'], ['classes', 'classes']]),
1134
1087
  });
1135
- function carrierHas(carrier, key) {
1136
- if (typeof carrier !== 'object' || carrier === null)
1137
- return false;
1138
- try {
1139
- return key in carrier;
1140
- }
1141
- catch {
1142
- return true;
1143
- }
1144
- }
1145
1088
  function v1RiskUnreadable(card) {
1146
- if (!carrierHas(card, 'risk'))
1089
+ if (slotPresenceOf(card, 'risk') === 'absent')
1147
1090
  return false;
1148
1091
  try {
1149
1092
  const risk = card.risk;
@@ -1156,12 +1099,12 @@ function v1RiskUnreadable(card) {
1156
1099
  function withUnreadableEvidence(carrier, leg, req, reported = []) {
1157
1100
  const keys = new Set(reported);
1158
1101
  for (const [from, to] of UNREADABLE_EVIDENCE_KEYS[leg]) {
1159
- if (carrierHas(carrier, from) && !Object.hasOwn(req, to))
1102
+ if (slotPresenceOf(carrier, from) !== 'absent' && !Object.hasOwn(req, to))
1160
1103
  keys.add(from);
1161
1104
  }
1162
1105
  if (leg === 'row') {
1163
1106
  const rd = ownDataValue(carrier, 'riskDescriptor');
1164
- if (carrierHas(rd, 'allowRuleShadowed') && !Object.hasOwn(req, 'allowRuleShadow'))
1107
+ if (typeof rd === 'object' && rd !== null && slotPresenceOf(rd, 'allowRuleShadowed') !== 'absent' && !Object.hasOwn(req, 'allowRuleShadow'))
1165
1108
  keys.add('riskDescriptor.allowRuleShadowed');
1166
1109
  }
1167
1110
  if (leg !== 'generic' && !Object.hasOwn(req, 'allowRuleShadow')) {
@@ -1190,7 +1133,7 @@ export function classifierNoRulingDetail(word, lang) {
1190
1133
  return renderMessage(msg(CLASSIFIER_NO_RULING_REASONS[word]), lang);
1191
1134
  }
1192
1135
  if (typeof word === 'string' && CAUSE_WORD.test(word))
1193
- return renderMessage(msg('approval.classifier.noRulingOther', { reason: word }), lang);
1136
+ return renderMessage(msg('approval.classifier.noRulingOther', { reason: displayUntrusted(word) }), lang);
1194
1137
  return renderMessage(msg('approval.classifier.noRulingBare'), lang);
1195
1138
  }
1196
1139
  export function approvalBoundGrantsDetail(grants, lang) {
@@ -1863,7 +1806,7 @@ async function presentToolApprovalFrameAndRespond(frame, approvalId, respond, st
1863
1806
  return { kind: 'not_sent', lane: 'respond', cause: 'retracted' };
1864
1807
  }
1865
1808
  if (card.kind === 'aborted') {
1866
- hold.phase = 'respond';
1809
+ enterLiveRespondPhase(hold);
1867
1810
  const interruptOpts = lane?.approvalDecisionNoteCapable === true ? { note: INTERRUPT_DENY_REASON } : {};
1868
1811
  let interruptDeny;
1869
1812
  try {
@@ -1877,7 +1820,7 @@ async function presentToolApprovalFrameAndRespond(frame, approvalId, respond, st
1877
1820
  hostLog('debug', `liveToolApprovalWire: ${approvalId} card aborted — one tool-level deny issued to settle the pending ask`);
1878
1821
  return { kind: 'unsettled', lane: 'respond', cause: 'interrupted' };
1879
1822
  }
1880
- hold.phase = 'respond';
1823
+ enterLiveRespondPhase(hold);
1881
1824
  const noteCapable = lane?.approvalDecisionNoteCapable === true;
1882
1825
  const denyReasonRead = card.kind === 'deny' ? ((r) => (typeof r === 'string' ? r : undefined))(card.reason) : undefined;
1883
1826
  const answerSnapshot = card.kind === 'deny'
@@ -1892,6 +1835,7 @@ async function presentToolApprovalFrameAndRespond(frame, approvalId, respond, st
1892
1835
  const attributionKeys = decision === 'deny' ? decisionAttributionKeyOf(decidedByReading, denySettledByForWire) : {};
1893
1836
  const sentAttributionKey = carriesAttributionKey(attributionKeys);
1894
1837
  let lastSendCarriedAttribution = sentAttributionKey;
1838
+ let deliveryFailure;
1895
1839
  const denyReasonSnapshot = denyReasonRead;
1896
1840
  if (card.kind === 'failed') {
1897
1841
  hostLog('debug', `liveToolApprovalWire: approval card unavailable (${card.reason}) — fail-closed deny for ${approvalId}`);
@@ -1973,8 +1917,8 @@ async function presentToolApprovalFrameAndRespond(frame, approvalId, respond, st
1973
1917
  ruleArmDroppedForCheck = 'text_not_offered';
1974
1918
  }
1975
1919
  }
1920
+ const signalPreAborted = signal !== undefined && signal.aborted;
1976
1921
  const respondOpts = {
1977
- ...(signal && !signal.aborted ? { signal } : {}),
1978
1922
  ...(basePayload?.updatedInput !== undefined ? { updatedInput: basePayload.updatedInput } : {}),
1979
1923
  ...(persistRule !== undefined ? { persistRule } : {}),
1980
1924
  ...(persistRuleEdited !== undefined ? { persistRuleEdited } : {}),
@@ -1982,56 +1926,56 @@ async function presentToolApprovalFrameAndRespond(frame, approvalId, respond, st
1982
1926
  ...(note !== undefined ? { note } : {}),
1983
1927
  ...attributionKeys,
1984
1928
  };
1985
- let attributionDropped = false;
1986
- let attributionRenamed = false;
1929
+ const ladder = { lastCarried: lastSendCarriedAttribution, dropped: false, renamed: false };
1987
1930
  let raw;
1988
1931
  if (basePayload !== undefined)
1989
1932
  emitAnswerCommitted(liveFrameCallKey(approvalId), 'respond', answerSnapshot, basePayload);
1990
1933
  try {
1991
- raw = await respond(approvalId, decision, respondOpts);
1992
- }
1993
- catch (first) {
1994
- if (shouldResendWithoutAttribution(first, lastSendCarriedAttribution, signal)) {
1995
- const withoutAttribution = withoutAttributionKey(respondOpts);
1996
- lastSendCarriedAttribution = false;
1997
- hostLog('debug', `liveToolApprovalWire: respond(deny) for ${approvalId} was refused because the settlement note is not part of ` +
1998
- 'what this deployment signs — re-sending the SAME decision exactly once with that one key removed ' +
1999
- '(the refusal happened before the approval was judged, so nothing was consumed and this is a re-delivery, not a second act)');
2000
- raw = await respond(approvalId, decision, withoutAttribution);
2001
- attributionDropped = true;
2002
- }
2003
- else if (shouldResendUnderSuccessorKey(first, Object.hasOwn(respondOpts, 'settledBy'), signal)) {
2004
- const renamed = withAttributionKeyRenamed(respondOpts);
2005
- hostLog('debug', `liveToolApprovalWire: respond(deny) for ${approvalId} was refused because the settlement note was sent under a name ` +
2006
- 'this engine has retired — re-sending the SAME decision exactly once with that one key renamed to the name the refusal points to ' +
2007
- '(the refusal happened before the approval was judged, so nothing was consumed and this is a re-delivery, not a second act)');
2008
- try {
2009
- raw = await respond(approvalId, decision, renamed);
2010
- attributionRenamed = true;
2011
- }
2012
- catch (second) {
2013
- if (!shouldResendWithoutAttribution(second, true, signal))
2014
- throw second;
2015
- const renamedWithoutAttribution = withoutAttributionKey(renamed);
2016
- lastSendCarriedAttribution = false;
2017
- hostLog('debug', `liveToolApprovalWire: respond(deny) for ${approvalId} was refused again because the settlement note is not part of ` +
2018
- 'what this deployment signs — re-sending the SAME decision exactly once more with that key removed ' +
2019
- '(still before the approval was judged)');
2020
- raw = await respond(approvalId, decision, renamedWithoutAttribution);
2021
- attributionDropped = true;
2022
- }
2023
- }
2024
- else {
2025
- throw first;
1934
+ const delivery = await deliverApprovalDecision({
1935
+ approvalId,
1936
+ body: respondOpts,
1937
+ send: (o, sig) => respond(approvalId, decision, !signalPreAborted && sig !== undefined ? { ...o, signal: sig } : o),
1938
+ signal,
1939
+ tally: newSendTally(),
1940
+ ladder,
1941
+ onLadderStep: (step) => {
1942
+ hostLog('debug', step === 'renamed'
1943
+ ? `liveToolApprovalWire: respond(deny) for ${approvalId} was refused because the settlement note was sent under a name ` +
1944
+ 'this engine has retired — re-sending the SAME decision exactly once with that one key renamed to the name the refusal points to ' +
1945
+ '(the refusal happened before the approval was judged, so nothing was consumed and this is a re-delivery, not a second act)'
1946
+ : step === 'dropped'
1947
+ ? `liveToolApprovalWire: respond(deny) for ${approvalId} was refused because the settlement note is not part of ` +
1948
+ 'what this deployment signs — re-sending the SAME decision exactly once with that one key removed ' +
1949
+ '(the refusal happened before the approval was judged, so nothing was consumed and this is a re-delivery, not a second act)'
1950
+ : `liveToolApprovalWire: respond(deny) for ${approvalId} was refused again because the settlement note is not part of ` +
1951
+ 'what this deployment signs — re-sending the SAME decision exactly once more with that key removed ' +
1952
+ '(still before the approval was judged)');
1953
+ },
1954
+ parkingOf: (body) => {
1955
+ const p = readToolApprovalRespondParking(body);
1956
+ return p?.kind === 'parking' ? p.view : undefined;
1957
+ },
1958
+ });
1959
+ if (delivery.kind === 'thrown') {
1960
+ deliveryFailure = delivery;
1961
+ throw delivery.error;
2026
1962
  }
1963
+ raw = delivery.raw;
2027
1964
  }
1965
+ finally {
1966
+ lastSendCarriedAttribution = ladder.lastCarried;
1967
+ }
1968
+ const attributionDropped = ladder.dropped;
1969
+ const attributionRenamed = ladder.renamed;
2028
1970
  const parkingBody = readToolApprovalRespondParking(raw);
2029
1971
  if (parkingBody !== undefined) {
2030
1972
  const parking = parkingBody.kind === 'parking' && parkingBody.view.approvalId === approvalId ? parkingBody.view : undefined;
2031
1973
  if (parking !== undefined) {
2032
- hostLog('debug', `liveToolApprovalWire: respond(${decision}) for ${approvalId} answered 202 parking_in_progress${parking.retryAfterMs !== undefined ? ` (retryAfterMs=${parking.retryAfterMs})` : ''} — ` +
2033
- `the answer did NOT take effect${parking.decidePath !== undefined ? ' (the engine pointed at a decide path for the parked card)' : ''}; not re-sent, not reported as decided; the user is told to answer again on the parked card`);
2034
- surfaceApprovalParking(parking.retryAfterMs);
1974
+ const hint = ownReadingSlot(parking, 'retryAfterMs');
1975
+ const decidePath = ownReadingSlot(parking, 'decidePath');
1976
+ hostLog('debug', `liveToolApprovalWire: respond(${decision}) for ${approvalId} answered 202 parking_in_progress${hint !== undefined ? ` (retryAfterMs=${hint})` : ''} — ` +
1977
+ `the answer did NOT take effect${decidePath !== undefined ? ' (the engine pointed at a decide path for the parked card)' : ''}; not reported as decided (the one invited re-send, if any, has already been made); the user is told to answer again on the parked card`);
1978
+ surfaceApprovalParking(hint);
2035
1979
  return { kind: 'unsettled', lane: 'respond', cause: 'parking_in_progress', parking };
2036
1980
  }
2037
1981
  hostLog('error', `liveToolApprovalWire: 202 parking body for ${approvalId} is ${parkingBody.kind === 'parking' ? `for another approval (${parkingBody.view.approvalId})` : 'unreadable (approvalId is not usable)'} — ` +
@@ -2131,7 +2075,15 @@ async function presentToolApprovalFrameAndRespond(frame, approvalId, respond, st
2131
2075
  return { kind: 'decided', lane: 'respond', decision, ...(ack !== undefined ? { ack } : {}), ...(deny !== undefined ? { deny } : {}) };
2132
2076
  }
2133
2077
  catch (e) {
2134
- const r = resolutionOfDecisionFailure(e, { lane: 'respond', route: 'live_respond', attributionCarried: lastSendCarriedAttribution });
2078
+ const fromDelivery = deliveryFailure !== undefined && deliveryFailure.error === e ? deliveryFailure : undefined;
2079
+ const r = resolutionOfDecisionFailure(e, {
2080
+ lane: 'respond',
2081
+ route: 'live_respond',
2082
+ attributionCarried: lastSendCarriedAttribution,
2083
+ ...(fromDelivery?.transportExhausted === true ? { transportExhausted: true } : {}),
2084
+ ...(fromDelivery?.afterRetry === true ? { afterRetry: true } : {}),
2085
+ ...(fromDelivery !== undefined ? { delivered: fromDelivery.reading } : {}),
2086
+ });
2135
2087
  const refusal = r.kind === 'unsettled' ? r.refusal : undefined;
2136
2088
  hostLog('debug', `liveToolApprovalWire: respond(${decision}) failed for ${approvalId} ` +
2137
2089
  `(status=${refusal?.status ?? 'none'} errorCode=${logSafeErrorCode(refusal?.errorCode)} ` +
@@ -1,3 +1,4 @@
1
+ import type { UiLanguage } from './env/uiLanguage.js';
1
2
  export type HookMatcherUnjudgedReason = 'event_out_of_scope' | 'not_a_string' | 'oversize' | 'pattern_unsupported' | 'over_budget';
2
3
  export type HookMatcherRefusedReason = 'alias_without_canonical' | 'invalid_regex';
3
4
  export type HookMatcherVerdict = {
@@ -24,3 +25,4 @@ export type HookMatcherVerdict = {
24
25
  readonly reason: HookMatcherUnjudgedReason;
25
26
  };
26
27
  export declare function hookMatcherVerdict(event: string, matcher: unknown): HookMatcherVerdict;
28
+ export declare function hookMatcherUnjudgedWhy(reason: HookMatcherUnjudgedReason | string, lang?: UiLanguage): string;
@@ -1,3 +1,4 @@
1
+ import { msg, renderMessage } from './i18n/translate.js';
1
2
  import { HOOK_TOOL_ALIASES } from './hookToolAliases.js';
2
3
  import { SETTINGS_TOOL_NAME_MATCHER_EVENTS } from './generated/settingsSchemaTables.js';
3
4
  import { SETTINGS_HOOK_MATCHER_FORM, SETTINGS_HOOK_MATCHER_SELECTS } from './generated/settingsSchemaFns.js';
@@ -231,3 +232,14 @@ export function hookMatcherVerdict(event, matcher) {
231
232
  }
232
233
  return Object.freeze({ kind: 'accepted', reading, aliases: Object.freeze(selected.map((p) => Object.freeze({ ...p }))) });
233
234
  }
235
+ const UNJUDGED_WHY_KEY = {
236
+ event_out_of_scope: 'config.hooks.matcher.unjudged.eventOutOfScope',
237
+ not_a_string: 'config.hooks.matcher.unjudged.notAString',
238
+ oversize: 'config.hooks.matcher.unjudged.oversize',
239
+ pattern_unsupported: 'config.hooks.matcher.unjudged.patternUnsupported',
240
+ over_budget: 'config.hooks.matcher.unjudged.overBudget',
241
+ };
242
+ export function hookMatcherUnjudgedWhy(reason, lang) {
243
+ const key = typeof reason === 'string' && Object.hasOwn(UNJUDGED_WHY_KEY, reason) ? UNJUDGED_WHY_KEY[reason] : 'config.hooks.matcher.unjudged.unknown';
244
+ return renderMessage(msg(key), lang);
245
+ }
@@ -0,0 +1,19 @@
1
+ import type { UiLanguage } from './env/uiLanguage.js';
2
+ export declare const COMPACT_LATCH_STATES: readonly ["armed", "fired", "none"];
3
+ export type CompactLatchState = (typeof COMPACT_LATCH_STATES)[number];
4
+ export declare const COMPACT_SUMMARY_LEGS: readonly ["engine", "local_fallback", "local_fallback_unavailable", "none"];
5
+ export type CompactSummaryLeg = (typeof COMPACT_SUMMARY_LEGS)[number];
6
+ export type CompactHookExecutor = 'engine' | 'shell' | 'none';
7
+ export type CompactHookDisclosure = 'engine_outcome_unknown' | 'neither_ran';
8
+ export interface CompactHookTransitionInput {
9
+ readonly latch: CompactLatchState;
10
+ readonly leg: CompactSummaryLeg;
11
+ }
12
+ export interface CompactHookTransition {
13
+ readonly executor: CompactHookExecutor;
14
+ readonly revokeEngineRun: boolean;
15
+ readonly shellRunsHook: boolean;
16
+ readonly disclosure?: CompactHookDisclosure;
17
+ }
18
+ export declare function compactHookTransition(input: CompactHookTransitionInput): CompactHookTransition;
19
+ export declare function compactHookDisclosureSentence(disclosure: CompactHookDisclosure, lang?: UiLanguage): string;
@@ -0,0 +1,41 @@
1
+ import { msg, renderMessage } from './i18n/translate.js';
2
+ import { readOwnDataValue } from './ownKey.js';
3
+ export const COMPACT_LATCH_STATES = Object.freeze(['armed', 'fired', 'none']);
4
+ export const COMPACT_SUMMARY_LEGS = Object.freeze(['engine', 'local_fallback', 'local_fallback_unavailable', 'none']);
5
+ const frozen = (t) => Object.freeze({ ...t });
6
+ const KEEP = Object.freeze({ executor: 'engine', revokeEngineRun: false, shellRunsHook: false });
7
+ function inSet(set, v) {
8
+ return typeof v === 'string' && set.includes(v);
9
+ }
10
+ export function compactHookTransition(input) {
11
+ let latch;
12
+ let leg;
13
+ try {
14
+ latch = readOwnDataValue(input, 'latch');
15
+ leg = readOwnDataValue(input, 'leg');
16
+ }
17
+ catch {
18
+ return KEEP;
19
+ }
20
+ if (!inSet(COMPACT_LATCH_STATES, latch) || !inSet(COMPACT_SUMMARY_LEGS, leg))
21
+ return KEEP;
22
+ if (leg === 'none')
23
+ return latch === 'none' ? frozen({ executor: 'none', revokeEngineRun: false, shellRunsHook: false }) : KEEP;
24
+ if (leg === 'engine')
25
+ return KEEP;
26
+ if (latch === 'fired')
27
+ return frozen({ executor: 'engine', revokeEngineRun: false, shellRunsHook: false, disclosure: 'engine_outcome_unknown' });
28
+ if (leg === 'local_fallback') {
29
+ return latch === 'armed'
30
+ ? frozen({ executor: 'shell', revokeEngineRun: true, shellRunsHook: true })
31
+ : frozen({ executor: 'shell', revokeEngineRun: false, shellRunsHook: true });
32
+ }
33
+ return frozen({ executor: 'none', revokeEngineRun: false, shellRunsHook: false, disclosure: 'neither_ran' });
34
+ }
35
+ export function compactHookDisclosureSentence(disclosure, lang) {
36
+ if (disclosure === 'engine_outcome_unknown')
37
+ return renderMessage(msg('session.hooks.compactTransition.disclosure.engineOutcomeUnknown'), lang);
38
+ if (disclosure === 'neither_ran')
39
+ return renderMessage(msg('session.hooks.compactTransition.disclosure.neitherRan'), lang);
40
+ return '';
41
+ }
@@ -7,7 +7,7 @@ export interface HooksForWireOptions {
7
7
  readonly plan: HooksWirePlan;
8
8
  }
9
9
  export declare function hooksForWire(opts: HooksForWireOptions): WireHooksConfig | undefined;
10
- export declare function hooksWirePlan(opts?: HooksWirePlanOptions): HooksWirePlan;
10
+ export declare function hooksWirePlan(opts: HooksWirePlanOptions): HooksWirePlan;
11
11
  export declare function __resetHooksWireCapsForTests(): void;
12
12
  export declare function fleetHookFailureNoticeCapable(baseUrl: string | undefined): boolean;
13
13
  export declare const HOOK_FAILURE_WARN_PREFIX = "Hook error";