@sema-agent/client-core 0.93.1 → 0.95.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 (321) hide show
  1. package/CHANGELOG.md +554 -0
  2. package/README.md +89 -55
  3. package/dist/adapt/arms.js +13 -11
  4. package/dist/adapt/panelTasks.js +4 -10
  5. package/dist/adapt/toolCards.js +2 -2
  6. package/dist/adapt/wireShapes.js +3 -8
  7. package/dist/adapter/activeRunSelfHeal.d.ts +8 -3
  8. package/dist/adapter/activeRunSelfHeal.js +20 -12
  9. package/dist/adapter/downstream/eventToSdkMessage.js +24 -17
  10. package/dist/adapter/downstream/terminalToSdkResult.js +13 -6
  11. package/dist/adapter/runStream.js +2 -1
  12. package/dist/adapter/types.d.ts +7 -0
  13. package/dist/adapter/types.js +15 -0
  14. package/dist/agentSession/backgroundView.js +5 -1
  15. package/dist/agentSession/engineAgentRegistryRead.js +2 -1
  16. package/dist/agentSession/engineSessionBackgroundStop.js +5 -3
  17. package/dist/agentsWireCaps.d.ts +17 -0
  18. package/dist/agentsWireCaps.js +111 -1
  19. package/dist/approvalDecidedByCapability.d.ts +0 -1
  20. package/dist/approvalDecidedByCapability.js +2 -7
  21. package/dist/approvalReachWire.d.ts +18 -0
  22. package/dist/approvalReachWire.js +58 -0
  23. package/dist/approvalsStreamLiveCapability.d.ts +0 -1
  24. package/dist/approvalsStreamLiveCapability.js +15 -14
  25. package/dist/atMostOnce.d.ts +8 -0
  26. package/dist/atMostOnce.js +36 -0
  27. package/dist/attachmentSeatCapability.d.ts +0 -1
  28. package/dist/attachmentSeatCapability.js +0 -3
  29. package/dist/attachmentsWireCaps.js +11 -6
  30. package/dist/bashExitReading.d.ts +10 -0
  31. package/dist/bashExitReading.js +12 -0
  32. package/dist/callerCwdCapability.d.ts +15 -0
  33. package/dist/callerCwdCapability.js +42 -0
  34. package/dist/centerWiringCapability.d.ts +1 -3
  35. package/dist/centerWiringCapability.js +18 -21
  36. package/dist/classifierStatus.js +4 -4
  37. package/dist/cloudConfigWireCaps.js +43 -21
  38. package/dist/compensations.js +1 -1
  39. package/dist/controlRouter.js +3 -10
  40. package/dist/coreValuePorts.d.ts +64 -1
  41. package/dist/coreValuePorts.js +30 -0
  42. package/dist/cycleOrder.d.ts +15 -0
  43. package/dist/cycleOrder.js +45 -0
  44. package/dist/decideFailureNote.js +4 -1
  45. package/dist/decideReceipt.d.ts +2 -1
  46. package/dist/decideReceipt.js +41 -13
  47. package/dist/declared/supportFloorDeclared.d.ts +1 -0
  48. package/dist/declared/supportFloorDeclared.js +5 -0
  49. package/dist/detachWire.d.ts +1 -4
  50. package/dist/detachWire.js +1 -1
  51. package/dist/deviceExecutorManagementCapability.d.ts +0 -1
  52. package/dist/deviceExecutorManagementCapability.js +36 -40
  53. package/dist/deviceFlowPolling.d.ts +5 -0
  54. package/dist/deviceFlowPolling.js +28 -0
  55. package/dist/deviceRebind.d.ts +88 -0
  56. package/dist/deviceRebind.js +242 -0
  57. package/dist/displayUntrusted.d.ts +1 -0
  58. package/dist/displayUntrusted.js +963 -30
  59. package/dist/engineAgentAbsence.d.ts +2 -2
  60. package/dist/engineAgentPanelStore.d.ts +8 -18
  61. package/dist/engineAgentPanelStore.js +19 -537
  62. package/dist/engineCapReader.d.ts +6 -6
  63. package/dist/engineCapReader.js +30 -43
  64. package/dist/engineCapsCache.d.ts +7 -2
  65. package/dist/engineCapsCache.js +64 -26
  66. package/dist/engineCredentialRequirement.d.ts +9 -0
  67. package/dist/engineCredentialRequirement.js +23 -0
  68. package/dist/engineEnvSourcing.d.ts +53 -0
  69. package/dist/engineEnvSourcing.js +81 -0
  70. package/dist/engineErrorCodes.d.ts +19 -4
  71. package/dist/engineErrorCodes.js +39 -21
  72. package/dist/engineIdentity.js +2 -0
  73. package/dist/engineNoticeCodes.d.ts +22 -2
  74. package/dist/engineNoticeCodes.js +73 -6
  75. package/dist/engineRefusedToolName.d.ts +1 -0
  76. package/dist/engineRefusedToolName.js +8 -0
  77. package/dist/engineWireSdk.js +2 -2
  78. package/dist/executionLaneCapability.d.ts +2 -3
  79. package/dist/executionLaneCapability.js +28 -28
  80. package/dist/fileHistoryCaptureCapability.d.ts +0 -1
  81. package/dist/fileHistoryCaptureCapability.js +13 -12
  82. package/dist/fileHistoryLegNotice.d.ts +14 -2
  83. package/dist/fileHistoryLegNotice.js +101 -15
  84. package/dist/fleet/fleetLedger.d.ts +2 -0
  85. package/dist/fleet/fleetLedger.js +74 -52
  86. package/dist/fleet/fleetProjection.d.ts +0 -3
  87. package/dist/fleet/fleetProjection.js +9 -16
  88. package/dist/fleetAgentPanelProjection.d.ts +4 -17
  89. package/dist/fleetAgentPanelProjection.js +7 -197
  90. package/dist/fleetAgentRowLike.d.ts +16 -0
  91. package/dist/fleetAgentRowLike.js +1 -0
  92. package/dist/gateOutcome.d.ts +2 -1
  93. package/dist/gateOutcome.js +33 -18
  94. package/dist/gateVocabulary.js +1 -1
  95. package/dist/generated/engineAskFaceTables.d.ts +3 -0
  96. package/dist/generated/engineAskFaceTables.js +12 -0
  97. package/dist/generated/engineFactTables.d.ts +4 -2
  98. package/dist/generated/engineFactTables.js +13 -0
  99. package/dist/generated/engineNoticeTables.d.ts +5 -0
  100. package/dist/generated/engineNoticeTables.js +7 -0
  101. package/dist/generated/sdkFactTables.d.ts +5 -0
  102. package/dist/generated/sdkFactTables.js +34 -0
  103. package/dist/generated/settingsSchemaFns.d.ts +10 -0
  104. package/dist/generated/settingsSchemaFns.js +22 -0
  105. package/dist/generated/settingsSchemaTables.d.ts +3 -0
  106. package/dist/generated/settingsSchemaTables.js +3 -0
  107. package/dist/headlessPermissionModeWire.d.ts +2 -2
  108. package/dist/headlessPermissionModeWire.js +11 -21
  109. package/dist/headlessReconnectWire.js +49 -20
  110. package/dist/hitl/allowRuleShadow.d.ts +1 -1
  111. package/dist/hitl/allowRuleShadow.js +49 -8
  112. package/dist/hitl/approvalCompleteParked.d.ts +1 -0
  113. package/dist/hitl/approvalCompleteParked.js +14 -0
  114. package/dist/hitl/approvalEndingCause.d.ts +5 -0
  115. package/dist/hitl/approvalEndingCause.js +61 -0
  116. package/dist/hitl/approvalHolds.d.ts +46 -0
  117. package/dist/hitl/approvalHolds.js +140 -0
  118. package/dist/hitl/approvalOutcomeNote.js +2 -1
  119. package/dist/hitl/approvalResolution.js +9 -1
  120. package/dist/hitl/approvalsFeed.js +23 -6
  121. package/dist/hitl/askGateWire.d.ts +2 -1
  122. package/dist/hitl/askGateWire.js +29 -1
  123. package/dist/hitl/automaticAnswerVerdict.d.ts +8 -2
  124. package/dist/hitl/automaticAnswerVerdict.js +71 -23
  125. package/dist/hitl/crashConverged.js +2 -0
  126. package/dist/hitl/decisionConflict.d.ts +3 -0
  127. package/dist/hitl/decisionConflict.js +43 -0
  128. package/dist/hitl/decisionRefusal.d.ts +23 -0
  129. package/dist/hitl/decisionRefusal.js +88 -0
  130. package/dist/hitl/frameRouter.d.ts +10 -0
  131. package/dist/hitl/frameRouter.js +71 -32
  132. package/dist/hitl/gateLedger.d.ts +8 -0
  133. package/dist/hitl/gateLedger.js +38 -0
  134. package/dist/hitl/hitlBridge.d.ts +14 -3
  135. package/dist/hitl/hitlBridge.js +75 -62
  136. package/dist/hitl/hitlHostSurface.d.ts +3 -0
  137. package/dist/hitl/hitlHostSurface.js +17 -15
  138. package/dist/hitl/livePendingAsk.d.ts +16 -6
  139. package/dist/hitl/livePendingAsk.js +36 -4
  140. package/dist/hitl/localAllowRule.js +2 -1
  141. package/dist/hitl/noAllowCause.d.ts +9 -0
  142. package/dist/hitl/noAllowCause.js +26 -0
  143. package/dist/hitl/parkExpiryJudgements.d.ts +19 -0
  144. package/dist/hitl/parkExpiryJudgements.js +46 -0
  145. package/dist/hitl/parkResolver.d.ts +3 -7
  146. package/dist/hitl/parkResolver.js +55 -28
  147. package/dist/hitl/parkRowBirthWait.js +2 -1
  148. package/dist/hitl/persistedRulesWire.d.ts +6 -1
  149. package/dist/hitl/persistedRulesWire.js +16 -4
  150. package/dist/hitl/planReviewWire.d.ts +2 -3
  151. package/dist/hitl/planReviewWire.js +86 -39
  152. package/dist/hitl/replayedApproval.d.ts +8 -0
  153. package/dist/hitl/replayedApproval.js +125 -10
  154. package/dist/hitl/resumeRunningCard.d.ts +2 -0
  155. package/dist/hitl/resumeRunningCard.js +15 -4
  156. package/dist/hitl/sessionPolicyDeliverable.d.ts +1 -1
  157. package/dist/hitl/sessionPolicyDeliverable.js +3 -8
  158. package/dist/hitl/sessionPolicyWire.js +1 -1
  159. package/dist/hitl/toolApprovalWire.d.ts +50 -5
  160. package/dist/hitl/toolApprovalWire.js +368 -56
  161. package/dist/hooksWireCaps.js +38 -6
  162. package/dist/host.d.ts +5 -0
  163. package/dist/host.js +3 -1
  164. package/dist/hostCallbackGuard.d.ts +1 -0
  165. package/dist/hostCallbackGuard.js +25 -0
  166. package/dist/humanTurnRead.d.ts +15 -1
  167. package/dist/humanTurnRead.js +28 -2
  168. package/dist/index.d.ts +45 -14
  169. package/dist/index.js +33 -12
  170. package/dist/interactiveInterrupt.d.ts +8 -0
  171. package/dist/interactiveInterrupt.js +54 -0
  172. package/dist/limitsWire.d.ts +5 -1
  173. package/dist/limitsWire.js +51 -13
  174. package/dist/liveModelCatalog.d.ts +109 -0
  175. package/dist/liveModelCatalog.js +344 -18
  176. package/dist/mcpEngineLeg.d.ts +25 -0
  177. package/dist/mcpEngineLeg.js +71 -15
  178. package/dist/mcpPanel.js +2 -1
  179. package/dist/mcpProbeCapability.d.ts +0 -1
  180. package/dist/mcpProbeCapability.js +13 -12
  181. package/dist/mcpReconnect.d.ts +1 -3
  182. package/dist/mcpReconnect.js +20 -10
  183. package/dist/memoryComplianceCapability.d.ts +0 -1
  184. package/dist/memoryComplianceCapability.js +14 -13
  185. package/dist/memoryOriginCapability.d.ts +0 -1
  186. package/dist/memoryOriginCapability.js +14 -13
  187. package/dist/memoryVerbsWire.d.ts +1 -1
  188. package/dist/memoryVerbsWire.js +4 -0
  189. package/dist/model/liveCatalogShape.d.ts +14 -0
  190. package/dist/model/liveCatalogShape.js +71 -0
  191. package/dist/model/modelSupplyRules.d.ts +1 -0
  192. package/dist/model/modelSupplyRules.js +30 -9
  193. package/dist/model/modelsPolicy.d.ts +21 -0
  194. package/dist/model/modelsPolicy.js +90 -0
  195. package/dist/modelIdentityResolvability.d.ts +4 -2
  196. package/dist/modelIdentityResolvability.js +25 -5
  197. package/dist/modelSwitchFallback.d.ts +69 -0
  198. package/dist/modelSwitchFallback.js +206 -0
  199. package/dist/notifications.js +12 -11
  200. package/dist/outputStyleSeatCapability.d.ts +15 -0
  201. package/dist/outputStyleSeatCapability.js +42 -0
  202. package/dist/ownKey.d.ts +7 -0
  203. package/dist/ownKey.js +58 -0
  204. package/dist/panelReduce.d.ts +114 -0
  205. package/dist/panelReduce.js +1135 -0
  206. package/dist/panelStateHolder.d.ts +17 -0
  207. package/dist/panelStateHolder.js +201 -0
  208. package/dist/peerLaneCapability.d.ts +0 -1
  209. package/dist/peerLaneCapability.js +15 -14
  210. package/dist/permissionModesCapability.d.ts +0 -1
  211. package/dist/permissionModesCapability.js +5 -10
  212. package/dist/permissionRuleIssue.js +1 -1
  213. package/dist/permissionRulesWriteCapability.d.ts +0 -1
  214. package/dist/permissionRulesWriteCapability.js +15 -14
  215. package/dist/permissionsAllowGrantCapability.d.ts +2 -1
  216. package/dist/permissionsAllowGrantCapability.js +35 -19
  217. package/dist/permissionsDeclaration.d.ts +16 -1
  218. package/dist/permissionsDeclaration.js +142 -15
  219. package/dist/printToolResultFrame.js +2 -10
  220. package/dist/promptDelivery.js +0 -8
  221. package/dist/protocolSegment.d.ts +1 -0
  222. package/dist/protocolSegment.js +13 -1
  223. package/dist/request/taskRequest.d.ts +11 -3
  224. package/dist/request/taskRequest.js +13 -1
  225. package/dist/resultFrameKeys.d.ts +4 -0
  226. package/dist/resultFrameKeys.js +13 -0
  227. package/dist/resumeRefusalCopy.d.ts +18 -1
  228. package/dist/resumeRefusalCopy.js +132 -31
  229. package/dist/retryStatus.js +6 -4
  230. package/dist/rewindArchiveCapability.d.ts +2 -1
  231. package/dist/rewindArchiveCapability.js +28 -15
  232. package/dist/rewindEngineAction.d.ts +21 -0
  233. package/dist/rewindEngineAction.js +36 -0
  234. package/dist/rewindWireCaps.d.ts +2 -1
  235. package/dist/rewindWireCaps.js +1 -0
  236. package/dist/{hitl/rosterMountedNames.d.ts → rosterMountedNames.d.ts} +1 -1
  237. package/dist/runCancelContext.js +2 -1
  238. package/dist/runTerminal.d.ts +0 -11
  239. package/dist/runTerminal.js +4 -27
  240. package/dist/sdkRegistryTransit.d.ts +2 -1
  241. package/dist/sdkRegistryTransit.js +1 -0
  242. package/dist/sealedKeyCapability.d.ts +0 -1
  243. package/dist/sealedKeyCapability.js +19 -20
  244. package/dist/seatContract.d.ts +85 -28
  245. package/dist/seatContract.js +512 -148
  246. package/dist/sessionIdSegment.d.ts +1 -0
  247. package/dist/sessionIdSegment.js +11 -0
  248. package/dist/sessionMemoryErase.d.ts +1 -1
  249. package/dist/sessionMemoryErase.js +6 -1
  250. package/dist/sessionMemoryStatus.js +3 -2
  251. package/dist/sessionPolicyCapability.d.ts +0 -1
  252. package/dist/sessionPolicyCapability.js +14 -13
  253. package/dist/sessionReadRedactionCapability.d.ts +15 -0
  254. package/dist/sessionReadRedactionCapability.js +42 -0
  255. package/dist/sessionSyncFileHistoryCapability.d.ts +0 -1
  256. package/dist/sessionSyncFileHistoryCapability.js +13 -12
  257. package/dist/skillToolListsCapability.d.ts +0 -1
  258. package/dist/skillToolListsCapability.js +13 -12
  259. package/dist/skillsWireCaps.d.ts +4 -0
  260. package/dist/skillsWireCaps.js +66 -1
  261. package/dist/sqlEngineCapability.d.ts +0 -1
  262. package/dist/sqlEngineCapability.js +21 -21
  263. package/dist/steerPriorityCapability.d.ts +0 -1
  264. package/dist/steerPriorityCapability.js +18 -19
  265. package/dist/storePostureCapability.d.ts +1 -1
  266. package/dist/storePostureCapability.js +16 -16
  267. package/dist/streamDrainingLegs.d.ts +6 -0
  268. package/dist/streamDrainingLegs.js +23 -0
  269. package/dist/subagent/agentStateDetail.d.ts +1 -0
  270. package/dist/subagent/agentStateDetail.js +41 -0
  271. package/dist/subagent/engineCompactWire.d.ts +15 -0
  272. package/dist/subagent/engineCompactWire.js +82 -45
  273. package/dist/subagent/engineDelegatedPrompt.js +10 -6
  274. package/dist/subagent/engineSubagentOutput.d.ts +0 -1
  275. package/dist/subagent/engineSubagentOutput.js +5 -20
  276. package/dist/subagent/engineSubagentTail.d.ts +0 -1
  277. package/dist/subagent/engineSubagentTail.js +7 -32
  278. package/dist/subagentContentStore.js +3 -3
  279. package/dist/supportFloor.js +2 -5
  280. package/dist/taskRequestWords.d.ts +2 -4
  281. package/dist/taskRequestWords.js +3 -2
  282. package/dist/terminalStatuses.d.ts +30 -0
  283. package/dist/terminalStatuses.js +67 -0
  284. package/dist/toolResult.d.ts +5 -0
  285. package/dist/toolResult.js +88 -36
  286. package/dist/types/engineState.d.ts +2 -1
  287. package/dist/usageAnalytics.d.ts +146 -0
  288. package/dist/usageAnalytics.js +311 -0
  289. package/dist/userAttachmentEnvelope.d.ts +22 -1
  290. package/dist/userAttachmentEnvelope.js +90 -2
  291. package/dist/userInvokedSkillsCapability.d.ts +0 -1
  292. package/dist/userInvokedSkillsCapability.js +13 -12
  293. package/dist/webSearchBackendCapability.d.ts +0 -1
  294. package/dist/webSearchBackendCapability.js +20 -19
  295. package/dist/webSearchWireCaps.js +3 -11
  296. package/dist/wireErrorTriage.d.ts +11 -0
  297. package/dist/wireErrorTriage.js +35 -0
  298. package/dist/wireFailureShape.d.ts +10 -0
  299. package/dist/wireFailureShape.js +72 -5
  300. package/dist/wireRefusalCopy.d.ts +6 -1
  301. package/dist/wireRefusalCopy.js +23 -25
  302. package/dist/wiringInstructionsAttribution.d.ts +10 -0
  303. package/dist/wiringInstructionsAttribution.js +67 -0
  304. package/dist/workflowClient.js +19 -2
  305. package/dist/workflowsJournalCapability.d.ts +0 -1
  306. package/dist/workflowsJournalCapability.js +13 -12
  307. package/dist/writeProtectionCapability.d.ts +0 -1
  308. package/dist/writeProtectionCapability.js +26 -26
  309. package/docs/INTEGRATION-CLIENTS.md +1733 -52
  310. package/package.json +5 -5
  311. package/dist/askSurvivesStandingAnswer.d.ts +0 -13
  312. package/dist/askSurvivesStandingAnswer.js +0 -53
  313. package/dist/engineCapsGenerationGuard.d.ts +0 -4
  314. package/dist/engineCapsGenerationGuard.js +0 -19
  315. package/dist/hitl/askSurvivesPosture.d.ts +0 -20
  316. package/dist/hitl/askSurvivesPosture.js +0 -48
  317. package/dist/panelRunningHistory.d.ts +0 -22
  318. package/dist/panelRunningHistory.js +0 -82
  319. package/dist/registryConflict.d.ts +0 -3
  320. package/dist/registryConflict.js +0 -44
  321. /package/dist/{hitl/rosterMountedNames.js → rosterMountedNames.js} +0 -0
