@sema-agent/client-core 0.97.1 → 0.99.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 (353) hide show
  1. package/CHANGELOG.md +607 -0
  2. package/README.md +96 -46
  3. package/dist/adapt/arms.d.ts +1 -0
  4. package/dist/adapt/arms.js +188 -53
  5. package/dist/adapt/ids.d.ts +12 -1
  6. package/dist/adapt/ids.js +59 -8
  7. package/dist/adapt/instanceLedger.d.ts +50 -0
  8. package/dist/adapt/instanceLedger.js +147 -0
  9. package/dist/adapt/panelTasks.d.ts +1 -1
  10. package/dist/adapt/panelTasks.js +2 -2
  11. package/dist/adapt/textStream.d.ts +1 -0
  12. package/dist/adapt/textStream.js +24 -7
  13. package/dist/adapt/toolCards.d.ts +27 -5
  14. package/dist/adapt/toolCards.js +39 -6
  15. package/dist/adapt/wireShapes.js +6 -2
  16. package/dist/adapt.d.ts +2 -0
  17. package/dist/adapt.js +8 -3
  18. package/dist/adapter/activeRunSelfHeal.d.ts +9 -3
  19. package/dist/adapter/activeRunSelfHeal.js +205 -313
  20. package/dist/adapter/downstream/eventToSdkMessage.d.ts +2 -5
  21. package/dist/adapter/downstream/eventToSdkMessage.js +77 -36
  22. package/dist/adapter/downstream/terminalToSdkResult.js +11 -4
  23. package/dist/adapter/downstream/turnUsageToModelUsage.d.ts +5 -2
  24. package/dist/adapter/downstream/turnUsageToModelUsage.js +2 -0
  25. package/dist/adapter/runStream.js +79 -48
  26. package/dist/adapter/types.d.ts +4 -4
  27. package/dist/adapter/types.js +2 -1
  28. package/dist/agentSession/backgroundView.js +2 -1
  29. package/dist/agentSession/engineAgentRegistryRead.d.ts +2 -2
  30. package/dist/agentSession/engineAgentRegistryRead.js +12 -13
  31. package/dist/agentSession/engineSessionBackgroundStop.js +16 -8
  32. package/dist/agentsWireCaps.d.ts +8 -11
  33. package/dist/agentsWireCaps.js +196 -194
  34. package/dist/approvalDecidedByCapability.d.ts +0 -4
  35. package/dist/approvalDecidedByCapability.js +0 -6
  36. package/dist/approvalsStreamLiveCapability.d.ts +0 -4
  37. package/dist/approvalsStreamLiveCapability.js +0 -6
  38. package/dist/assistantInbox.d.ts +34 -0
  39. package/dist/assistantInbox.js +118 -0
  40. package/dist/centerWiringCapability.js +9 -1
  41. package/dist/clientSlice.d.ts +0 -9
  42. package/dist/clientSlice.js +0 -3
  43. package/dist/cloudConfigWireCaps.d.ts +5 -3
  44. package/dist/cloudConfigWireCaps.js +106 -64
  45. package/dist/compensations.js +1 -1
  46. package/dist/connectorStatus.d.ts +21 -0
  47. package/dist/connectorStatus.js +112 -0
  48. package/dist/controlRouter.d.ts +18 -3
  49. package/dist/controlRouter.js +106 -67
  50. package/dist/coreValuePorts.d.ts +29 -4
  51. package/dist/coreValuePorts.js +10 -0
  52. package/dist/corruptSessionCopy.d.ts +2 -1
  53. package/dist/corruptSessionCopy.js +3 -3
  54. package/dist/decideReceipt.d.ts +2 -2
  55. package/dist/decideReceipt.js +5 -2
  56. package/dist/declared/supportFloorDeclared.js +3 -3
  57. package/dist/detachWire.js +3 -2
  58. package/dist/deviceExecutorManagementCapability.d.ts +0 -4
  59. package/dist/deviceExecutorManagementCapability.js +0 -6
  60. package/dist/deviceRebind.d.ts +49 -1
  61. package/dist/deviceRebind.js +221 -3
  62. package/dist/devicesFace.d.ts +34 -0
  63. package/dist/devicesFace.js +90 -0
  64. package/dist/displayUntrusted.d.ts +2 -0
  65. package/dist/displayUntrusted.js +253 -76
  66. package/dist/engineAgentAbsence.d.ts +1 -1
  67. package/dist/engineAgentPanelStore.d.ts +12 -4
  68. package/dist/engineAgentPanelStore.js +16 -11
  69. package/dist/engineCapReader.d.ts +2 -5
  70. package/dist/engineCapReader.js +8 -10
  71. package/dist/engineCapsCache.d.ts +12 -0
  72. package/dist/engineCapsCache.js +76 -18
  73. package/dist/engineCapsChange.d.ts +2 -0
  74. package/dist/engineCapsChange.js +9 -0
  75. package/dist/engineClosedSets.d.ts +1 -0
  76. package/dist/engineClosedSets.js +4 -1
  77. package/dist/engineErrorCodes.d.ts +11 -3
  78. package/dist/engineErrorCodes.js +11 -8
  79. package/dist/engineIdentity.d.ts +1 -0
  80. package/dist/engineIdentity.js +8 -0
  81. package/dist/engineRowRef.d.ts +28 -0
  82. package/dist/engineRowRef.js +114 -0
  83. package/dist/engineSessionMessages.d.ts +68 -0
  84. package/dist/engineSessionMessages.js +370 -0
  85. package/dist/engineTargetSeat.d.ts +27 -0
  86. package/dist/engineTargetSeat.js +199 -0
  87. package/dist/engineToolDirectory.d.ts +0 -9
  88. package/dist/engineToolDirectory.js +1 -94
  89. package/dist/engineUrl.d.ts +18 -0
  90. package/dist/engineUrl.js +52 -0
  91. package/dist/engineWireFor.js +3 -8
  92. package/dist/env/uiLanguage.d.ts +11 -1
  93. package/dist/env/uiLanguage.js +38 -2
  94. package/dist/eventLeg.d.ts +100 -0
  95. package/dist/eventLeg.js +305 -0
  96. package/dist/executionLaneCapability.d.ts +0 -4
  97. package/dist/executionLaneCapability.js +3 -16
  98. package/dist/fileHistoryCaptureCapability.d.ts +2 -5
  99. package/dist/fileHistoryCaptureCapability.js +13 -21
  100. package/dist/fileHistoryLegNotice.d.ts +2 -1
  101. package/dist/fileHistoryLegNotice.js +3 -3
  102. package/dist/fleet/fleetLedger.d.ts +0 -3
  103. package/dist/fleet/fleetLedger.js +21 -36
  104. package/dist/fleet/fleetProjection.d.ts +2 -2
  105. package/dist/fleet/fleetProjection.js +10 -8
  106. package/dist/frameBinding.d.ts +8 -0
  107. package/dist/frameBinding.js +35 -0
  108. package/dist/gateFailureCodes.d.ts +2 -0
  109. package/dist/gateFailureCodes.js +15 -0
  110. package/dist/gateOutcome.d.ts +3 -1
  111. package/dist/gateOutcome.js +41 -8
  112. package/dist/gateVocabulary.d.ts +10 -4
  113. package/dist/gateVocabulary.js +107 -47
  114. package/dist/generated/engineAskFaceTables.js +2 -2
  115. package/dist/generated/engineFactTables.d.ts +22 -3
  116. package/dist/generated/engineFactTables.js +51 -4
  117. package/dist/generated/engineNoticeTables.js +18 -3
  118. package/dist/generated/settingsSchemaFns.d.ts +6 -0
  119. package/dist/generated/settingsSchemaFns.js +57 -0
  120. package/dist/generated/settingsSchemaHooksClassifier.d.ts +2 -0
  121. package/dist/generated/settingsSchemaHooksClassifier.js +254 -0
  122. package/dist/generated/settingsSchemaTables.d.ts +1 -0
  123. package/dist/generated/settingsSchemaTables.js +4 -0
  124. package/dist/generated/settingsSchemaTypes.d.ts +105 -0
  125. package/dist/generated/settingsSchemaTypes.js +1 -0
  126. package/dist/generated/toolNameTables.d.ts +1 -0
  127. package/dist/generated/toolNameTables.js +1 -0
  128. package/dist/hitl/allowRuleShadow.d.ts +8 -2
  129. package/dist/hitl/allowRuleShadow.js +36 -29
  130. package/dist/hitl/approvalCardReading.d.ts +15 -0
  131. package/dist/hitl/approvalCardReading.js +154 -0
  132. package/dist/hitl/approvalCardReasons.d.ts +14 -0
  133. package/dist/hitl/approvalCardReasons.js +119 -0
  134. package/dist/hitl/approvalHolds.d.ts +50 -15
  135. package/dist/hitl/approvalHolds.js +177 -27
  136. package/dist/hitl/approvalResolution.d.ts +51 -26
  137. package/dist/hitl/approvalResolution.js +86 -122
  138. package/dist/hitl/approvalsFeed.js +6 -18
  139. package/dist/hitl/askClassPair.d.ts +2 -0
  140. package/dist/hitl/askClassPair.js +17 -0
  141. package/dist/hitl/askGateWire.d.ts +20 -2
  142. package/dist/hitl/askGateWire.js +50 -1
  143. package/dist/hitl/askParkRowRouting.d.ts +5 -0
  144. package/dist/hitl/askParkRowRouting.js +32 -1
  145. package/dist/hitl/askSettlementLine.d.ts +28 -0
  146. package/dist/hitl/askSettlementLine.js +99 -0
  147. package/dist/hitl/automaticAnswerVerdict.d.ts +3 -2
  148. package/dist/hitl/automaticAnswerVerdict.js +29 -13
  149. package/dist/hitl/crashConverged.d.ts +11 -20
  150. package/dist/hitl/crashConverged.js +56 -0
  151. package/dist/hitl/crashConvergedNotice.d.ts +6 -3
  152. package/dist/hitl/crashConvergedNotice.js +48 -24
  153. package/dist/hitl/decisionConflict.js +3 -10
  154. package/dist/hitl/decisionRefusal.d.ts +40 -1
  155. package/dist/hitl/decisionRefusal.js +199 -42
  156. package/dist/hitl/frameRouter.d.ts +5 -2
  157. package/dist/hitl/frameRouter.js +27 -24
  158. package/dist/hitl/gateLedger.d.ts +2 -0
  159. package/dist/hitl/gateLedger.js +50 -13
  160. package/dist/hitl/hitlBridge.d.ts +2 -2
  161. package/dist/hitl/hitlBridge.js +13 -10
  162. package/dist/hitl/livePendingAsk.d.ts +3 -3
  163. package/dist/hitl/livePendingAsk.js +7 -18
  164. package/dist/hitl/parkResolver.d.ts +2 -24
  165. package/dist/hitl/parkResolver.js +61 -97
  166. package/dist/hitl/persistedRulesWire.d.ts +25 -0
  167. package/dist/hitl/persistedRulesWire.js +104 -2
  168. package/dist/hitl/planReviewWire.d.ts +31 -13
  169. package/dist/hitl/planReviewWire.js +120 -78
  170. package/dist/hitl/refusedToolNameProse.d.ts +0 -1
  171. package/dist/hitl/refusedToolNameProse.js +0 -3
  172. package/dist/hitl/replayedApproval.d.ts +4 -3
  173. package/dist/hitl/replayedApproval.js +7 -4
  174. package/dist/hitl/sessionPolicyDeliverable.d.ts +2 -0
  175. package/dist/hitl/sessionPolicyDeliverable.js +48 -7
  176. package/dist/hitl/sessionPolicyWire.d.ts +34 -21
  177. package/dist/hitl/sessionPolicyWire.js +179 -70
  178. package/dist/hitl/standingRows.d.ts +20 -2
  179. package/dist/hitl/standingRows.js +69 -8
  180. package/dist/hitl/suspendedReopen.d.ts +2 -1
  181. package/dist/hitl/suspendedReopen.js +7 -10
  182. package/dist/hitl/toolApprovalWire.d.ts +103 -156
  183. package/dist/hitl/toolApprovalWire.js +661 -411
  184. package/dist/hookMatcherVerdict.d.ts +6 -1
  185. package/dist/hookMatcherVerdict.js +14 -7
  186. package/dist/hooksWireCaps.d.ts +2 -2
  187. package/dist/hooksWireCaps.js +174 -81
  188. package/dist/host.d.ts +21 -0
  189. package/dist/hostTurnSettings.d.ts +71 -0
  190. package/dist/hostTurnSettings.js +291 -0
  191. package/dist/humanTurn.d.ts +14 -1
  192. package/dist/humanTurn.js +100 -12
  193. package/dist/humanTurnRead.d.ts +2 -0
  194. package/dist/humanTurnRead.js +22 -1
  195. package/dist/i18n/messages.en.d.ts +703 -0
  196. package/dist/i18n/messages.en.js +701 -0
  197. package/dist/i18n/messages.zh.d.ts +3 -0
  198. package/dist/i18n/messages.zh.js +837 -0
  199. package/dist/i18n/translate.d.ts +25 -0
  200. package/dist/i18n/translate.js +127 -0
  201. package/dist/index.d.ts +78 -29
  202. package/dist/index.js +54 -18
  203. package/dist/inheritEnvCapability.d.ts +32 -0
  204. package/dist/inheritEnvCapability.js +104 -0
  205. package/dist/inheritEnvWire.d.ts +3 -2
  206. package/dist/inheritEnvWire.js +12 -14
  207. package/dist/interactiveHalt.js +17 -6
  208. package/dist/liveModelCatalog.d.ts +3 -3
  209. package/dist/liveModelCatalog.js +15 -13
  210. package/dist/liveQuestionStore.d.ts +2 -21
  211. package/dist/mcpLiveness.d.ts +2 -1
  212. package/dist/mcpPanel.d.ts +10 -1
  213. package/dist/mcpPanel.js +40 -13
  214. package/dist/mcpProbeCapability.d.ts +2 -1
  215. package/dist/mcpProbeCapability.js +7 -11
  216. package/dist/mcpProbeWire.d.ts +9 -2
  217. package/dist/mcpProbeWire.js +6 -1
  218. package/dist/mcpWireCaps.d.ts +47 -2
  219. package/dist/mcpWireCaps.js +164 -16
  220. package/dist/memoryEntriesWire.d.ts +4 -9
  221. package/dist/memoryEntriesWire.js +5 -10
  222. package/dist/model/modelSupplyRules.d.ts +0 -2
  223. package/dist/model/modelSupplyRules.js +3 -12
  224. package/dist/model/modelsPolicy.d.ts +0 -5
  225. package/dist/model/modelsPolicy.js +6 -36
  226. package/dist/model/onboardJudgement.d.ts +93 -0
  227. package/dist/model/onboardJudgement.js +415 -0
  228. package/dist/model/subagentModelWord.d.ts +31 -0
  229. package/dist/model/subagentModelWord.js +261 -0
  230. package/dist/model/tierVocabulary.d.ts +2 -0
  231. package/dist/model/tierVocabulary.js +17 -5
  232. package/dist/modelCapabilityProbe.d.ts +64 -0
  233. package/dist/modelCapabilityProbe.js +600 -0
  234. package/dist/modelIdentityResolvability.d.ts +3 -0
  235. package/dist/modelIdentityResolvability.js +26 -17
  236. package/dist/notifications.d.ts +6 -0
  237. package/dist/notifications.js +71 -23
  238. package/dist/outputStyleSeatCapability.d.ts +0 -3
  239. package/dist/outputStyleSeatCapability.js +0 -3
  240. package/dist/ownKey.d.ts +22 -0
  241. package/dist/ownKey.js +94 -3
  242. package/dist/panelReduce.d.ts +21 -10
  243. package/dist/panelReduce.js +728 -550
  244. package/dist/panelStateHolder.d.ts +3 -7
  245. package/dist/panelStateHolder.js +14 -130
  246. package/dist/peerLaneCapability.d.ts +0 -4
  247. package/dist/peerLaneCapability.js +0 -6
  248. package/dist/permissionRuleIssue.js +2 -0
  249. package/dist/permissionRulesWriteCapability.d.ts +2 -5
  250. package/dist/permissionRulesWriteCapability.js +8 -12
  251. package/dist/permissionWireCaps.d.ts +2 -2
  252. package/dist/permissionWireCaps.js +2 -0
  253. package/dist/permissionsAllowGrantCapability.d.ts +0 -4
  254. package/dist/permissionsAllowGrantCapability.js +0 -6
  255. package/dist/permissionsDeclaration.d.ts +0 -11
  256. package/dist/permissionsDeclaration.js +60 -53
  257. package/dist/pluginHooksWire.d.ts +46 -3
  258. package/dist/pluginHooksWire.js +219 -16
  259. package/dist/preemptWire.d.ts +44 -0
  260. package/dist/preemptWire.js +83 -0
  261. package/dist/printModelStatus.d.ts +63 -0
  262. package/dist/printModelStatus.js +155 -0
  263. package/dist/printToolResultFrame.js +15 -4
  264. package/dist/replayBody.d.ts +3 -0
  265. package/dist/replayBody.js +14 -0
  266. package/dist/request/taskRequest.d.ts +11 -6
  267. package/dist/request/taskRequest.js +112 -19
  268. package/dist/resumeRefusalCopy.d.ts +13 -9
  269. package/dist/resumeRefusalCopy.js +81 -118
  270. package/dist/retryStatus.d.ts +45 -0
  271. package/dist/retryStatus.js +185 -1
  272. package/dist/rewindArchiveCapability.d.ts +0 -4
  273. package/dist/rewindArchiveCapability.js +2 -10
  274. package/dist/rewindArchiveReading.d.ts +0 -1
  275. package/dist/rewindArchiveReading.js +0 -3
  276. package/dist/runCancelContext.d.ts +2 -1
  277. package/dist/runCancelContext.js +4 -2
  278. package/dist/runReattachPolicy.d.ts +31 -0
  279. package/dist/runReattachPolicy.js +46 -0
  280. package/dist/runTerminal.d.ts +3 -6
  281. package/dist/runTerminal.js +8 -9
  282. package/dist/sandboxWire.d.ts +3 -1
  283. package/dist/sandboxWire.js +76 -27
  284. package/dist/scenarioRefusal.d.ts +9 -0
  285. package/dist/scenarioRefusal.js +111 -0
  286. package/dist/scenarioWire.js +1 -1
  287. package/dist/seam.d.ts +48 -2
  288. package/dist/seam.js +25 -4
  289. package/dist/seatContract.d.ts +311 -18
  290. package/dist/seatContract.js +824 -100
  291. package/dist/selfOrchestrationDenial.js +7 -19
  292. package/dist/sessionIdSegment.d.ts +6 -0
  293. package/dist/sessionIdSegment.js +24 -0
  294. package/dist/sessionMemoryStatus.js +6 -11
  295. package/dist/sessionPolicyCapability.d.ts +2 -5
  296. package/dist/sessionPolicyCapability.js +8 -12
  297. package/dist/sessionSyncFileHistoryCapability.d.ts +0 -3
  298. package/dist/sessionSyncFileHistoryCapability.js +0 -3
  299. package/dist/settingsHooksSalvage.d.ts +44 -0
  300. package/dist/settingsHooksSalvage.js +211 -0
  301. package/dist/skillToolListsCapability.d.ts +2 -4
  302. package/dist/skillToolListsCapability.js +8 -9
  303. package/dist/sqlEngineCapability.d.ts +0 -4
  304. package/dist/sqlEngineCapability.js +0 -6
  305. package/dist/sseIdleTriage.js +3 -2
  306. package/dist/steerPriorityCapability.d.ts +0 -3
  307. package/dist/steerPriorityCapability.js +0 -3
  308. package/dist/streamDrainingLegs.d.ts +4 -0
  309. package/dist/streamDrainingLegs.js +6 -1
  310. package/dist/subagent/engineCompactWire.d.ts +0 -1
  311. package/dist/subagent/engineCompactWire.js +7 -5
  312. package/dist/subagent/engineSubagentResume.js +15 -9
  313. package/dist/subagent/engineTaskHandleWire.js +4 -7
  314. package/dist/subagentContentStore.d.ts +3 -0
  315. package/dist/subagentContentStore.js +22 -10
  316. package/dist/submitReopen.d.ts +24 -0
  317. package/dist/submitReopen.js +75 -0
  318. package/dist/terminalStatuses.d.ts +3 -0
  319. package/dist/terminalStatuses.js +10 -2
  320. package/dist/toolHistoryMismatch.js +3 -2
  321. package/dist/toolResult.d.ts +10 -1
  322. package/dist/toolResult.js +34 -6
  323. package/dist/toolRoster.d.ts +3 -4
  324. package/dist/toolRoster.js +21 -22
  325. package/dist/turnFailurePresentation.d.ts +39 -0
  326. package/dist/turnFailurePresentation.js +402 -0
  327. package/dist/usageAnalytics.js +6 -11
  328. package/dist/userAttachmentEnvelope.d.ts +1 -0
  329. package/dist/userAttachmentEnvelope.js +37 -7
  330. package/dist/userAttachmentSeat.d.ts +21 -0
  331. package/dist/userAttachmentSeat.js +75 -0
  332. package/dist/userInvokedSkillsCapability.d.ts +11 -4
  333. package/dist/userInvokedSkillsCapability.js +31 -10
  334. package/dist/webSearchBackendCapability.d.ts +0 -4
  335. package/dist/webSearchBackendCapability.js +0 -6
  336. package/dist/wireErrorTriage.d.ts +7 -0
  337. package/dist/wireErrorTriage.js +26 -23
  338. package/dist/wireFailureShape.d.ts +62 -5
  339. package/dist/wireFailureShape.js +106 -5
  340. package/dist/wireRefusalCopy.d.ts +25 -3
  341. package/dist/wireRefusalCopy.js +74 -80
  342. package/dist/workflowsJournalCapability.d.ts +2 -5
  343. package/dist/workflowsJournalCapability.js +8 -12
  344. package/dist/writeProtectionCapability.d.ts +0 -4
  345. package/dist/writeProtectionCapability.js +0 -6
  346. package/docs/INTEGRATION-CLIENTS.md +1775 -56
  347. package/package.json +6 -5
  348. package/dist/attachmentSeatCapability.d.ts +0 -12
  349. package/dist/attachmentSeatCapability.js +0 -23
  350. package/dist/hitl/approvalOutcomeNote.d.ts +0 -10
  351. package/dist/hitl/approvalOutcomeNote.js +0 -29
  352. package/dist/sessionReadRedactionCapability.d.ts +0 -13
  353. package/dist/sessionReadRedactionCapability.js +0 -35
