@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,16 +1,12 @@
1
- import type { EngineAgentPanelAbsence, EngineAgentPanelEvent } from './engineAgentPanelStore.js';
2
- import { type PanelDelta, type PanelFrame, type PanelReduceState } from './panelReduce.js';
1
+ import { type PanelDelta, type PanelFact, type PanelFrame, type PanelReduceState } from './panelReduce.js';
3
2
  export declare function panelStateNow(): PanelReduceState;
4
3
  export declare function stepEnginePanel(frame: PanelFrame): void;
5
4
  export declare function replaceEnginePanelState(fn: (s: PanelReduceState) => PanelReduceState): void;
6
5
  export declare function clearEnginePanelIdentity(): void;
7
6
  export declare function clearEnginePanelAnchors(): void;
8
7
  export declare function resetEnginePanelHolder(): void;
9
- type Listener = (ev: EngineAgentPanelEvent) => void;
10
- export declare function subscribeLegacyEvents(fn: Listener): () => void;
11
- type AbsenceListener = (ev: EngineAgentPanelAbsence) => void;
12
- export declare function subscribeAbsence(fn: AbsenceListener): () => void;
13
- export declare function resetAbsenceChannel(): void;
8
+ type FactTap = (f: PanelFact) => void;
9
+ export declare function __tapEnginePanelFactsForTests(fn: FactTap): () => void;
14
10
  type RowListener = (d: PanelDelta) => void;
15
11
  export declare function subscribeRows(fn: RowListener): () => void;
16
12
  export declare function clearEnginePanelRows(): void;
@@ -1,4 +1,4 @@
1
- import { createPanelReduceState, isNewEngineAgentPanelCycle, panelClearAnchors, panelClearIdentity, panelClearRows, panelRowSnapshot, stepPanelFrame, } from './panelReduce.js';
1
+ import { createPanelReduceState, panelClearAnchors, panelClearIdentity, panelClearRows, panelRowSnapshot, stepPanelFrame, } from './panelReduce.js';
2
2
  let state = createPanelReduceState();