@@ -1,8 +1,11 @@
1
1
  import { askParkForeignGateKind } from '../adapter/activeRunSelfHeal.js';
2
2
  import { eventSeq } from '../adapter/types.js';
3
3
  import { hostLog } from '../host.js';
4
+ import { invokeHostCallbackIsolated } from '../hostCallbackGuard.js';
4
5
  import { abortableSleep } from '../abortableSleep.js';
5
6
  import { readOwnDataValue } from '../ownKey.js';
7
+ import { THROWN_SLOT_UNREADABLE, readThrownSlot, thrownIsInstanceOf, wireFailureTextsOf } from '../wireFailureShape.js';
8
+ import { decisionConflictOf } from './decisionConflict.js';
6
9
  import { suspendedReopenOf } from './suspendedReopen.js';
7
10
  export const DEFAULT_DENY_REASON = 'The user rejected this tool use';
8
11
  const MAX_DENY_REASON_CHARS = 4096;
@@ -26,6 +29,14 @@ export const PLAN_REVIEW_MODE_AFTER_WORDS = Object.freeze(['default', 'acceptEdi
26
29
  export function isPlanReviewModeAfter(v) {
27
30
  return v !== undefined && PLAN_REVIEW_MODE_AFTER_WORDS.includes(v);
28
31
  }
32
+ export const GATE_FAILURE_CODES = [
33
+ 'no_pending',
34
+ 'binding_mismatch',
35
+ 'wrong_gate',
36
+ 'bad_plan_edit',
37
+ 'bad_plan_mode',
38
+ 'empty_answer',
39
+ ];
29
40
  export const NO_APPROVAL_CARD_PORT_REASON = 'no approval card port installed (print/non-REPL mode, or host forgot installApprovalCardPort)';
30
41
  export const APPROVAL_CARD_PORT_KEY_MISMATCH_REASON = 'no approval card port installed for the default session key, but a non-default sessionKey has one — likely a keyed-install/default-read mismatch (installApprovalCardPortFor vs the zero-arg default-key read), not a missing install';
31
42
  export const NO_QUESTION_OVERLAY_REASON = 'no question overlay mounted (print/non-REPL mode)';
@@ -40,28 +51,46 @@ export class HitlSafetyError extends Error {
40
51
  this.name = 'HitlSafetyError';
41
52
  }
42
53
  }
54
+ export function hitlSafetyCodeOf(e) {
55
+ if (!thrownIsInstanceOf(e, HitlSafetyError))
56
+ return undefined;
57
+ const raw = readThrownSlot(e, 'code');
58
+ return typeof raw === 'string' && GATE_FAILURE_CODES.includes(raw) ? raw : undefined;
59
+ }
43
60
  const _gateCurrentPendingReadonlyPin = true;
44
61
  void _gateCurrentPendingReadonlyPin;
45
62
  export function readDecideCurrentPending(e) {
46
- const raw = e?.currentPending;
63
+ if (e === null || e === undefined)
64
+ return undefined;
65
+ const raw = readThrownSlot(e, 'currentPending');
47
66
  if (typeof raw !== 'object' || raw === null)
48
67
  return undefined;
49
- const o = raw;
50
- if (typeof o.toolName !== 'string' || o.toolName.length === 0)
68
+ const toolName = readThrownSlot(raw, 'toolName');
69
+ const boundCallId = readThrownSlot(raw, 'boundCallId');
70
+ const boundInputHash = readThrownSlot(raw, 'boundInputHash');
71
+ if (typeof toolName !== 'string' || toolName.length === 0)
51
72
  return undefined;
52
- if (typeof o.boundCallId !== 'string' || o.boundCallId.length === 0)
73
+ if (typeof boundCallId !== 'string' || boundCallId.length === 0)
53
74
  return undefined;
54
75
  return {
55
- toolName: o.toolName,
56
- boundCallId: o.boundCallId,
57
- ...(typeof o.boundInputHash === 'string' && o.boundInputHash.length > 0
58
- ? { boundInputHash: o.boundInputHash }
76
+ toolName,
77
+ boundCallId,
78
+ ...(typeof boundInputHash === 'string' && boundInputHash.length > 0
79
+ ? { boundInputHash }
59
80
  : {}),
60
81
  };
61
82
  }
62
83
  export function readWireErrorCode(e) {
63
- const raw = e?.errorCode;
64
- return typeof raw === 'string' && raw.length > 0 ? raw : undefined;
84
+ const reading = readWireErrorCodeReading(e);
85
+ return reading.state === 'code' ? reading.code : undefined;
86
+ }
87
+ export function readWireErrorCodeReading(e) {
88
+ if (e === null || e === undefined)
89
+ return { state: 'absent' };
90
+ const raw = readThrownSlot(e, 'errorCode');
91
+ if (raw === THROWN_SLOT_UNREADABLE)
92
+ return { state: 'unreadable' };
93
+ return typeof raw === 'string' && raw.length > 0 ? { state: 'code', code: raw } : { state: 'absent' };
65
94
  }
66
95
  const DECIDE_TRANSPORT_RETRY_BACKOFF_MS = 750;
67
96
  const DECIDE_RETRY_BACKOFF_MAX_MS = 5_000;
@@ -79,10 +108,9 @@ function decideTimeoutRetryBudgetMs() {
79
108
  function isDecideAttemptTimeout(e, depth = 0) {
80
109
  if (depth > 3 || e === null || typeof e !== 'object')
81
110
  return false;
82
- const o = e;
83
- if (o.name === 'TimeoutError')
111
+ if (readThrownSlot(e, 'name') === 'TimeoutError')
84
112
  return true;
85
- return isDecideAttemptTimeout(o.cause, depth + 1);
113
+ return isDecideAttemptTimeout(readThrownSlot(e, 'cause'), depth + 1);
86
114
  }
87
115
  const TRANSIENT_NETWORK_CODES = new Set([
88
116
  'ECONNREFUSED', 'ECONNRESET', 'ETIMEDOUT', 'EPIPE', 'EAI_AGAIN',
@@ -92,18 +120,21 @@ const TRANSIENT_NETWORK_CODES = new Set([
92
120
  function isTransientDecideTransportFailure(e, depth = 0) {
93
121
  if (depth > 3 || e === null || typeof e !== 'object')
94
122
  return false;
95
- if (e instanceof HitlSafetyError)
123
+ if (thrownIsInstanceOf(e, HitlSafetyError))
96
124
  return false;
97
- const o = e;
98
- if (typeof o.status === 'number')
125
+ const status = readThrownSlot(e, 'status');
126
+ if (status === THROWN_SLOT_UNREADABLE || typeof status === 'number')
99
127
  return false;
100
- if (o.name === 'TimeoutError' || o.name === 'AbortError')
128
+ const name = readThrownSlot(e, 'name');
129
+ if (name === 'TimeoutError' || name === 'AbortError')
101
130
  return true;
102
- if (typeof o.code === 'string' && TRANSIENT_NETWORK_CODES.has(o.code))
131
+ const code = readThrownSlot(e, 'code');
132
+ if (typeof code === 'string' && TRANSIENT_NETWORK_CODES.has(code))
103
133
  return true;
104
- if (typeof o.message === 'string' && o.message.toLowerCase().includes('fetch failed'))
134
+ const message = readThrownSlot(e, 'message');
135
+ if (typeof message === 'string' && message.toLowerCase().includes('fetch failed'))
105
136
  return true;
106
- return isTransientDecideTransportFailure(o.cause, depth + 1);
137
+ return isTransientDecideTransportFailure(readThrownSlot(e, 'cause'), depth + 1);
107
138
  }
108
139
  export class DecideTransportRetryExhaustedError extends Error {
109
140
  attempts;
@@ -148,7 +179,7 @@ class DecideSpan {
148
179
  }
149
180
  catch (e) {
150
181
  this.ok = false;
151
- this.retryExhausted = e instanceof DecideTransportRetryExhaustedError;
182
+ this.retryExhausted = thrownIsInstanceOf(e, DecideTransportRetryExhaustedError);
152
183
  throw e;
153
184
  }
154
185
  finally {
@@ -174,32 +205,13 @@ class DecideSpan {
174
205
  notifyDecideObserver(this.observer, Object.freeze({ ...this.identity, phase: 'end', ok: this.ok, attempts: this.attempts, retryExhausted: this.retryExhausted }));
175
206
  }
176
207
  }
177
- function reportObserverFault(phase, what, e) {
178
- try {
179
- hostLog('debug', `hitlBridge: onDecideOperation(${phase}) ${what}: ${String(e).slice(0, 160)}`);
180
- return true;
181
- }
182
- catch {
183
- return false;
184
- }
185
- }
186
208
  function wireOptsOf(opts) {
187
209
  if (opts === undefined || opts.operation === undefined)
188
210
  return opts;
189
211
  return opts.signal !== undefined ? { signal: opts.signal } : undefined;
190
212
  }
191
213
  function notifyDecideObserver(observer, ev) {
192
- try {
193
- const out = observer(ev);
194
- if (out && typeof out.then === 'function') {
195
- void Promise.resolve(out).then(undefined, (e) => {
196
- reportObserverFault(ev.phase, 'rejected', e);
197
- });
198
- }
199
- }
200
- catch (e) {
201
- reportObserverFault(ev.phase, 'threw', e);
202
- }
214
+ invokeHostCallbackIsolated(`hitlBridge: onDecideOperation(${ev.phase})`, () => observer(ev));
203
215
  }
204
216
  const ANY_TOOL_FAMILY = () => true;
205
217
  export async function findPendingForTask(client, taskId, matches, opts, callId, identityAccepts = (r) => matches(typeof r.toolName === 'string' ? r.toolName : undefined)) {
@@ -208,7 +220,9 @@ export async function findPendingForTask(client, taskId, matches, opts, callId,
208
220
  rows = (await client.approvals.list(opts)).pending;
209
221
  }
210
222
  catch (e) {
211
- return { ok: false, reason: `approvals.list failed: ${String(e)}` };
223
+ const t = wireFailureTextsOf(e);
224
+ hostLog('debug', `hitlBridge: approvals.list failed: ${t.log}`);
225
+ return { ok: false, reason: `approvals.list failed: ${t.reason}` };
212
226
  }
213
227
  const decidable = rows.filter((r) => askParkForeignGateKind(r) === null);
214
228
  const identityRow = callId !== undefined
@@ -327,13 +341,8 @@ export class HitlBridge {
327
341
  throw new HitlSafetyError(`plan-review "${outcome.decision}" must NOT carry editedPlan`, 'bad_plan_edit');
328
342
  }
329
343
  const modeAfter = outcome.permissionModeAfter;
330
- if (modeAfter !== undefined) {
331
- if (outcome.decision !== 'approve') {
332
- throw new HitlSafetyError(`plan-review "${outcome.decision}" must NOT carry permissionModeAfter (it only applies to an approval)`, 'bad_plan_mode');
333
- }
334
- if (!isPlanReviewModeAfter(modeAfter)) {
335
- throw new HitlSafetyError('plan-review permissionModeAfter must be "default" or "acceptEdits"', 'bad_plan_mode');
336
- }
344
+ if (modeAfter !== undefined && !isPlanReviewModeAfter(modeAfter)) {
345
+ throw new HitlSafetyError('plan-review permissionModeAfter must be "default" or "acceptEdits"', 'bad_plan_mode');
337
346
  }
338
347
  const req = { decision: outcome.decision };
339
348
  if (modeAfter !== undefined && isPlanReviewModeAfter(modeAfter))
@@ -376,7 +385,7 @@ export class HitlBridge {
376
385
  return r;
377
386
  }
378
387
  catch (e) {
379
- retryExhausted = e instanceof DecideTransportRetryExhaustedError;
388
+ retryExhausted = thrownIsInstanceOf(e, DecideTransportRetryExhaustedError);
380
389
  throw e;
381
390
  }
382
391
  finally {
@@ -409,18 +418,21 @@ export class HitlBridge {
409
418
  return r;
410
419
  }
411
420
  catch (e) {
412
- if (isBindingMismatch(e)) {
421
+ const binding = bindingMismatchReading(e);
422
+ if (binding === 'mismatch') {
413
423
  throw new HitlSafetyError('approval_binding_mismatch — the pending action changed under the human; refetch + re-present', 'binding_mismatch');
414
424
  }
425
+ if (binding === 'unreadable')
426
+ throw e;
415
427
  if (!isTransientDecideTransportFailure(e) || callerAborted())
416
428
  throw e;
417
429
  if (isDecideAttemptTimeout(e)) {
418
430
  if (attempts >= DECIDE_TIMEOUT_MIN_ATTEMPTS && Date.now() - startedAt >= decideTimeoutRetryBudgetMs()) {
419
- throw new DecideTransportRetryExhaustedError(attempts, String(e));
431
+ throw new DecideTransportRetryExhaustedError(attempts, wireFailureTextsOf(e).reason);
420
432
  }
421
433
  }
422
434
  else if (netRetriesUsed >= 1) {
423
- throw new DecideTransportRetryExhaustedError(attempts, String(e));
435
+ throw new DecideTransportRetryExhaustedError(attempts, wireFailureTextsOf(e).reason);
424
436
  }
425
437
  else {
426
438
  netRetriesUsed++;
@@ -481,16 +493,17 @@ function marshalAnswer(a) {
481
493
  entry.note = a.note;
482
494
  return entry;
483
495
  }
484
- function isBindingMismatch(e) {
496
+ function bindingMismatchReading(e) {
485
497
  if (!e || typeof e !== 'object')
486
- return false;
487
- const o = e;
488
- const code = o.errorCode;
489
- if (code === 'approval_binding_mismatch')
490
- return true;
491
- if (typeof o.name === 'string' && o.name === 'ApprovalBindingMismatchError')
492
- return true;
493
- return false;
498
+ return 'not';
499
+ const code = readWireErrorCodeReading(e);
500
+ const name = readThrownSlot(e, 'name');
501
+ const family = (code.state === 'code' && code.code === 'approval_binding_mismatch') || name === 'ApprovalBindingMismatchError';
502
+ if (family)
503
+ return decisionConflictOf(e) !== 'answer_invalid' ? 'mismatch' : 'not';
504
+ if (code.state === 'unreadable')
505
+ return 'unreadable';
506
+ return 'not';
494
507
  }
495
508
  export function backendDeny(reason) {
496
509
  return {
@@ -23,6 +23,7 @@ export declare function hitlHostSurfaceFor(sessionKey: string): HitlHostSurface
23
23
  export declare function _resetHitlHostSurfaceForTest(): void;
24
24
  export declare function surfaceForCurrentSession(): HitlHostSurface | null;
25
25
  export declare const CANCEL_DENY_BUDGET_MS = 2000;
26
+ export declare const INTERRUPT_DENY_REASON = "Interrupted by user";
26
27
  export declare const CANCEL_DENY_WARN_TEXT = "could not cancel the pending question \u2014 the session may stay locked; the run may need engine-side recovery";
27
28
  export declare const REMEMBER_NOT_APPLIED_WARN_TEXT = "this session-wide allow was not remembered by the worker \u2014 you will be asked again for this tool";
28
29
  export declare const EDIT_NOT_FORWARDED_WARN_TEXT = "your edited tool input was NOT forwarded \u2014 the tool is running with the ORIGINAL input you saw before editing";
@@ -31,6 +32,8 @@ export declare function surfaceEditNotForwarded(): void;
31
32
  export declare const APPROVAL_PARKING_WARN_TEXT = "This approval is being parked; answer it again on the parked card when it appears.";
32
33
  export declare function approvalParkingNoticeText(retryAfterMs?: number): string;
33
34
  export declare function surfaceApprovalParking(retryAfterMs?: number): void;
35
+ export declare const COMPACT_NOT_RUNNING_WARN_TEXT = "engine run finished before compaction was applied; nothing was compacted";
36
+ export declare function surfaceCompactNotRunning(sessionKey?: string): void;
34
37
  export declare const REPLAYED_APPROVAL_LIST_UNREADABLE_WARN_TEXT: string;
35
38
  export declare function surfaceReplayedApprovalListUnreadable(): void;
36
39
  export declare const EDIT_REFUSED_ON_BLIND_ASK_WARN_TEXT: string;
@@ -2,7 +2,7 @@ import { createSessionSlot, DEFAULT_SESSION_KEY } from '../sessionSlot.js';
2
2
  import { hostLog } from '../host.js';
3
3
  import { unrefTimer } from '../unrefTimer.js';
4
4
  import { decideFailureNote } from '../decideFailureNote.js';
5
- import { HitlSafetyError } from './hitlBridge.js';
5
+ import { decisionRefusalSaysAskGone } from './decisionRefusal.js';
6
6
  const hostSurfaceByKey = createSessionSlot();
7
7
  const hostSurfaceMissesByKey = new Map();
8
8
  export function installHitlHostSurface(surface) {
@@ -29,22 +29,26 @@ export function _resetHitlHostSurfaceForTest() {
29
29
  hostSurfaceMissesByKey.clear();
30
30
  }
31
31
  export function surfaceForCurrentSession() {
32
- const hostSurface = hitlHostSurfaceFor(DEFAULT_SESSION_KEY);
32
+ return surfaceForSession(DEFAULT_SESSION_KEY);
33
+ }
34
+ function surfaceForSession(sessionKey) {
35
+ const hostSurface = hitlHostSurfaceFor(sessionKey);
33
36
  if (hostSurface === null) {
34
- hostSurfaceMissesByKey.set(DEFAULT_SESSION_KEY, (hostSurfaceMissesByKey.get(DEFAULT_SESSION_KEY) ?? 0) + 1);
37
+ hostSurfaceMissesByKey.set(sessionKey, (hostSurfaceMissesByKey.get(sessionKey) ?? 0) + 1);
35
38
  }
36
39
  return hostSurface;
37
40
  }
38
41
  export const CANCEL_DENY_BUDGET_MS = 2000;
42
+ export const INTERRUPT_DENY_REASON = 'Interrupted by user';
39
43
  export const CANCEL_DENY_WARN_TEXT = 'could not cancel the pending question — the session may stay locked; the run may need engine-side recovery';
40
44
  const CANCEL_DENY_WARN_KEY = 'hitl-cancel-deny-warn';
41
45
  const CANCEL_DENY_WARN_TIMEOUT_MS = 10_000;
42
46
  function surfaceCancelDenyWarn(text = CANCEL_DENY_WARN_TEXT) {
43
47
  surfaceSelfClearingWarn(CANCEL_DENY_WARN_KEY, text, CANCEL_DENY_WARN_TIMEOUT_MS);
44
48
  }
45
- function surfaceSelfClearingWarn(key, text, timeoutMs) {
49
+ function surfaceSelfClearingWarn(key, text, timeoutMs, sessionKey = DEFAULT_SESSION_KEY) {
46
50
  try {
47
- const s = surfaceForCurrentSession();
51
+ const s = surfaceForSession(sessionKey);
48
52
  if (!s)
49
53
  return;
50
54
  s.showNotice({ key, text, color: 'warning', priority: 'immediate', timeoutMs });
@@ -83,6 +87,12 @@ export function approvalParkingNoticeText(retryAfterMs) {
83
87
  export function surfaceApprovalParking(retryAfterMs) {
84
88
  surfaceSelfClearingWarn(APPROVAL_PARKING_KEY, approvalParkingNoticeText(retryAfterMs), APPROVAL_PARKING_TIMEOUT_MS);
85
89
  }
90
+ export const COMPACT_NOT_RUNNING_WARN_TEXT = 'engine run finished before compaction was applied; nothing was compacted';
91
+ const COMPACT_NOT_RUNNING_KEY = 'engine-compact-not-running';
92
+ const COMPACT_NOT_RUNNING_TIMEOUT_MS = 10_000;
93
+ export function surfaceCompactNotRunning(sessionKey = DEFAULT_SESSION_KEY) {
94
+ surfaceSelfClearingWarn(COMPACT_NOT_RUNNING_KEY, COMPACT_NOT_RUNNING_WARN_TEXT, COMPACT_NOT_RUNNING_TIMEOUT_MS, sessionKey);
95
+ }
86
96
  export const REPLAYED_APPROVAL_LIST_UNREADABLE_WARN_TEXT = "Could not read the pending-approval list, so an approval request read back from this run's event log was not raised as a question, " +
87
97
  'and no decision was sent for it.';
88
98
  const REPLAYED_APPROVAL_LIST_UNREADABLE_KEY = 'hitl-replayed-approval-list-unreadable';
@@ -123,14 +133,6 @@ const RULE_NOT_SENT_REJECTED_TIMEOUT_MS = 10_000;
123
133
  export function surfaceRuleArmRejected(why) {
124
134
  surfaceSelfClearingWarn(RULE_NOT_SENT_REJECTED_KEY, ruleNotSentRejectedText(why), RULE_NOT_SENT_REJECTED_TIMEOUT_MS);
125
135
  }
126
- function isNoPendingError(e) {
127
- if (e instanceof HitlSafetyError)
128
- return e.code === 'no_pending';
129
- if (typeof e !== 'object' || e === null || !('code' in e))
130
- return false;
131
- const code = e.code;
132
- return typeof code === 'string' && code === 'no_pending';
133
- }
134
136
  export function observeCancelByDeny(settle, taskId) {
135
137
  let timer;
136
138
  const budget = new Promise((_, reject) => {
@@ -142,8 +144,8 @@ export function observeCancelByDeny(settle, taskId) {
142
144
  hostLog('debug', `[hitl-cancel-deny] cancel-by-deny settled for run ${taskId} (session unlocked)`);
143
145
  })
144
146
  .catch((e) => {
145
- if (isNoPendingError(e)) {
146
- hostLog('debug', `[hitl-cancel-deny] cancel-by-deny no_pending for run ${taskId} (benign — already resolved)`);
147
+ if (decisionRefusalSaysAskGone(e)) {
148
+ hostLog('debug', `[hitl-cancel-deny] cancel-by-deny found the question no longer pending for run ${taskId} (benign — settled elsewhere, parked or gone)`);
147
149
  return;
148
150
  }
149
151
  const rowNote = decideFailureNote(e, 'deny');
@@ -22,16 +22,26 @@ export type LivePendingReading = {
22
22
  dropped: number;
23
23
  };
24
24
  export declare function readLivePendingRows(body: unknown): LivePendingReading;
25
- export interface SuspendedAskFilter {
26
- sessionId?: string;
27
- }
28
- export declare function suspendedSubagentAsks(snapshot: ApprovalsFeedEmission | null | undefined, filter?: SuspendedAskFilter): LivePendingAskView[];
25
+ export type SuspendedAskFilter = {
26
+ readonly sessionId: string;
27
+ readonly allSessions?: never;
28
+ readonly identityPending?: never;
29
+ } | {
30
+ readonly allSessions: true;
31
+ readonly sessionId?: never;
32
+ readonly identityPending?: never;
33
+ } | {
34
+ readonly identityPending: true;
35
+ readonly sessionId?: never;
36
+ readonly allSessions?: never;
37
+ };
38
+ export declare function suspendedSubagentAsks(snapshot: ApprovalsFeedEmission | null | undefined, filter: SuspendedAskFilter): LivePendingAskView[];
29
39
  export interface ApprovalsAwaitingDecisionCount {
30
40
  durable: number | null;
31
41
  live: number | null;
32
42
  suspendedSubagent: number | null;
33
43
  }
34
- export declare function countApprovalsAwaitingDecision(snapshot: ApprovalsFeedEmission | null | undefined, filter?: SuspendedAskFilter): ApprovalsAwaitingDecisionCount;
44
+ export declare function countApprovalsAwaitingDecision(snapshot: ApprovalsFeedEmission | null | undefined, filter: SuspendedAskFilter): ApprovalsAwaitingDecisionCount;
35
45
  export declare function livePendingRowToApprovalFrame(row: LivePendingAskView): ToolApprovalFrame;
36
46
  export declare function surfaceSuspendedAskAndRespond(row: LivePendingAskView, respond: RespondToolApprovalFn, signal?: AbortSignal, lane?: ToolApprovalFrameLaneOpts): Promise<ToolApprovalFrameOutcome>;
37
47
  export interface SuspendedAskDelta {
@@ -45,4 +55,4 @@ export interface SuspendedAskTracker {
45
55
  requeue(approvalId: string): void;
46
56
  noteDecided(approvalId: string): void;
47
57
  }
48
- export declare function createSuspendedAskTracker(filter?: SuspendedAskFilter): SuspendedAskTracker;
58
+ export declare function createSuspendedAskTracker(filter: SuspendedAskFilter): SuspendedAskTracker;
@@ -1,3 +1,4 @@
1
+ import { THROWN_SLOT_UNREADABLE, readThrownSlot } from '../wireFailureShape.js';
1
2
  import { isToolApprovalFrame, surfaceToolApprovalFrameAndRespond, } from './toolApprovalWire.js';
2
3
  function nonEmptyString(v) {
3
4
  return typeof v === 'string' && v !== '';
@@ -69,20 +70,48 @@ export function readLivePendingRows(body) {
69
70
  return { kind: 'malformed' };
70
71
  return { kind: 'present', rows, dropped };
71
72
  }
72
- export function suspendedSubagentAsks(snapshot, filter) {
73
+ const IDENTITY_PENDING_SCOPE = Object.freeze({ kind: 'identity_pending' });
74
+ function suspendedAskScopeOf(filter) {
75
+ if (typeof filter !== 'object' || filter === null)
76
+ return IDENTITY_PENDING_SCOPE;
77
+ const sessionId = readThrownSlot(filter, 'sessionId', true);
78
+ const allSessions = readThrownSlot(filter, 'allSessions', true);
79
+ const identityPending = readThrownSlot(filter, 'identityPending', true);
80
+ if (sessionId === THROWN_SLOT_UNREADABLE || allSessions === THROWN_SLOT_UNREADABLE || identityPending === THROWN_SLOT_UNREADABLE)
81
+ return IDENTITY_PENDING_SCOPE;
82
+ const sessionOk = typeof sessionId === 'string' && sessionId !== '';
83
+ const allOk = allSessions === true;
84
+ const pendingOk = identityPending === true;
85
+ if ((sessionId !== undefined && !sessionOk) || (allSessions !== undefined && !allOk) || (identityPending !== undefined && !pendingOk))
86
+ return IDENTITY_PENDING_SCOPE;
87
+ if (sessionOk && !allOk && !pendingOk)
88
+ return { kind: 'session', sessionId };
89
+ if (allOk && !sessionOk && !pendingOk)
90
+ return { kind: 'all' };
91
+ return IDENTITY_PENDING_SCOPE;
92
+ }
93
+ function subagentAsksIn(snapshot, scope) {
94
+ if (scope.kind === 'identity_pending')
95
+ return [];
73
96
  if (snapshot?.kind === 'unknown')
74
97
  return [];
75
98
  const rows = snapshot?.livePending;
76
99
  if (!Array.isArray(rows))
77
100
  return [];
78
- return rows.filter(r => r.fromSubagent === true && (filter?.sessionId === undefined || r.sessionId === filter.sessionId));
101
+ return rows.filter(r => r.fromSubagent === true && (scope.kind === 'all' || r.sessionId === scope.sessionId));
102
+ }
103
+ export function suspendedSubagentAsks(snapshot, filter) {
104
+ return subagentAsksIn(snapshot, suspendedAskScopeOf(filter));
79
105
  }
80
106
  export function countApprovalsAwaitingDecision(snapshot, filter) {
107
+ const scope = suspendedAskScopeOf(filter);
108
+ if (scope.kind === 'identity_pending')
109
+ return { durable: null, live: null, suspendedSubagent: null };
81
110
  if (snapshot === null || snapshot === undefined)
82
111
  return { durable: null, live: null, suspendedSubagent: null };
83
112
  if (snapshot.kind === 'unknown')
84
113
  return { durable: null, live: null, suspendedSubagent: null };
85
- const bySession = (rows) => filter?.sessionId === undefined ? [...rows] : rows.filter(r => r.sessionId === filter.sessionId);
114
+ const bySession = (rows) => scope.kind === 'session' ? rows.filter(r => r.sessionId === scope.sessionId) : [...rows];
86
115
  const durable = (snapshot.pendingDropped ?? 0) > 0 ? null : Array.isArray(snapshot.pending) ? bySession(snapshot.pending).length : null;
87
116
  if (!Array.isArray(snapshot.livePending))
88
117
  return { durable, live: null, suspendedSubagent: null };
@@ -113,6 +142,7 @@ export function surfaceSuspendedAskAndRespond(row, respond, signal, lane) {
113
142
  }
114
143
  const TRACKER_UNSEEN_CLAIMS_MAX = 512;
115
144
  export function createSuspendedAskTracker(filter) {
145
+ const scope = suspendedAskScopeOf(filter);
116
146
  const shown = new Set();
117
147
  const shownWithFrame = new Set();
118
148
  const claimed = new Map();
@@ -137,7 +167,9 @@ export function createSuspendedAskTracker(filter) {
137
167
  ingest(snapshot) {
138
168
  if (snapshot?.kind === 'unknown')
139
169
  return { appeared: [], gone: [], upgraded: [] };
140
- const rows = suspendedSubagentAsks(snapshot, filter);
170
+ if (scope.kind === 'identity_pending')
171
+ return { appeared: [], gone: [], upgraded: [] };
172
+ const rows = subagentAsksIn(snapshot, scope);
141
173
  const present = new Set(rows.map(r => r.approvalId));
142
174
  const appeared = [];
143
175
  const upgraded = [];
@@ -1,3 +1,4 @@
1
+ import { wireFailureTextsOf } from '../wireFailureShape.js';
1
2
  const BASH_TOOL_NAME_FOR_RULES = 'Bash';
2
3
  export function parseLocalAllowRule(rule, expectedToolName, deps) {
3
4
  if (typeof rule !== 'string' || rule === '') {
@@ -8,7 +9,7 @@ export function parseLocalAllowRule(rule, expectedToolName, deps) {
8
9
  value = deps.parseRule(rule);
9
10
  }
10
11
  catch (e) {
11
- return { ok: false, error: `rule text did not parse (${String(e)})` };
12
+ return { ok: false, error: `rule text did not parse (${wireFailureTextsOf(e).reason})` };
12
13
  }
13
14
  if (typeof value.toolName !== 'string' || value.toolName === '') {
14
15
  return { ok: false, error: 'rule text carries no tool name' };
@@ -0,0 +1,9 @@
1
+ export type NoAllowCause = 'no_allow_rule' | 'ask_rule' | 'budget' | 'other';
2
+ export interface RuleLadderNoAllowFacts {
3
+ readonly allowed?: boolean;
4
+ readonly denied?: boolean;
5
+ readonly askRuleMatched?: boolean;
6
+ readonly budgetExhausted?: boolean;
7
+ readonly noRuleMatched?: boolean;
8
+ }
9
+ export declare function noAllowCauseOf(card: object | null | undefined, ladder: RuleLadderNoAllowFacts | null | undefined): NoAllowCause | undefined;
@@ -0,0 +1,26 @@
1
+ import { automaticAnswerVerdict } from './automaticAnswerVerdict.js';
2
+ function ladderSays(ladder, key) {
3
+ if (typeof ladder !== 'object' || ladder === null)
4
+ return false;
5
+ try {
6
+ const d = Object.getOwnPropertyDescriptor(ladder, key);
7
+ return d !== undefined && 'value' in d && d.value === true;
8
+ }
9
+ catch {
10
+ return false;
11
+ }
12
+ }
13
+ export function noAllowCauseOf(card, ladder) {
14
+ if (ladderSays(ladder, 'allowed') || ladderSays(ladder, 'denied'))
15
+ return undefined;
16
+ if (ladderSays(ladder, 'askRuleMatched'))
17
+ return 'ask_rule';
18
+ if (ladderSays(ladder, 'budgetExhausted'))
19
+ return 'budget';
20
+ const standing = automaticAnswerVerdict(card, 'standing_rule');
21
+ if (standing.kind === 'must_ask' && (standing.askClass === 'ask_rule' || standing.origin === 'ask_rule'))
22
+ return 'ask_rule';
23
+ if (ladderSays(ladder, 'noRuleMatched') && standing.kind === 'may_answer')
24
+ return 'no_allow_rule';
25
+ return 'other';
26
+ }
@@ -0,0 +1,19 @@
1
+ export type ApprovalCompleteDisposition = 'live-expired-parked' | 'live-expired-retract' | 'settled' | null;
2
+ export declare function classifyApprovalCompleteFrame(frame: unknown): ApprovalCompleteDisposition;
3
+ export type ParkRowDeadlineState = {
4
+ kind: 'none';
5
+ } | {
6
+ kind: 'pending';
7
+ deadlineMs: number;
8
+ remainingMs: number;
9
+ } | {
10
+ kind: 'past';
11
+ deadlineMs: number;
12
+ remainingMs: number;
13
+ };
14
+ export declare function parkRowDeadlineState(row: unknown, nowMs: number): ParkRowDeadlineState;
15
+ export declare function lateDecideRoute(o: {
16
+ windowClosed: boolean;
17
+ durableRowFound: boolean;
18
+ }): 'decide' | 'respond';
19
+ export declare function runReapedByDeadline(client: unknown, taskId: string): Promise<boolean>;
@@ -0,0 +1,46 @@
1
+ import { APPROVAL_EXPIRED } from '../engineErrorCodes.js';
2
+ import { approvalCompleteParked } from './approvalCompleteParked.js';
3
+ export function classifyApprovalCompleteFrame(frame) {
4
+ if (typeof frame !== 'object' || frame === null)
5
+ return null;
6
+ const f = frame;
7
+ if (f.type !== 'tool_approval_complete')
8
+ return null;
9
+ const outcome = f.outcome;
10
+ if (outcome === 'allowed' || outcome === 'denied')
11
+ return 'settled';
12
+ if (outcome !== 'expired')
13
+ return null;
14
+ return approvalCompleteParked(frame) ? 'live-expired-parked' : 'live-expired-retract';
15
+ }
16
+ const PARK_DEADLINE_MAX_SANE_MS = 24 * 60 * 60 * 1000;
17
+ export function parkRowDeadlineState(row, nowMs) {
18
+ if (typeof row !== 'object' || row === null)
19
+ return { kind: 'none' };
20
+ const raw = row.deadline;
21
+ if (typeof raw !== 'number' || !Number.isFinite(raw) || raw <= 0)
22
+ return { kind: 'none' };
23
+ const remainingMs = raw - nowMs;
24
+ if (remainingMs > PARK_DEADLINE_MAX_SANE_MS)
25
+ return { kind: 'none' };
26
+ return remainingMs > 0
27
+ ? { kind: 'pending', deadlineMs: raw, remainingMs }
28
+ : { kind: 'past', deadlineMs: raw, remainingMs };
29
+ }
30
+ export function lateDecideRoute(o) {
31
+ if (!o.windowClosed)
32
+ return 'respond';
33
+ return o.durableRowFound ? 'decide' : 'respond';
34
+ }
35
+ export async function runReapedByDeadline(client, taskId) {
36
+ try {
37
+ const runs = client?.runs;
38
+ if (typeof runs?.get !== 'function')
39
+ return false;
40
+ const rec = (await runs.get(taskId));
41
+ return rec?.errorCode === APPROVAL_EXPIRED;
42
+ }
43
+ catch {
44
+ return false;
45
+ }
46
+ }
@@ -1,7 +1,6 @@
1
1
  import type { AgentEvent } from '@sema-agent/sdk';
2
- import { type GateCurrentPending, type HitlFailureStage } from './hitlBridge.js';
2
+ import { type GateCurrentPending, type HitlFailureStage, type HitlSafetyCode } from './hitlBridge.js';
3
3
  import { type QuestionAnswer } from '../liveQuestionStore.js';
4
- import { type FsApprovalOutcome } from './toolApprovalWire.js';
5
4
  import type { AskAnsweredOutput, GateLedger } from './gateLedger.js';
6
5
  import { type AskGateWireDeps, type GatePark } from './frameRouter.js';
7
6
  import { type DecideReceiptView } from '../decideReceipt.js';
@@ -13,8 +12,7 @@ export interface HopBudget {
13
12
  }
14
13
  export declare function nextHopBudget(prev: HopBudget | undefined, round: HopRound): HopBudget;
15
14
  export declare const MAX_TOTAL_PARKS = 64;
16
- export declare const GATE_FAILURE_CODES: readonly ["no_pending", "binding_mismatch", "wrong_gate", "bad_plan_edit", "bad_plan_mode", "empty_answer"];
17
- export type GateFailureCode = (typeof GATE_FAILURE_CODES)[number];
15
+ export type GateFailureCode = HitlSafetyCode;
18
16
  export type GateOutcome = {
19
17
  kind: 'decided';
20
18
  gatedCallId?: string | undefined;
@@ -35,9 +33,7 @@ export type GateOutcome = {
35
33
  currentPending?: GateCurrentPending | undefined;
36
34
  };
37
35
  export declare function isAlreadyResolvedGateReason(reason: unknown): boolean;
38
- export declare function isAlreadyResolvedFailure(outcome: Extract<GateOutcome | FsApprovalOutcome, {
39
- kind: 'failed';
40
- }>): boolean;
36
+ export declare function isAlreadyResolvedFailure(failure: unknown): boolean;
41
37
  export declare function isGateStandingErrorCode(code: string | null | undefined, retriable?: boolean): boolean;
42
38
  export declare function isCodeClassifiedGateFailure(code: string | null | undefined, retriable?: boolean): boolean;
43
39
  export declare function toAnsweredOutput(questions: unknown[], answer: QuestionAnswer): AskAnsweredOutput;