@@ -1,39 +1,125 @@
1
- import { ASK_GONE, ASK_GONE_PARKED, isDecideAlreadyResolvedCode, isDecideParkMovedCode, refusalRetriableReading, refusalSaysStillPending } from '../engineErrorCodes.js';
2
- import { notPendingCauseReading } from './approvalEndingCause.js';
3
- import { GATE_FAILURE_CODES } from './hitlBridge.js';
1
+ import { ASK_GONE, ASK_GONE_PARKED, RESUME_PREFLIGHT_REJECTED, isDecideAlreadyResolvedCode, isDecideParkMovedCode, refusalRetriableReading, refusalSaysStillPending } from '../engineErrorCodes.js';
2
+ import { notPendingCauseReading, refusalCauseWordOf } from './approvalEndingCause.js';
3
+ import { GATE_FAILURE_CODES, readDecideCurrentPending, readWireCodes } from './hitlBridge.js';
4
4
  import { isAlreadyResolvedGateReason, isCodeClassifiedGateFailure } from './parkResolver.js';
5
5
  import { decisionConflictOf } from './decisionConflict.js';
6
6
  import { readLivePendingRows } from './livePendingAsk.js';
7
- import { ownDataField } from '../ownKey.js';
8
- import { readToolApprovalRespondRefusal } from './toolApprovalWire.js';
7
+ import { guardedRead, ownDataField, readOwnDataValue } from '../ownKey.js';
8
+ import { PROTOCOL_ERROR_NAME, isDisplayableWireCode, protocolErrorNameReading, readErrorRecord, readRefusalField } from '../wireFailureShape.js';
9
+ import { denyAttributionRefusalFromError } from '../wireRefusalCopy.js';
9
10
  const ASK_DECIDED_CODE = 'conflict.ask_decided';