3
3
  export function panelStateNow() {
4
4
  return state;
@@ -8,13 +8,14 @@ export function stepEnginePanel(frame) {
8
8
  state = r.state;
9
9
  if (rowListener !== null)
10
10
  rowQueue.push(...r.deltas);
11
- for (const f of r.facts) {
12
- if (f.ch === 'event')
13
- deliverLegacyEvent(f.ev);
14
- else
15
- deliverAbsence(f.absence);
11
+ try {
12
+ if (factTap !== null)
13
+ for (const f of r.facts)
14
+ factTap(f);
15
+ }
16
+ finally {
17
+ drainRows();
16
18
  }
17
- drainRows();
18
19
  }
19
20
  export function replaceEnginePanelState(fn) {
20
21
  state = fn(state);
@@ -27,135 +28,18 @@ export function clearEnginePanelAnchors() {
27
28
  }
28
29
  export function resetEnginePanelHolder() {
29
30
  state = createPanelReduceState();
30
- listener = null;
31
- buffer.length = 0;
32
- absenceListener = null;
33
- absenceBuffer.clear();
34
31
  rowListener = null;
35
32
  rowQueue.length = 0;
33
+ factTap = null;
36
34
  }
37
- const MAX_BUFFER = 200;
38
- let listener = null;
39
- const buffer = [];
40
- function launchAnchorChanged(prev, next) {
41
- if (prev.kind !== 'fleet-row' || next.kind !== 'fleet-row')
42
- return false;
43
- return isNewEngineAgentPanelCycle(prev, next);
44
- }
45
- function deliverLegacyEvent(ev) {
46
- if (ev.kind !== 'sweep')
47
- absenceBuffer.delete(ev.taskId);
48
- if (listener) {
49
- try {
50
- listener(ev);
51
- }
52
- catch {
53
- }
54
- return;
55
- }
56
- if (ev.kind === 'sweep' && buffer.length > 0 && buffer[buffer.length - 1]?.kind === 'sweep')
57
- return;
58
- const progress = ev.kind === 'tick' || ev.kind === 'fleet-row';
59
- if (progress) {
60
- const kind = ev.kind;
61
- const taskId = ev.taskId;
62
- let i = -1;
63
- for (let at = buffer.length - 1; at >= 0; at--) {
64
- const b = buffer[at];
65
- if (b === undefined)
66
- continue;
67
- if (b.kind === 'sweep')
68
- break;
69
- if (b.kind === 'end') {
70
- if (b.taskId === taskId)
71
- break;
72
- continue;
73
- }
74
- if (b.taskId !== taskId)
75
- continue;
76
- if (b.kind === kind && !launchAnchorChanged(b, ev))
77
- i = at;
78
- break;
79
- }
80
- if (i >= 0) {
81
- const merged = { ...buffer[i], ...ev };
82
- buffer.splice(i, 1);
83
- buffer.push(merged);
84
- return;
85
- }
86
- }
87
- if (buffer.length < MAX_BUFFER) {
88
- buffer.push(ev);
89
- return;
90
- }
91
- const evictAt = buffer.findIndex(b => b.kind === 'tick' || b.kind === 'fleet-row');
92
- if (evictAt >= 0) {
93
- buffer.splice(evictAt, 1);
94
- buffer.push(ev);
95
- return;
96
- }
97
- buffer.shift();
98
- buffer.push(ev);
99
- }
100
- export function subscribeLegacyEvents(fn) {
101
- listener = fn;
102
- if (buffer.length > 0) {
103
- const pending = buffer.splice(0, buffer.length);
104
- for (const ev of pending) {
105
- try {
106
- fn(ev);
107
- }
108
- catch {
109
- }
110
- }
111
- }
112
- return () => {
113
- if (listener === fn)
114
- listener = null;
115
- };
116
- }
117
- const MAX_ABSENCE_BUFFER = 200;
118
- let absenceListener = null;
119
- const absenceBuffer = new Map();
120
- function deliverAbsence(ev) {
121
- if (absenceListener) {
122
- try {
123
- absenceListener(ev);
124
- }
125
- catch {
126
- }
127
- return;
128
- }
129
- absenceBuffer.delete(ev.taskId);
130
- absenceBuffer.set(ev.taskId, ev);
131
- if (absenceBuffer.size > MAX_ABSENCE_BUFFER) {
132
- const oldest = absenceBuffer.keys().next().value;
133
- if (oldest !== undefined)
134
- absenceBuffer.delete(oldest);
135
- }
136
- }
137
- export function subscribeAbsence(fn) {
138
- absenceListener = fn;
139
- if (absenceBuffer.size > 0) {
140
- const pending = [...absenceBuffer.values()];
141
- absenceBuffer.clear();
142
- for (const ev of pending) {
143
- try {
144
- fn(ev);
145
- }
146
- catch {
147
- }
148
- }
149
- }
35
+ let factTap = null;
36
+ export function __tapEnginePanelFactsForTests(fn) {
37
+ factTap = fn;
150
38
  return () => {
151
- if (absenceListener === fn)
152
- absenceListener = null;
39
+ if (factTap === fn)
40
+ factTap = null;
153
41
  };
154
42
  }
155
- export function resetAbsenceChannel() {
156
- absenceListener = null;
157
- absenceBuffer.clear();
158
- }
159
43
  let rowListener = null;
160
44
  const rowQueue = [];
161
45
  let rowDraining = false;
@@ -10,10 +10,6 @@ export type PeerLaneReading = {
10
10
  kind: 'present';
11
11
  };
12
12
  export declare function projectPeerLaneCapability(caps: unknown): PeerLaneReading | undefined;
13
- export declare function noteEngineCapsForPeerLane(baseUrl: string, caps: unknown, opts?: {
14
- generation?: number;
15
- }): void;
16
13
  export declare function observedPeerLane(baseUrl?: string | undefined): PeerLaneReading;
17
14
  export declare function peerLaneAvailable(reading: PeerLaneReading): 'yes' | 'no' | 'unknown';
18
15
  export declare function peerLaneDoctorDetail(reading: PeerLaneReading): string;
19
- export declare function __resetPeerLaneReadingsForTests(): void;
@@ -22,9 +22,6 @@ const reader = createEngineCapReader({
22
22
  name: 'peerLane',
23
23
  project: projectPeerLaneCapability,
24
24
  });
25
- export function noteEngineCapsForPeerLane(baseUrl, caps, opts) {
26
- reader.note(baseUrl, caps, opts);
27
- }
28
25
  export function observedPeerLane(baseUrl = engineWireTarget()?.baseUrl) {
29
26
  return reader.observed(baseUrl);
30
27
  }
@@ -49,6 +46,3 @@ export function peerLaneDoctorDetail(reading) {
49
46
  return 'cross-session lane on — this engine can discover and deliver across sessions for the same caller';
50
47
  }
51
48
  }
52
- export function __resetPeerLaneReadingsForTests() {
53
- reader.__resetForTests();
54
- }
@@ -2,6 +2,7 @@ import { capForDisplay, escapeDisplayControlChars } from './fleetTaskDesc.js';
2
2
  export const PERMISSION_RULE_ISSUE_CODES = Object.freeze([
3
3
  'invalid.empty_tool',
4
4
  'invalid.paren',
5
+ 'invalid.tool_name',
5
6
  'invalid.param_split',
6
7
  'invalid.primary_field',
7
8
  'invalid.cap_exceeded',
@@ -21,6 +22,7 @@ const ISSUE_MESSAGE_MAX = 200;
21
22
  const ISSUE_SENTENCES = Object.freeze({
22
23
  'invalid.empty_tool': 'this rule is invalid: it names no tool',
23
24
  'invalid.paren': 'this rule is invalid: its parentheses do not parse (escape a literal one as \\( or \\))',
25
+ 'invalid.tool_name': "this rule is invalid: its tool name is not spelled as a tool name (blanks around the rule, an invisible or disallowed character in the name or before the parenthesis, a leading '-', or the wildcard '*', which names no tool), so it would reach no tool or the wrong one",
24
26
  'invalid.param_split': 'this rule is invalid: its parentheses do not hold a parameter rule written name:pattern',
25
27
  'invalid.primary_field': "this rule is invalid: it patterns the tool's primary field, which matches the whole trimmed string rather than a prefix",
26
28
  'invalid.cap_exceeded': 'this rule set is invalid: it is over one of the deployment caps (rule count, rule length, pattern length, or star count); this client cannot tell which from the code alone',
@@ -1,3 +1,4 @@
1
+ import type { UiLanguage } from './env/uiLanguage.js';
1
2
  export type PermissionRulesWriteReading = {
2
3
  kind: 'unobserved';
3
4
  } | {
@@ -10,10 +11,6 @@ export type PermissionRulesWriteReading = {
10
11
  kind: 'present';
11
12
  };
12
13
  export declare function projectPermissionRulesWriteCapability(caps: unknown): PermissionRulesWriteReading | undefined;
13
- export declare function noteEngineCapsForPermissionRulesWrite(baseUrl: string, caps: unknown, opts?: {
14
- generation?: number;
15
- }): void;
16
14
  export declare function observedPermissionRulesWrite(baseUrl?: string | undefined): PermissionRulesWriteReading;
17
15
  export declare function permissionRulesWriteAvailable(reading: PermissionRulesWriteReading): boolean;
18
- export declare function permissionRulesWriteDoctorDetail(reading: PermissionRulesWriteReading): string;
19
- export declare function __resetPermissionRulesWriteReadingsForTests(): void;
16
+ export declare function permissionRulesWriteDoctorDetail(reading: PermissionRulesWriteReading, lang?: UiLanguage): string;
@@ -1,5 +1,6 @@
1
1
  import { engineWireTarget } from './engineWireTarget.js';
2
2
  import { createEngineCapReader, unreadableReadingDetail } from './engineCapReader.js';
3
+ import { msg, renderMessage } from './i18n/translate.js';
3
4
  import { ownDataField } from './ownKey.js';
4
5
  export function projectPermissionRulesWriteCapability(caps) {
5
6
  try {
@@ -22,29 +23,24 @@ const reader = createEngineCapReader({
22
23
  name: 'permissionRulesWrite',
23
24
  project: projectPermissionRulesWriteCapability,
24
25
  });
25
- export function noteEngineCapsForPermissionRulesWrite(baseUrl, caps, opts) {
26
- reader.note(baseUrl, caps, opts);
27
- }
28
26
  export function observedPermissionRulesWrite(baseUrl = engineWireTarget()?.baseUrl) {
29
27
  return reader.observed(baseUrl);
30
28
  }
31
29
  export function permissionRulesWriteAvailable(reading) {
32
30
  return reading.kind === 'present';
33
31
  }
34
- export function permissionRulesWriteDoctorDetail(reading) {
32
+ export function permissionRulesWriteDoctorDetail(reading, lang) {
33
+ const subject = msg('notice.capability.subject.permissionRulesWrite');
35
34
  switch (reading.kind) {
36
35
  case 'unreadable':
37
- return unreadableReadingDetail('permission-rule write entry');
36
+ return unreadableReadingDetail(renderMessage(subject, lang), lang);
38
37
  case 'unobserved':
39
- return 'permission-rule write entry not observed — the engine reports it on /v1/capabilities (permissionRulesWrite); this process has no usable capabilities reading cached for it (none received, the last one was unreadable, or the last one was discarded when the engine connection was reset; this process cannot tell which)';
38
+ return renderMessage(msg('notice.capability.unobserved', { subject, key: 'permissionRulesWrite' }), lang);
40
39
  case 'not_reported':
41
- return 'permission-rule write entry not reported by this engine — this binary predates the entry itself; hide it rather than calling it';
40
+ return renderMessage(msg('notice.capability.permissionRulesWrite.notReported'), lang);
42
41
  case 'absent':
43
- return 'permission-rule write entry unreachable for this call — either the rules lane is not open on this deployment, or this call cannot bring a verifiable identity; the engine reports one bit for both, so this client cannot tell which';
42
+ return renderMessage(msg('notice.capability.permissionRulesWrite.absent'), lang);
44
43
  case 'present':
45
- return 'permission-rule write entry reachable for this call — a per-call attempt still answers for itself whether the direction, text, and scope are accepted';
44
+ return renderMessage(msg('notice.capability.permissionRulesWrite.present'), lang);
46
45
  }
47
46
  }
48
- export function __resetPermissionRulesWriteReadingsForTests() {
49
- reader.__resetForTests();
50
- }
@@ -1,6 +1,6 @@
1
- import { type TaskRequestPermissionMode } from './taskRequestWords.js';
1
+ import type { PermissionMode } from '@sema-agent/sdk';
2
2
  import { type PermissionModesReading } from './permissionModesCapability.js';
3
- export type PermissionMode = TaskRequestPermissionMode;
3
+ export type { PermissionMode };
4
4
  export interface PermissionModeField {
5
5
  permissionMode?: PermissionMode;
6
6
  }
@@ -1,5 +1,7 @@
1
1
  import { PERMISSION_MODE_WORDS } from './taskRequestWords.js';
2
2
  import { permissionModeAdmitted } from './permissionModesCapability.js';
3
+ const _permissionModePin = true;
4
+ void _permissionModePin;
3
5
  const BIT_GATED_MODE = 'dontAsk';
4
6
  const KNOWN = new Set(PERMISSION_MODE_WORDS.filter((w) => w !== BIT_GATED_MODE));
5
7
  export function permissionModeField(mode, opts) {
@@ -10,12 +10,8 @@ export type PermissionsAllowGrantReading = {
10
10
  layer?: boolean;
11
11
  };
12
12
  export declare function projectPermissionsAllowGrantCapability(caps: unknown): PermissionsAllowGrantReading | undefined;
13
- export declare function noteEngineCapsForPermissionsAllowGrant(baseUrl: string, caps: unknown, opts?: {
14
- generation?: number;
15
- }): void;
16
13
  export declare function observedPermissionsAllowGrant(baseUrl?: string | undefined): PermissionsAllowGrantReading;
17
14
  export declare function permissionsAllowGrantAvailable(reading: PermissionsAllowGrantReading): boolean;
18
15
  export declare function allowWireForm(reading: PermissionsAllowGrantReading): 'layer' | 'grant' | 'off';
19
16
  export declare function allowRulesGate(reading: PermissionsAllowGrantReading, settingsRead: 'clean' | 'partial' | 'unreadable' | undefined): 'open' | 'capability_off' | 'settings_read_not_clean';
20
17
  export declare function permissionsAllowGrantDoctorDetail(reading: PermissionsAllowGrantReading, settingsRead?: 'clean' | 'partial' | 'unreadable'): string;
21
- export declare function __resetPermissionsAllowGrantReadingsForTests(): void;
@@ -36,9 +36,6 @@ const reader = createEngineCapReader({
36
36
  name: ALLOW_GRANT_CAP_PATH.join('.'),
37
37
  project: projectPermissionsAllowGrantCapability,
38
38
  });
39
- export function noteEngineCapsForPermissionsAllowGrant(baseUrl, caps, opts) {
40
- reader.note(baseUrl, caps, opts);
41
- }
42
39
  export function observedPermissionsAllowGrant(baseUrl = engineWireTarget()?.baseUrl) {
43
40
  return reader.observed(baseUrl);
44
41
  }
@@ -102,6 +99,3 @@ export function permissionsAllowGrantDoctorDetail(reading, settingsRead) {
102
99
  }
103
100
  return 'allow rules kept on this side — no usable capabilities reading is cached for this engine (none received, the last one was unreadable, or the last one was discarded when the engine connection was reset; this process cannot tell which), so allow rules are not sent and matching approvals are still answered here';
104
101
  }
105
- export function __resetPermissionsAllowGrantReadingsForTests() {
106
- reader.__resetForTests();
107
- }
@@ -38,20 +38,9 @@ export interface PermissionsRewrittenRule {
38
38
  to: string;
39
39
  bucket: 'deny' | 'ask' | 'allow';
40
40
  }
41
- export interface PermissionsUncheckedRule {
42
- rule: string;
43
- bucket: 'deny' | 'ask';
44
- }
45
- export interface PermissionsUnreachableRule {
46
- rule: string;
47
- bucket: 'deny' | 'ask';
48
- mintedPrefix?: string;
49
- }
50
41
  export interface PermissionsDeclarationReport extends PermissionsDeclaration {
51
42
  kept: PermissionsKeptRule[];
52
43
  rewritten: PermissionsRewrittenRule[];
53
- unchecked: PermissionsUncheckedRule[];
54
- unreachable: PermissionsUnreachableRule[];
55
44
  clientOwned?: PermissionsClientOwnedStatement[];
56
45
  }
57
46
  export interface PermissionsClientOwnedStatement {
@@ -1,8 +1,8 @@
1
1
  import { compileAllowList, hasCoreValuePort, protocolOf, ruleToolGrammarOf } from './coreValuePorts.js';
2
- import { clientOwnedServerPrefix, mintedPrefixOf, ruleToolNameVerdictOf } from './protocolSegment.js';
2
+ import { clientOwnedServerPrefix, ruleToolNameVerdictOf } from './protocolSegment.js';
3
3
  import { ruleCompileVerdict } from './ruleCompileVerdict.js';
4
4
  import { allowRulesGate, allowWireForm } from './permissionsAllowGrantCapability.js';
5
- import { THROWN_SLOT_UNREADABLE, readThrownSlot } from './wireFailureShape.js';
5
+ import { THROWN_SLOT_UNREADABLE, asAssemblyRefusal, readThrownSlot, withAssemblyRefusal } from './wireFailureShape.js';
6
6
  export const WIRE_RULE_TRUST_ORDER = Object.freeze([
7
7
  'policySettings',
8
8
  'cliArg',
@@ -65,16 +65,16 @@ function requireRulePorts() {
65
65
  const missing = required.filter((p) => !hasCoreValuePort(p));
66
66
  if (missing.length === 0)
67
67
  return;
68
- throw new Error(`permissionsDeclaration: 规则判据端口缺席(${missing.join(' / ')})—— 先用 installCoreValuePorts 装上 core 的同名实现。` +
69
- '缺席不等于全部合格:不判就发会让整份请求被引擎拒收,不判就删会静默丢掉 deny 规则,所以这里拒绝装配。');
68
+ throw withAssemblyRefusal(new Error(`permissionsDeclaration: 规则判据端口缺席(${missing.join(' / ')})—— 先用 installCoreValuePorts 装上 core 的同名实现。` +
69
+ '缺席不等于全部合格:不判就发会让整份请求被引擎拒收,不判就删会静默丢掉 deny 规则,所以这里拒绝装配。'), 'ports_missing');
70
70
  }
71
71
  function nameCheck(name) {
72
72
  if (name.includes('('))
73
73
  return { issue: 'paren_in_tool_name' };
74
74
  const verdict = ruleToolNameVerdictOf(name);
75
75
  if (verdict.kind === 'unknown') {
76
- throw new Error('permissionsDeclaration: 规则工具名判官(judgeRuleToolName)答不上来(抛 / 回的不是 current · retired · unprefixed_namespace · unmintable_segment 之一)—— ' +
77
- '装的必须是 core 的同名实现、原样装。判不出不等于够得着:不判就发会让整份请求被引擎拒收,不判就删会静默丢掉 deny 规则,所以这里拒绝装配。');
76
+ throw withAssemblyRefusal(new Error('permissionsDeclaration: 规则工具名判官(judgeRuleToolName)答不上来(抛 / 回的不是 current · retired · unprefixed_namespace · unmintable_segment 之一)—— ' +
77
+ '装的必须是 core 的同名实现、原样装。判不出不等于够得着:不判就发会让整份请求被引擎拒收,不判就删会静默丢掉 deny 规则,所以这里拒绝装配。'), 'judge_unanswerable');
78
78
  }
79
79
  if (verdict.kind === 'retired')
80
80
  return { retired: verdict.currentName !== undefined ? { currentName: verdict.currentName } : {} };
@@ -83,10 +83,8 @@ function nameCheck(name) {
83
83
  const ns = protocolOf(name);
84
84
  if (ns !== undefined && ns.parse(name) === undefined)
85
85
  return { issue: 'incomplete_protocol_name' };
86
- if (verdict.kind === 'unmintable_segment') {
87
- const minted = mintedPrefixOf(name);
88
- return { unminted: minted !== undefined ? { minted } : {} };
89
- }
86
+ if (verdict.kind === 'unmintable_segment')
87
+ return { unminted: true };
90
88
  return { ok: true };
91
89
  }
92
90
  function wholeServerRuleName(name) {
@@ -107,8 +105,14 @@ function compileRefused(verdict) {
107
105
  ...(verdict.message !== undefined ? { message: verdict.message } : {}),
108
106
  };
109
107
  }
110
- function sentFate(wire, check, unchecked) {
111
- return 'unminted' in check ? { sent: true, wire, unchecked, unreachable: check.unminted } : { sent: true, wire, unchecked };
108
+ function tighteningWholeName(name, check) {
109
+ if (!('retired' in check))
110
+ return name;
111
+ const successor = check.retired.currentName;
112
+ if (successor === undefined)
113
+ return name;
114
+ const next = nameCheck(successor);
115
+ return 'retired' in next || 'issue' in next ? name : successor;
112
116
  }
113
117
  function judgeList(rules, behavior, allowForm = 'grant') {
114
118
  let portsChecked = false;
@@ -121,46 +125,37 @@ function judgeList(rules, behavior, allowForm = 'grant') {
121
125
  }
122
126
  const parsed = parseRule(rule);
123
127
  if (parsed.ruleContent === undefined) {
124
- let name = wholeServerRuleName(parsed.toolName);
125
- let check = nameCheck(name);
126
- if ('retired' in check) {
127
- const successor = check.retired.currentName;
128
- if (behavior === 'allow' || successor === undefined)
129
- return kept('retired_tool_name');
130
- name = successor;
131
- check = nameCheck(name);
132
- if ('retired' in check)
133
- return kept('retired_tool_name');
134
- }
128
+ const name = wholeServerRuleName(parsed.toolName);
129
+ const check = nameCheck(name);
130
+ if (behavior !== 'allow')
131
+ return { sent: true, wire: tighteningWholeName(name, check) };
132
+ if ('retired' in check)
133
+ return kept('retired_tool_name');
135
134
  if ('issue' in check)
136
135
  return kept(check.issue);
137
- if (behavior === 'allow' && 'unminted' in check)
136
+ if ('unminted' in check)
138
137
  return kept('unminted_protocol_segment');
139
- const verdict = compileVerdict(name, behavior === 'ask' ? 'ask' : 'deny');
138
+ const verdict = compileVerdict(name, 'deny');
140
139
  if (verdict.kind === 'refused')
141
140
  return compileRefused(verdict);
142
- if (verdict.kind === 'unknown' && behavior === 'allow')
141
+ if (verdict.kind === 'unknown')
143
142
  return kept('judge_failed');
144
- return behavior === 'allow' ? { sent: true, wire: name, unchecked: false } : sentFate(name, check, verdict.kind === 'unknown');
143
+ return { sent: true, wire: name };
145
144
  }
146
145
  const check = nameCheck(parsed.toolName);
146
+ if (behavior !== 'allow')
147
+ return { sent: true, wire: rule };
147
148
  if ('retired' in check)
148
149
  return kept('retired_tool_name');
149
150
  if ('issue' in check)
150
151
  return kept(check.issue);
151
152
  if (ruleToolGrammarOf(parsed.toolName) === 'path' && parsed.ruleContent.startsWith('~/'))
152
153
  return kept('home_relative_path');
153
- if (behavior === 'allow') {
154
- if (allowForm !== 'layer')
155
- return kept('content_form_not_grantable');
156
- if ('unminted' in check)
157
- return kept('unminted_protocol_segment');
158
- return { sent: true, wire: rule, unchecked: false };
159
- }
160
- const verdict = compileVerdict(rule, behavior);
161
- if (verdict.kind === 'refused')
162
- return compileRefused(verdict);
163
- return sentFate(rule, check, verdict.kind === 'unknown');
154
+ if (allowForm !== 'layer')
155
+ return kept('content_form_not_grantable');
156
+ if ('unminted' in check)
157
+ return kept('unminted_protocol_segment');
158
+ return { sent: true, wire: rule };
164
159
  });
165
160
  }
166
161
  function outsideSettingsFiles(origin) {
@@ -269,24 +264,25 @@ function clientOwnedFate(server) {
269
264
  return judgeList([`${prefix}*`], 'allow')[0];
270
265
  }
271
266
  const WHO = 'permissionsDeclaration';
267
+ const malformed = (sentence) => withAssemblyRefusal(new TypeError(sentence), 'input_malformed');
272
268
  function ownField(obj, key, where) {
273
269
  if (Object.hasOwn(obj, key))
274
270
  return obj[key];
275
271
  if (key in obj)
276
- throw new TypeError(`${WHO}: ${where}${key} 只在原型链上,不是自有字段 —— 拒绝读取(请交普通对象)。`);
272
+ throw malformed(`${WHO}: ${where}${key} 只在原型链上,不是自有字段 —— 拒绝读取(请交普通对象)。`);
277
273
  return undefined;
278
274
  }
279
275
  function ruleList(v, key) {
280
276
  if (v === undefined || v === null)
281
277
  return undefined;
282
278
  if (!Array.isArray(v))
283
- throw new TypeError(`${WHO}: ${key} 必须是规则串数组或缺席 —— 收到 typeof=${typeof v}。`);
279
+ throw malformed(`${WHO}: ${key} 必须是规则串数组或缺席 —— 收到 typeof=${typeof v}。`);
284
280
  const out = [];
285
281
  const n = v.length;
286
282
  for (let i = 0; i < n; i++) {
287
283
  if (!Object.hasOwn(v, i)) {
288
284
  if (i in v)
289
- throw new TypeError(`${WHO}: ${key}[${i}] 是空洞,而原型链上在这个下标有值 —— 拒绝读取(请交不带空洞的普通数组)。`);
285
+ throw malformed(`${WHO}: ${key}[${i}] 是空洞,而原型链上在这个下标有值 —— 拒绝读取(请交不带空洞的普通数组)。`);
290
286
  continue;
291
287
  }
292
288
  const r = v[i];
@@ -302,7 +298,7 @@ function originMap(v, key) {
302
298
  typeof v.get === 'function' &&
303
299
  typeof v[Symbol.iterator] === 'function';
304
300
  if (!ok)
305
- throw new TypeError(`${WHO}: origins.${key} 必须是 Map(规则原串 → 来源)或缺席 —— 收到 typeof=${typeof v}。`);
301
+ throw malformed(`${WHO}: origins.${key} 必须是 Map(规则原串 → 来源)或缺席 —— 收到 typeof=${typeof v}。`);
306
302
  const snap = new Map();
307
303
  for (const entry of v) {
308
304
  const [r, origin] = entry;
@@ -313,8 +309,23 @@ function originMap(v, key) {
313
309
  }
314
310
  const slotsOf = (list, name) => (list ?? []).map((rule, at) => ({ rule, list: name, at }));
315
311
  function assemble(input, caps) {
312
+ let read;
313
+ try {
314
+ read = readAssemblyInput(input, caps);
315
+ }
316
+ catch (e) {
317
+ throw asAssemblyRefusal(e, 'input_malformed', WHO);
318
+ }
319
+ try {
320
+ return judgeAssembly(read, caps);
321
+ }
322
+ catch (e) {
323
+ throw asAssemblyRefusal(e, 'judge_unanswerable', WHO);
324
+ }
325
+ }
326
+ function readAssemblyInput(input, caps) {
316
327
  if (input === null || typeof input !== 'object' || Array.isArray(input)) {
317
- throw new TypeError(`${WHO}: 入参必须是对象 —— 收到 ${input === null ? 'null' : Array.isArray(input) ? 'array' : `typeof=${typeof input}`}。`);
328
+ throw malformed(`${WHO}: 入参必须是对象 —— 收到 ${input === null ? 'null' : Array.isArray(input) ? 'array' : `typeof=${typeof input}`}。`);
318
329
  }
319
330
  const deny = ruleList(ownField(input, 'deny', ''), 'deny');
320
331
  const ask = ruleList(ownField(input, 'ask', ''), 'ask');
@@ -325,7 +336,7 @@ function assemble(input, caps) {
325
336
  let origins = {};
326
337
  if (originsRaw !== undefined && originsRaw !== null) {
327
338
  if (typeof originsRaw !== 'object' || Array.isArray(originsRaw)) {
328
- throw new TypeError(`${WHO}: origins 必须是 { deny?, ask?, allow? } 对象或缺席 —— 收到 typeof=${typeof originsRaw}。`);
339
+ throw malformed(`${WHO}: origins 必须是 { deny?, ask?, allow? } 对象或缺席 —— 收到 typeof=${typeof originsRaw}。`);
329
340
  }
330
341
  const od = originMap(ownField(originsRaw, 'deny', 'origins.'), 'deny');
331
342
  const oa = originMap(ownField(originsRaw, 'ask', 'origins.'), 'ask');
@@ -333,6 +344,10 @@ function assemble(input, caps) {
333
344
  origins = { ...(od ? { deny: od } : {}), ...(oa ? { ask: oa } : {}), ...(ol ? { allow: ol } : {}) };
334
345
  }
335
346
  const gate = allowRulesGate(caps, ownField(input, 'settingsRead', ''));
347
+ return { deny, ask, allow, cliDeny, ownedServers, origins, gate };
348
+ }
349
+ function judgeAssembly(read, caps) {
350
+ const { deny, ask, allow, cliDeny, ownedServers, origins, gate } = read;
336
351
  const cliSlots = slotsOf(cliDeny, 'cliDeny');
337
352
  const cli = cliDeny === undefined ? undefined : { slots: cliSlots, fates: judgeList(cliDeny, 'deny') };
338
353
  const denySlots = slotsOf(deny, 'deny');
@@ -361,8 +376,6 @@ function assemble(input, caps) {
361
376
  buckets.allow = [...allowJ.sent];
362
377
  const keptRows = [];
363
378
  const rewritten = [];
364
- const unchecked = [];
365
- const unreachable = [];
366
379
  const rows = [
367
380
  ['deny', [...denySlots, ...cliSlots], denyJ],
368
381
  ['ask', askSlots, askJ],
@@ -392,15 +405,9 @@ function assemble(input, caps) {
392
405
  continue;
393
406
  if (winner.rule !== wire)
394
407
  rewritten.push({ from: winner.rule, to: wire, bucket });
395
- const f = (winner.list === 'cliDeny' ? j.fates[denySlots.length + winner.at] : j.fates[winner.at]);
396
- if (f.sent && f.unchecked && bucket !== 'allow')
397
- unchecked.push({ rule: wire, bucket });
398
- if (f.sent && f.unreachable !== undefined && bucket !== 'allow') {
399
- unreachable.push({ rule: wire, bucket, ...(f.unreachable.minted !== undefined ? { mintedPrefix: f.unreachable.minted } : {}) });
400
- }
401
408
  }
402
409
  }
403
- return { buckets, report: { kept: keptRows, rewritten, unchecked, unreachable, ...(clientOwned.length > 0 ? { clientOwned } : {}) } };
410
+ return { buckets, report: { kept: keptRows, rewritten, ...(clientOwned.length > 0 ? { clientOwned } : {}) } };
404
411
  }
405
412
  export function permissionsDeclaration(input, caps) {
406
413
  const { buckets } = assemble(input, caps);