10
11
  const TRANSIENT_STATUSES = new Set([408, 425, 429, 502, 503, 504]);
11
- const DISPLAYABLE_CODE = /^[A-Za-z0-9._:-]{1,64}$/;
12
+ export function refusalCarrierOf(err) {
13
+ if (typeof err !== 'object' || err === null)
14
+ return { carrier: err };
15
+ const name = guardedRead(() => readOwnDataValue(err, 'name'));
16
+ if (name !== 'HitlSafetyError')
17
+ return { carrier: err };
18
+ const code = guardedRead(() => readOwnDataValue(err, 'code'));
19
+ const local = typeof code === 'string' && GATE_FAILURE_CODES.includes(code) ? code : undefined;
20
+ const cause = guardedRead(() => readOwnDataValue(err, 'cause'));
21
+ const carrier = typeof cause === 'object' && cause !== null ? cause : err;
22
+ return local !== undefined ? { local, carrier } : { carrier };
23
+ }
24
+ const ROUTE_WORDS = { approval_decide: true, live_respond: true, ask_decide: true, plan_review: true, compact: true };
25
+ const REFUSAL_ROUTES = Object.freeze(Object.keys(ROUTE_WORDS));
26
+ const PRIOR_REFUSAL_EVIDENCE = Object.freeze([
27
+ Object.freeze({
28
+ errorCode: 'corrupt',
29
+ routes: Object.freeze(['plan_review', 'approval_decide', 'live_respond']),
30
+ evidence: 'server resume-legs.ts:1019 / :2752 / :2910 (resume context read, before the claim CAS at :1666 / :1457); plan_review resumePlanReview reads context before settling',
31
+ }),
32
+ ]);
33
+ function routeOf(context) {
34
+ const r = guardedRead(() => (typeof context === 'object' && context !== null ? readOwnDataValue(context, 'route') : undefined));
35
+ return typeof r === 'string' && REFUSAL_ROUTES.includes(r) ? r : undefined;
36
+ }
37
+ function carrierStatus(carrier) {
38
+ const raw = typeof carrier === 'object' && carrier !== null ? guardedRead(() => readOwnDataValue(carrier, 'status')) : undefined;
39
+ return typeof raw === 'number' && Number.isFinite(raw) ? raw : undefined;
40
+ }
41
+ function carrierCode(carrier) {
42
+ const raw = typeof carrier === 'object' && carrier !== null ? guardedRead(() => readOwnDataValue(carrier, 'errorCode')) : undefined;
43
+ return typeof raw === 'string' && raw.length > 0 ? raw : undefined;
44
+ }
45
+ export function refusalDeliveryOf(err, context) {
46
+ const { carrier } = refusalCarrierOf(err);
47
+ const status = carrierStatus(carrier);
48
+ const errorCode = carrierCode(carrier);
49
+ const facts = { ...(status !== undefined ? { status } : {}), ...(errorCode !== undefined ? { errorCode } : {}) };
50
+ if (status === undefined || !Number.isInteger(status) || status < 400 || status > 599)
51
+ return { delivery: 'no_answer', ...facts };
52
+ const route = routeOf(context);
53
+ if (route !== undefined && errorCode !== undefined && PRIOR_REFUSAL_EVIDENCE.some((p) => p.errorCode === errorCode && p.routes.includes(route))) {
54
+ return { delivery: 'refused', ...facts };
55
+ }
56
+ if (status < 500 || status === 501)
57
+ return { delivery: 'refused', ...facts };
58
+ return { delivery: 'ambiguous', ...facts };
59
+ }
12
60
  export function decisionRefusalSaysAskGone(err) {
13
61
  return readDecisionRefusalAsk(err).reading === 'settled';
14
62
  }
15
63
  const facts = (reading, gateMoved = false, wordingHint = false) => ({ reading, gateMoved, wordingHint });
16
- const PROTOCOL_ERROR_NAMES = Object.freeze({
17
- askDecided: 'AskDecidedError',
18
- approvalStale: 'ApprovalStaleError',
19
- parkedResumeStartup: 'ParkedResumeStartupError',
20
- });
64
+ function preflightSettledBitsPresent(carrier) {
65
+ const detail = guardedRead(() => readErrorRecord(carrier, 'detail'));
66
+ if (detail === undefined)
67
+ return false;
68
+ const bit = (k) => guardedRead(() => readOwnDataValue(detail, k));
69
+ const nonEmpty = (v) => typeof v === 'string' && v.length > 0;
70
+ return nonEmpty(bit('settledBy')) || nonEmpty(bit('rowStatus'));
71
+ }
72
+ const RESOLUTION_KINDS = Object.freeze(['decided', 'not_sent', 'unsettled']);
73
+ const ASK_READINGS = Object.freeze(['settled', 'not_settled', 'unreadable']);
74
+ function isResolutionShaped(v) {
75
+ if (typeof v !== 'object' || v === null)
76
+ return false;
77
+ const kind = guardedRead(() => readOwnDataValue(v, 'kind'));
78
+ return typeof kind === 'string' && RESOLUTION_KINDS.includes(kind);
79
+ }
80
+ function askFactsOfResolution(r) {
81
+ try {
82
+ const kind = ownDataField(r, 'kind');
83
+ if (kind === 'not_sent')
84
+ return facts(ownDataField(r, 'cause') === 'no_pending' ? 'settled' : 'not_settled');
85
+ if (kind !== 'unsettled')
86
+ return facts('not_settled');
87
+ const refusal = ownDataField(r, 'refusal');
88
+ if (typeof refusal !== 'object' || refusal === null)
89
+ return facts('not_settled');
90
+ const ask = ownDataField(refusal, 'ask');
91
+ if (typeof ask !== 'string' || !ASK_READINGS.includes(ask))
92
+ return facts('unreadable');
93
+ return facts(ask, ownDataField(refusal, 'gateMoved') === true, ownDataField(refusal, 'wordingHint') === true);
94
+ }
95
+ catch {
96
+ return facts('unreadable');
97
+ }
98
+ }
21
99
  export function readDecisionRefusalAsk(failure) {
22
100
  if (typeof failure !== 'object' || failure === null)
23
101
  return facts('not_settled');
24
- let flattened, localCode, name, errorCode, status, retriable, text;
102
+ if (isResolutionShaped(failure))
103
+ return askFactsOfResolution(failure);
104
+ const { local, carrier } = refusalCarrierOf(failure);
105
+ if (local !== undefined)
106
+ return facts(local === 'no_pending' ? 'settled' : 'not_settled');
107
+ if (typeof carrier !== 'object' || carrier === null)
108
+ return facts('not_settled');
109
+ let localCode, name, protocolName, errorCode, status, retriable, text;
25
110
  try {
26
- const slot = (key) => ownDataField(failure, key);
27
- if (slot('unreadable') === true)
28
- return facts('unreadable');
29
- flattened = slot('kind') === 'failed';
111
+ const slot = (key) => ownDataField(carrier, key);
30
112
  const closed = (v) => (typeof v === 'string' && GATE_FAILURE_CODES.includes(v) ? v : undefined);
31
- localCode = flattened ? (closed(slot('code')) ?? closed(slot('safetyCode'))) : closed(slot('code'));
32
- name = flattened ? undefined : slot('name');
113
+ localCode = closed(slot('code'));
114
+ name = slot('name');
115
+ const pn = protocolErrorNameReading(carrier);
116
+ if (pn.state === 'unreadable')
117
+ throw new TypeError('protocol name unreadable');
118
+ protocolName = pn.state === 'named' ? pn.name : undefined;
33
119
  errorCode = slot('errorCode');
34
120
  status = slot('status');
35
- retriable = refusalRetriableReading(failure);
36
- text = flattened ? slot('reason') : String(failure);
121
+ retriable = refusalRetriableReading(carrier);
122
+ text = String(carrier);
37
123
  }
38
124
  catch {
39
125
  return facts('unreadable');
@@ -45,46 +131,117 @@ export function readDecisionRefusalAsk(failure) {
45
131
  if (name === 'HitlSafetyError')
46
132
  return facts('not_settled');
47
133
  const code = typeof errorCode === 'string' && errorCode.length > 0 ? errorCode : undefined;
134
+ if (code === RESUME_PREFLIGHT_REJECTED && (preflightSettledBitsPresent(carrier) || retriable !== true))
135
+ return facts('not_settled', true);
48
136
  if (isCodeClassifiedGateFailure(code, retriable))
49
137
  return facts('not_settled');
50
138
  const st = typeof status === 'number' && Number.isInteger(status) && status >= 400 && status <= 599 ? status : undefined;
51
139
  if (code === ASK_DECIDED_CODE || code === ASK_GONE || (st === 410 && code !== ASK_GONE_PARKED))
52
140
  return facts('settled');
53
- if (st === 404 && notPendingCauseReading(failure) === 'ended')
141
+ if (st === 404 && notPendingCauseReading(carrier) === 'ended')
54
142
  return facts('settled');
55
- if (code === undefined && name === PROTOCOL_ERROR_NAMES.askDecided)
143
+ if (code === undefined && protocolName === PROTOCOL_ERROR_NAME.AskDecidedError)
56
144
  return facts('settled');
57
- const gateMoved = isDecideAlreadyResolvedCode(code) || isDecideParkMovedCode(code) || code === ASK_GONE_PARKED || (code === undefined && name === PROTOCOL_ERROR_NAMES.approvalStale);
58
- if (gateMoved || st !== undefined || name === PROTOCOL_ERROR_NAMES.parkedResumeStartup)
145
+ const gateMoved = isDecideAlreadyResolvedCode(code) || isDecideParkMovedCode(code) || code === ASK_GONE_PARKED || (code === undefined && protocolName === PROTOCOL_ERROR_NAME.ApprovalStaleError);
146
+ if (gateMoved || st !== undefined || protocolName === PROTOCOL_ERROR_NAME.ParkedResumeStartupError)
59
147
  return facts('not_settled', gateMoved);
60
148
  return facts('not_settled', false, isAlreadyResolvedGateReason(text));
61
149
  }
62
150
  export function decisionRefusalAskReading(failure) {
63
151
  return readDecisionRefusalAsk(failure).reading;
64
152
  }
65
- export function classifyDecisionRefusal(err) {
66
- const r = readToolApprovalRespondRefusal(err);
67
- const status = r?.status;
68
- if (status === undefined || !Number.isInteger(status) || status < 400 || status > 599)
153
+ const USELESS_REFUSAL_TEXTS = new Set(['[object Object]', 'null', 'undefined', '']);
154
+ function refusalTextOf(err) {
155
+ const message = typeof err === 'object' && err !== null ? guardedRead(() => err.message) : undefined;
156
+ if (typeof message === 'string' && message.length > 0)
157
+ return message;
158
+ if (typeof err === 'string' && err.length > 0)
159
+ return err;
160
+ let coerced;
161
+ try {
162
+ coerced = String(err);
163
+ }
164
+ catch {
69
165
  return undefined;
70
- const code = r?.errorCode;
71
- const errorCode = code !== undefined && DISPLAYABLE_CODE.test(code) ? code : undefined;
72
- const standing = readDecisionRefusalAsk(err).reading === 'settled'
73
- ? 'settled-elsewhere'
74
- : status >= 500 && status !== 501
75
- ? 'ambiguous'
76
- : 'refused-pending';
77
- const transient = TRANSIENT_STATUSES.has(status) ||
78
- (typeof err === 'object' && err !== null && (refusalSaysStillPending(err) || (status === 404 && notPendingCauseReading(err) === 'other_replica')));
79
- const conflict = status === 409 ? decisionConflictOf(err) : undefined;
166
+ }
167
+ return USELESS_REFUSAL_TEXTS.has(coerced) ? undefined : coerced;
168
+ }
169
+ function isolated(read) {
170
+ return guardedRead(read);
171
+ }
172
+ export function mintDecisionRefusalReading(err, context, attributionCarried) {
173
+ const { carrier } = refusalCarrierOf(err);
174
+ const obj = typeof carrier === 'object' && carrier !== null ? carrier : undefined;
175
+ const status = carrierStatus(carrier);
176
+ const wire = obj !== undefined ? isolated(() => readWireCodes(obj)) : undefined;
177
+ const errorCode = wire?.errorCode ?? carrierCode(carrier);
178
+ const message = isolated(() => refusalTextOf(carrier));
179
+ const retriable = obj !== undefined && isolated(() => refusalSaysStillPending(obj)) === true;
180
+ const pn = obj !== undefined ? isolated(() => protocolErrorNameReading(obj)) : undefined;
181
+ const protocolName = pn?.state === 'named' ? pn.name : undefined;
182
+ const cause = obj !== undefined ? isolated(() => refusalCauseWordOf(obj)) : undefined;
183
+ const field = obj !== undefined ? isolated(() => readRefusalField(obj)) : undefined;
184
+ const currentPending = obj !== undefined ? isolated(() => readDecideCurrentPending(obj)) : undefined;
185
+ const attribution = attributionCarried !== undefined ? isolated(() => denyAttributionRefusalFromError(carrier, attributionCarried)) : undefined;
186
+ const ask = readDecisionRefusalAsk(err);
187
+ const delivery = refusalDeliveryOf(err, context);
188
+ const standing = delivery.delivery === 'no_answer' ? undefined : ask.reading === 'settled' ? 'settled-elsewhere' : delivery.delivery === 'refused' ? 'refused-pending' : 'ambiguous';
189
+ const inRange = standing !== undefined && status !== undefined;
190
+ const transient = inRange &&
191
+ (TRANSIENT_STATUSES.has(status) || retriable || (status === 404 && obj !== undefined && isolated(() => notPendingCauseReading(obj)) === 'other_replica'));
192
+ const conflict = inRange && status === 409 && obj !== undefined ? isolated(() => decisionConflictOf(obj)) : undefined;
80
193
  return Object.freeze({
81
- standing,
82
- status,
194
+ ...(status !== undefined ? { status } : {}),
83
195
  ...(errorCode !== undefined ? { errorCode } : {}),
196
+ ...(message !== undefined ? { message } : {}),
197
+ ...(retriable ? { retriable: true } : {}),
198
+ ...(protocolName !== undefined ? { protocolName } : {}),
199
+ ...(cause !== undefined || field !== undefined ? { extra: Object.freeze({ ...(cause !== undefined ? { cause } : {}), ...(field !== undefined ? { field } : {}) }) } : {}),
200
+ ...(wire?.blockedBy !== undefined ? { blockedBy: wire.blockedBy } : {}),
201
+ ...(currentPending !== undefined ? { currentPending } : {}),
202
+ ...(attribution !== undefined && attribution !== null ? { denyAttributionRefusal: attribution } : {}),
203
+ ask: ask.reading,
204
+ ...(ask.gateMoved ? { gateMoved: true } : {}),
205
+ ...(ask.wordingHint ? { wordingHint: true } : {}),
206
+ ...(standing !== undefined ? { standing } : {}),
84
207
  ...(transient ? { transient: true } : {}),
85
208
  ...(conflict !== undefined ? { conflict } : {}),
86
209
  });
87
210
  }
211
+ export function readDecisionRefusalReading(err, context) {
212
+ return mintDecisionRefusalReading(err, context);
213
+ }
214
+ function classifiedOf(reading) {
215
+ if (typeof reading !== 'object' || reading === null)
216
+ return undefined;
217
+ try {
218
+ const standing = ownDataField(reading, 'standing');
219
+ const status = ownDataField(reading, 'status');
220
+ if ((standing !== 'settled-elsewhere' && standing !== 'ambiguous' && standing !== 'refused-pending') || typeof status !== 'number')
221
+ return undefined;
222
+ const code = ownDataField(reading, 'errorCode');
223
+ const errorCode = typeof code === 'string' && isDisplayableWireCode(code) ? code : undefined;
224
+ const transient = ownDataField(reading, 'transient') === true;
225
+ const conflict = ownDataField(reading, 'conflict');
226
+ return Object.freeze({
227
+ standing,
228
+ status,
229
+ ...(errorCode !== undefined ? { errorCode } : {}),
230
+ ...(transient ? { transient: true } : {}),
231
+ ...(typeof conflict === 'string' ? { conflict: conflict } : {}),
232
+ });
233
+ }
234
+ catch {
235
+ return undefined;
236
+ }
237
+ }
238
+ export function classifyDecisionRefusal(err, context) {
239
+ if (isResolutionShaped(err)) {
240
+ const refusal = guardedRead(() => (ownDataField(err, 'kind') === 'unsettled' ? ownDataField(err, 'refusal') : undefined));
241
+ return classifiedOf(refusal);
242
+ }
243
+ return classifiedOf(mintDecisionRefusalReading(err, context));
244
+ }
88
245
  export function liveAskPendingReading(envelope, approvalId) {
89
246
  if (typeof approvalId !== 'string' || approvalId === '')
90
247
  return 'unknown';
@@ -114,9 +271,9 @@ export function decisionRefusalClosesOut(refusal, pending) {
114
271
  }
115
272
  }
116
273
  export function undeliverableDecisionContent(facts) {
117
- const code = typeof facts.errorCode === 'string' && DISPLAYABLE_CODE.test(facts.errorCode) ? ` ${facts.errorCode}` : '';
274
+ const code = typeof facts.errorCode === 'string' && isDisplayableWireCode(facts.errorCode) ? ` ${facts.errorCode}` : '';
118
275
  const head = `The engine refused the approval decision this client sent (HTTP ${String(facts.status)}${code}), so the call it asked about could not be answered from here and did not run`;
119
- const runId = typeof facts.runId === 'string' && DISPLAYABLE_CODE.test(facts.runId) ? ` ${facts.runId}` : '';
276
+ const runId = typeof facts.runId === 'string' && isDisplayableWireCode(facts.runId) ? ` ${facts.runId}` : '';
120
277
  switch (facts.end) {
121
278
  case 'run-stopped':
122
279
  return `${head}; the run was stopped instead of being left waiting for the approval window to close. Update the client, or run the task in an interactive session and answer the approval there.`;
@@ -1,6 +1,7 @@
1
1
  import type { AgentEvent } from '@sema-agent/sdk';
2
2
  import type { DecideOperationObserver, HitlClientLike } from './hitlBridge.js';
3
- import { type RespondToolApprovalFn, type ToolApprovalFrame, type ToolApprovalFrameLaneOpts, type ToolApprovalFrameOutcome } from './toolApprovalWire.js';
3
+ import { type RespondToolApprovalFn, type ToolApprovalFrame, type ToolApprovalFrameLaneOpts } from './toolApprovalWire.js';
4
+ import type { ApprovalResolution } from './approvalResolution.js';
4
5
  import type { GateLedger } from './gateLedger.js';
5
6
  import type { NoAllowCause } from './noAllowCause.js';
6
7
  import { type ReplayedApprovalDisposition } from './replayedApproval.js';
@@ -31,13 +32,14 @@ export interface AskGateWireDeps {
31
32
  respondToolApproval?: RespondToolApprovalFn;
32
33
  onParkReattach?: (e: ParkReattachNotice) => void;
33
34
  approvalLane?: ToolApprovalFrameLaneOpts;
34
- onToolApprovalOutcome?: (frame: ToolApprovalFrame, outcome: ToolApprovalFrameOutcome) => void | Promise<void>;
35
+ onToolApprovalOutcome?: (frame: ToolApprovalFrame, resolution: ApprovalResolution) => void | Promise<void>;
35
36
  onDecideOperation?: DecideOperationObserver;
36
37
  onReplayedApproval?: (frame: ToolApprovalFrame, disposition: ReplayedApprovalDisposition) => void | Promise<void>;
37
38
  }
38
39
  type GateKind = 'ask' | 'fs';
39
40
  export interface GatePark {
40
41
  gate: GateKind;
42
+ parkFrame: AgentEvent;
41
43
  pendingDone?: AgentEvent | undefined;
42
44
  gatedCallId?: string | undefined;
43
45
  toolName?: string | undefined;
@@ -50,6 +52,7 @@ export type FrameAction = {
50
52
  } | {
51
53
  kind: 'park';
52
54
  gate: GateKind;
55
+ parkFrame: AgentEvent;
53
56
  pendingDone?: AgentEvent | undefined;
54
57
  gatedCallId?: string | undefined;
55
58
  toolName?: string | undefined;
@@ -5,12 +5,14 @@ import { classifierDenyFromToolEnd } from '../classifierVerdictWire.js';
5
5
  import { toolEndOutputText } from '../toolResultContent.js';
6
6
  import { GATE_PARKED_ERROR_CODE } from '../engineErrorCodes.js';
7
7
  import { readRunTerminal, runTerminalCode, runTerminalGateKind, runTerminalGateToolName } from '../runTerminal.js';
8
+ import { parkHeldCallIdOf } from '../engineRowRef.js';
9
+ import { inheritFrameBinding } from '../frameBinding.js';
8
10
  import { surfaceForCurrentSession, surfaceReplayedApprovalListUnreadable } from './hitlHostSurface.js';
9
- import { liveCardHoldOf, noteEngineClosedApproval, supersedeLiveCard } from './approvalHolds.js';
11
+ import { liveCardHoldOf, noteEngineClosedApproval, settleEngineClosedApproval } from './approvalHolds.js';
10
12
  import { approvalCompleteParked } from './approvalCompleteParked.js';
11
13
  import { liveFrameCallKey } from './gateIdentity.js';
12
14
  import { SEMA_DENIAL_KIND_KEY, hasLedgerPositionKey } from './gateLedger.js';
13
- import { replayedApprovalDisposition, settledApprovalDisposition } from './replayedApproval.js';
15
+ import { replayedApprovalClosesCardFrame, replayedApprovalDisposition, settledApprovalDisposition } from './replayedApproval.js';
14
16
  import { settleWithinDeadline } from '../abortableSleep.js';
15
17
  import { ccToolDenialKindForSettledBy } from '../gateVocabulary.js';
16
18
  import { REJECT_MESSAGE } from '../adapt/wireShapes.js';
@@ -69,12 +71,12 @@ function denialKindForTranscript(attribution) {
69
71
  }
70
72
  function denyStampedEnd(ev, attribution) {
71
73
  const kind = denialKindForTranscript(attribution);
72
- return {
74
+ return inheritFrameBinding(ev, {
73
75
  ...ev,
74
76
  output: denyOutputForRender(attribution),
75
77
  structured: undefined,
76
78
  ...(kind !== undefined ? { [SEMA_DENIAL_KIND_KEY]: kind } : {}),
77
- };
79
+ });
78
80
  }
79
81
  export const HITL_INTERRUPT_MESSAGE_FOR_TOOL_USE = '[Request interrupted by user for tool use]';
80
82
  const RUN_CANCELLED_ERROR_CODE = RUN_CANCELLED_CODE;
@@ -149,8 +151,7 @@ function parkGateOf(result) {
149
151
  return arm === null ? null : { taskId, gate: arm, toolName };
150
152
  }
151
153
  function parkGatedCallId(src) {
152
- const v = src?.toolCallId;
153
- return typeof v === 'string' && v.length > 0 ? v : undefined;
154
+ return parkHeldCallIdOf(src);
154
155
  }
155
156
  function argsOfGatedStart(led, callId) {
156
157
  if (callId === undefined)
@@ -192,7 +193,9 @@ export function* flushHeldWithInterruptRewrite(led, evidence) {
192
193
  yield ev;
193
194
  continue;
194
195
  }
195
- yield { ...ev, output: HITL_INTERRUPT_MESSAGE_FOR_TOOL_USE };
196
+ yield inheritFrameBinding(ev, (gateAborted
197
+ ? { ...ev, output: HITL_INTERRUPT_MESSAGE_FOR_TOOL_USE, [SEMA_DENIAL_KIND_KEY]: 'interrupted' }
198
+ : { ...ev, output: HITL_INTERRUPT_MESSAGE_FOR_TOOL_USE }));
196
199
  }
197
200
  }
198
201
  const TOOL_END_ARM_ORDER = [
@@ -216,7 +219,7 @@ const TOOL_END_ARMS = [
216
219
  const startArgs = led.startArgs().get(callId);
217
220
  surfaceForCurrentSession()?.surfaceClassifierDeny(typeof ev.toolName === 'string' ? ev.toolName : 'tool', verdict, { toolCallId: callId, ...(startArgs !== undefined ? { args: startArgs } : {}) });
218
221
  hostLog('debug', `liveHitlAskWire: classifier deny verdict on ${callId} (${String(ev.toolName)}) — labeled render + notice`);
219
- return { kind: 'yield', events: [{ ...ev, output: verdict.message, structured: undefined }] };
222
+ return { kind: 'yield', events: [inheritFrameBinding(ev, { ...ev, output: verdict.message, structured: undefined })] };
220
223
  },
221
224
  },
222
225
  {
@@ -264,7 +267,7 @@ const TOOL_END_ARMS = [
264
267
  const answered = led.answerFor(callId);
265
268
  if (answered && ev.isError !== true && ev.structured === undefined) {
266
269
  led.dropAnswer(callId);
267
- return { kind: 'yield', events: [{ ...ev, structured: answered }] };
270
+ return { kind: 'yield', events: [inheritFrameBinding(ev, { ...ev, structured: answered })] };
268
271
  }
269
272
  return { kind: 'yield', events: [ev] };
270
273
  },
@@ -282,12 +285,9 @@ const TOOL_END_ARMS = [
282
285
  async function routeToolApprovalFrame(ev, ctx) {
283
286
  const { led, deps } = ctx;
284
287
  if (ev.type === 'tool_approval_complete') {
285
- const id = ev.approvalId;
286
- const parked = approvalCompleteParked(ev);
287
- if (typeof id === 'string' && id !== '')
288
- noteEngineClosedApproval(id, parked);
289
- if (typeof id === 'string' && id !== '' && supersedeLiveCard(liveFrameCallKey(id), parked)) {
290
- hostLog('debug', `liveHitlAskWire: tool_approval_complete for ${id} arrived while its card was waiting — card withdrawn (nothing will be sent from it)`);
288
+ if (settleEngineClosedApproval(ev, approvalCompleteParked(ev))) {
289
+ const id = ev.approvalId;
290
+ hostLog('debug', `liveHitlAskWire: tool_approval_complete for ${String(id)} arrived while its card was waiting — card withdrawn (nothing will be sent from it)`);
291
291
  }
292
292
  return { kind: 'skip' };
293
293
  }
@@ -304,6 +304,8 @@ async function routeToolApprovalFrame(ev, ctx) {
304
304
  : `liveHitlAskWire: tool_approval frame ${ev.approvalId} read back from the run event log is ${disposition.kind}` +
305
305
  `${disposition.kind === 'unknown' ? ` (${disposition.why})` : disposition.cause !== undefined ? ` (${disposition.cause})` : ''}` +
306
306
  ' — not raised as a question, no decision sent');
307
+ if (settledHere === undefined && replayedApprovalClosesCardFrame(disposition))
308
+ noteEngineClosedApproval(ev.approvalId, false);
307
309
  if (disposition.kind === 'unknown' && ctx.signal?.aborted !== true)
308
310
  surfaceReplayedApprovalListUnreadable();
309
311
  if (deps.onReplayedApproval !== undefined) {
@@ -328,14 +330,13 @@ async function routeToolApprovalFrame(ev, ctx) {
328
330
  }
329
331
  function settleLiveCardOutcome(ev, outcome, ctx, fromSubagent, gatedCallId) {
330
332
  const { led, deps } = ctx;
331
- const { decision } = outcome;
332
333
  if (deps.onToolApprovalOutcome !== undefined) {
333
334
  invokeHostCallbackIsolated('liveHitlAskWire: onToolApprovalOutcome', () => deps.onToolApprovalOutcome?.(ev, outcome));
334
335
  }
335
- if (decision === 'deny' && !fromSubagent) {
336
+ if (outcome.kind === 'decided' && outcome.decision === 'deny' && !fromSubagent) {
336
337
  const attribution = {
337
- ...(outcome.denySettledBy !== undefined ? { settledBy: outcome.denySettledBy } : {}),
338
- ...(outcome.denyReason !== undefined ? { reason: outcome.denyReason } : {}),
338
+ ...(outcome.deny?.settledBy !== undefined ? { settledBy: outcome.deny.settledBy } : {}),
339
+ ...(outcome.deny?.reason !== undefined ? { reason: outcome.deny.reason } : {}),
339
340
  };
340
341
  if (gatedCallId !== undefined)
341
342
  led.markDenied(gatedCallId, attribution);
@@ -400,15 +401,16 @@ function routeSuspended(ev, ctx) {
400
401
  const gatedCallId = parkGatedCallId(ev);
401
402
  const arm = parkGateArmOf(ev.gate);
402
403
  if (arm === 'ask' && ctx.taskId.current) {
403
- ctx.led.noteParkGate({ fsOrShellFamily: false });
404
- return { kind: 'park', gate: 'ask', ...(gatedCallId !== undefined ? { gatedCallId } : {}) };
404
+ ctx.led.noteParkGate({ fsOrShellFamily: false, gatedCallId });
405
+ return { kind: 'park', gate: 'ask', parkFrame: ev, ...(gatedCallId !== undefined ? { gatedCallId } : {}) };
405
406
  }
406
407
  if (arm === 'fs' && ctx.taskId.current) {
407
408
  const gateToolName = ev.gate?.toolName;
408
- ctx.led.noteParkGate({ fsOrShellFamily: parkFamilyEvidence(ctx.led, gateToolName, gatedCallId) });
409
+ ctx.led.noteParkGate({ fsOrShellFamily: parkFamilyEvidence(ctx.led, gateToolName, gatedCallId), gatedCallId });
409
410
  return {
410
411
  kind: 'park',
411
412
  gate: 'fs',
413
+ parkFrame: ev,
412
414
  ...(gatedCallId !== undefined ? { gatedCallId } : {}),
413
415
  ...(typeof gateToolName === 'string' && gateToolName !== '' ? { toolName: gateToolName } : {}),
414
416
  };
@@ -421,10 +423,11 @@ function routeDone(ev, ctx) {
421
423
  const park = parkGateOf(ev.result);
422
424
  if (park !== null) {
423
425
  ctx.taskId.current = ctx.taskId.current ?? park.taskId;
424
- led.noteParkGate({ fsOrShellFamily: park.gate === 'fs' && parkFamilyEvidence(led, park.toolName, gatedCallId) });
426
+ led.noteParkGate({ fsOrShellFamily: park.gate === 'fs' && parkFamilyEvidence(led, park.toolName, gatedCallId), gatedCallId });
425
427
  return {
426
428
  kind: 'park',
427
429
  gate: park.gate,
430
+ parkFrame: ev,
428
431
  pendingDone: ev,
429
432
  ...(gatedCallId !== undefined ? { gatedCallId } : {}),
430
433
  ...(park.toolName !== undefined && park.toolName !== '' ? { toolName: park.toolName } : {}),
@@ -434,7 +437,7 @@ function routeDone(ev, ctx) {
434
437
  const r = ev.result;
435
438
  const realTaskId = ctx.taskId.current;
436
439
  if (realTaskId && r && r.taskId === r.sessionId && r.taskId !== realTaskId) {
437
- events.push({ ...ev, result: { ...ev.result, taskId: realTaskId } });
440
+ events.push(inheritFrameBinding(ev, { ...ev, result: { ...ev.result, taskId: realTaskId } }));
438
441
  }
439
442
  else {
440
443
  events.push(ev);
@@ -14,6 +14,7 @@ export interface AskAnsweredOutput {
14
14
  }>;
15
15
  }
16
16
  export declare function durableSeqOf(ev: object): string | undefined;
17
+ export declare const BODY_SEQ_OTHER_AXIS_EVENTS: readonly string[];
17
18
  export declare function hasLedgerPositionKey(ev: object): boolean;
18
19
  export declare const PREAMBLE_APPROVALS_MAX_ENTRIES = 4096;
19
20
  export interface GateLedger {
@@ -52,6 +53,7 @@ export interface GateLedger {
52
53
  isFsOrShellGatedCall(callId: string): boolean;
53
54
  noteParkGate(evidence: {
54
55
  fsOrShellFamily: boolean;
56
+ gatedCallId?: string | undefined;
55
57
  }): void;
56
58
  hasBatchPark(): boolean;
57
59
  rememberAnswer(callId: string, answered: AskAnsweredOutput): void;
@@ -1,13 +1,21 @@
1
+ import { parkedToolEndRoleOf } from '../engineRowRef.js';
2
+ import { inheritFrameBinding } from '../frameBinding.js';
1
3
  export const SEMA_COLLATERAL_ABORT_KEY = '_sema_collateral_abort';
2
4
  export const SEMA_DENIAL_KIND_KEY = '_sema_denial_kind';
3
5
  export function durableSeqOf(ev) {
4
- const rawSeq = ev.id ?? ev.seq;
6
+ const rec = ev;
7
+ const id = rec.id;
8
+ const rawSeq = id ?? (seqIsAnotherAxis(rec.type) ? undefined : rec.seq);
5
9
  if (typeof rawSeq === 'string' && rawSeq.length > 0)
6
10
  return rawSeq;
7
11
  if (typeof rawSeq === 'number' && Number.isFinite(rawSeq))
8
12
  return String(rawSeq);
9
13
  return undefined;
10
14
  }
15
+ export const BODY_SEQ_OTHER_AXIS_EVENTS = Object.freeze(['task_progress', 'task_notification', 'task_started']);
16
+ function seqIsAnotherAxis(type) {
17
+ return typeof type === 'string' && BODY_SEQ_OTHER_AXIS_EVENTS.includes(type);
18
+ }
11
19
  export function hasLedgerPositionKey(ev) {
12
20
  const { id, seq } = ev;
13
21
  return (id !== undefined && id !== null) || (seq !== undefined && seq !== null);
@@ -27,8 +35,8 @@ export function createGateLedger() {
27
35
  const startedCalls = new Set();
28
36
  const endedCalls = new Set();
29
37
  const heldAskEnds = new Map();
30
- const gatedStartArgsByCall = new Map();
31
38
  const startArgsByCall = new Map();
39
+ const gatedStartCalls = new Set();
32
40
  const deniedCalls = new Set();
33
41
  const denyAttributionByCall = new Map();
34
42
  const pendingFsCalls = [];
@@ -37,6 +45,7 @@ export function createGateLedger() {
37
45
  let alreadyResolvedKey;
38
46
  let alreadyResolvedStreak = 0;
39
47
  let fsOrShellFamilyGate = false;
48
+ let batchParkSubject;
40
49
  const droppedFromBatch = new Set();
41
50
  let batchParkCount = 0;
42
51
  let heldSinceLastPark = false;
@@ -45,6 +54,8 @@ export function createGateLedger() {
45
54
  const resolveGateSubjects = () => {
46
55
  if (batchParkCount !== 1)
47
56
  return undefined;
57
+ if (batchParkSubject !== undefined)
58
+ return new Set([batchParkSubject]);
48
59
  if (!fsOrShellFamilyGate)
49
60
  return undefined;
50
61
  for (const id of heldAskEnds.keys()) {
@@ -78,8 +89,16 @@ export function createGateLedger() {
78
89
  }
79
90
  return n === 1;
80
91
  };
92
+ const bystanderUnderIdentity = (ev, subject) => {
93
+ const parent = ev.parentToolCallId;
94
+ if (typeof parent === 'string' && parent !== '')
95
+ return false;
96
+ const own = ev.gatedCallId;
97
+ return !(typeof own === 'string' && own !== '' && own !== subject);
98
+ };
81
99
  const retireBatchState = () => {
82
100
  fsOrShellFamilyGate = false;
101
+ batchParkSubject = undefined;
83
102
  droppedFromBatch.clear();
84
103
  batchParkCount = 0;
85
104
  heldSinceLastPark = false;
@@ -101,8 +120,8 @@ export function createGateLedger() {
101
120
  forgetRunScopedState() {
102
121
  seq = undefined;
103
122
  startedCalls.clear();
104
- gatedStartArgsByCall.clear();
105
123
  startArgsByCall.clear();
124
+ gatedStartCalls.clear();
106
125
  },
107
126
  notePreambleApproval(approvalId) {
108
127
  if (typeof approvalId !== 'string' || approvalId === '')
@@ -144,26 +163,41 @@ export function createGateLedger() {
144
163
  return true;
145
164
  },
146
165
  noteGatedStart(callId, ev) {
147
- gatedStartArgsByCall.set(callId, ev.args);
166
+ if (!startArgsByCall.has(callId))
167
+ startArgsByCall.set(callId, ev.args);
168
+ gatedStartCalls.add(callId);
148
169
  },
149
170
  gatedStartArgs() {
150
- return gatedStartArgsByCall;
171
+ const out = new Map();
172
+ for (const id of gatedStartCalls)
173
+ if (startArgsByCall.has(id))
174
+ out.set(id, startArgsByCall.get(id));
175
+ return out;
151
176
  },
152
177
  noteStart(callId, ev) {
178
+ if (gatedStartCalls.has(callId))
179
+ return;
153
180
  startArgsByCall.delete(callId);
154
181
  startArgsByCall.set(callId, ev.args);
155
- while (startArgsByCall.size > START_ARGS_MAX_ENTRIES) {
156
- const oldest = startArgsByCall.keys().next();
157
- if (oldest.done === true)
182
+ while (startArgsByCall.size - gatedStartCalls.size > START_ARGS_MAX_ENTRIES) {
183
+ let victim;
184
+ for (const id of startArgsByCall.keys()) {
185
+ if (!gatedStartCalls.has(id)) {
186
+ victim = id;
187
+ break;
188
+ }
189
+ }
190
+ if (victim === undefined)
158
191
  break;
159
- startArgsByCall.delete(oldest.value);
192
+ startArgsByCall.delete(victim);
160
193
  }
161
194
  },
162
195
  startArgs() {
163
196
  return startArgsByCall;
164
197
  },
165
198
  dropStartArgs(callId) {
166
- startArgsByCall.delete(callId);
199
+ if (!gatedStartCalls.has(callId))
200
+ startArgsByCall.delete(callId);
167
201
  },
168
202
  isEnded(callId) {
169
203
  return endedCalls.has(callId);
@@ -195,10 +229,12 @@ export function createGateLedger() {
195
229
  },
196
230
  *flushHeld() {
197
231
  const subjects = resolveGateSubjects();
232
+ const identity = subjects !== undefined ? batchParkSubject : undefined;
198
233
  for (const [callId, ev] of heldAskEnds) {
199
- endedCalls.add(callId);
200
- yield subjects !== undefined && !subjects.has(callId)
201
- ? { ...ev, [SEMA_COLLATERAL_ABORT_KEY]: true }
234
+ if (parkedToolEndRoleOf(ev) !== 'held')
235
+ endedCalls.add(callId);
236
+ yield subjects !== undefined && !subjects.has(callId) && (identity === undefined || bystanderUnderIdentity(ev, identity))
237
+ ? inheritFrameBinding(ev, { ...ev, [SEMA_COLLATERAL_ABORT_KEY]: true })
202
238
  : ev;
203
239
  }
204
240
  heldAskEnds.clear();
@@ -260,6 +296,7 @@ export function createGateLedger() {
260
296
  return;
261
297
  batchParkCount += 1;
262
298
  fsOrShellFamilyGate = evidence.fsOrShellFamily;
299
+ batchParkSubject = typeof evidence.gatedCallId === 'string' && evidence.gatedCallId !== '' ? evidence.gatedCallId : undefined;
263
300
  heldSinceLastPark = false;
264
301
  },
265
302
  hasBatchPark() {