@sema-agent/client-core 0.98.0 → 0.100.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 (236) hide show
  1. package/CHANGELOG.md +376 -0
  2. package/README.md +61 -35
  3. package/dist/adapt/arms.js +120 -55
  4. package/dist/adapt/panelTasks.d.ts +3 -2
  5. package/dist/adapt/panelTasks.js +34 -11
  6. package/dist/adapt/textStream.d.ts +1 -1
  7. package/dist/adapt/textStream.js +51 -28
  8. package/dist/adapter/activeRunSelfHeal.d.ts +11 -3
  9. package/dist/adapter/activeRunSelfHeal.js +210 -294
  10. package/dist/adapter/downstream/eventToSdkMessage.d.ts +25 -6
  11. package/dist/adapter/downstream/eventToSdkMessage.js +176 -12
  12. package/dist/adapter/downstream/terminalToSdkResult.js +10 -0
  13. package/dist/adapter/downstream/wiringManifestView.d.ts +3 -1
  14. package/dist/adapter/downstream/wiringManifestView.js +1 -0
  15. package/dist/adapter/runStream.js +82 -40
  16. package/dist/adapter/types.d.ts +2 -0
  17. package/dist/adapter/types.js +2 -1
  18. package/dist/agentSession/engineSessionBackgroundStop.js +16 -8
  19. package/dist/agentsWireCaps.d.ts +7 -3
  20. package/dist/agentsWireCaps.js +133 -39
  21. package/dist/cloudConfigWireCaps.d.ts +10 -1
  22. package/dist/cloudConfigWireCaps.js +181 -65
  23. package/dist/compactionStatus.d.ts +34 -0
  24. package/dist/compactionStatus.js +196 -0
  25. package/dist/controlRouter.d.ts +4 -2
  26. package/dist/controlRouter.js +39 -51
  27. package/dist/coreValuePorts.d.ts +26 -1
  28. package/dist/coreValuePorts.js +10 -0
  29. package/dist/corruptSessionCopy.d.ts +2 -1
  30. package/dist/corruptSessionCopy.js +3 -3
  31. package/dist/decideFailureNote.js +3 -3
  32. package/dist/declared/supportFloorDeclared.js +1 -1
  33. package/dist/detachWire.js +3 -2
  34. package/dist/devicesFace.d.ts +34 -0
  35. package/dist/devicesFace.js +90 -0
  36. package/dist/displayUntrusted.d.ts +1 -0
  37. package/dist/displayUntrusted.js +153 -5
  38. package/dist/engineAgentPanelStore.d.ts +14 -4
  39. package/dist/engineAgentPanelStore.js +14 -0
  40. package/dist/engineCapReader.d.ts +2 -1
  41. package/dist/engineCapReader.js +7 -5
  42. package/dist/engineCapsCache.d.ts +8 -0
  43. package/dist/engineCapsCache.js +59 -6
  44. package/dist/engineCapsChange.d.ts +2 -0
  45. package/dist/engineCapsChange.js +9 -0
  46. package/dist/engineErrorCodes.d.ts +11 -2
  47. package/dist/engineErrorCodes.js +11 -12
  48. package/dist/engineRowRef.js +4 -0
  49. package/dist/engineSessionMessages.d.ts +1 -0
  50. package/dist/engineSessionMessages.js +7 -1
  51. package/dist/engineTargetSeat.d.ts +27 -0
  52. package/dist/engineTargetSeat.js +199 -0
  53. package/dist/engineToolDirectory.d.ts +3 -0
  54. package/dist/engineToolDirectory.js +4 -2
  55. package/dist/engineWireFor.js +3 -8
  56. package/dist/env/uiLanguage.d.ts +2 -1
  57. package/dist/env/uiLanguage.js +3 -2
  58. package/dist/eventLeg.d.ts +7 -5
  59. package/dist/eventLeg.js +68 -49
  60. package/dist/fileHistoryCaptureCapability.d.ts +2 -4
  61. package/dist/fileHistoryCaptureCapability.js +12 -22
  62. package/dist/fileHistoryLegNotice.d.ts +2 -1
  63. package/dist/fileHistoryLegNotice.js +3 -3
  64. package/dist/frameBinding.d.ts +3 -0
  65. package/dist/frameBinding.js +12 -0
  66. package/dist/gateOutcome.js +16 -2
  67. package/dist/gateVocabulary.d.ts +8 -7
  68. package/dist/gateVocabulary.js +71 -73
  69. package/dist/generated/engineFactTables.d.ts +18 -1
  70. package/dist/generated/engineFactTables.js +56 -0
  71. package/dist/generated/engineNoticeTables.js +12 -3
  72. package/dist/generated/settingsSchemaFns.d.ts +18 -0
  73. package/dist/generated/settingsSchemaFns.js +70 -0
  74. package/dist/generated/settingsSchemaHooksClassifier.d.ts +2 -0
  75. package/dist/generated/settingsSchemaHooksClassifier.js +254 -0
  76. package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -0
  77. package/dist/generated/settingsSchemaMcpRequestEntry.js +162 -0
  78. package/dist/generated/settingsSchemaTables.d.ts +2 -0
  79. package/dist/generated/settingsSchemaTables.js +9 -0
  80. package/dist/generated/settingsSchemaTypes.d.ts +133 -0
  81. package/dist/generated/settingsSchemaTypes.js +1 -0
  82. package/dist/hitl/allowRuleShadow.d.ts +2 -1
  83. package/dist/hitl/allowRuleShadow.js +18 -15
  84. package/dist/hitl/approvalCardReasons.d.ts +3 -2
  85. package/dist/hitl/approvalCardReasons.js +29 -30
  86. package/dist/hitl/approvalHolds.d.ts +17 -0
  87. package/dist/hitl/approvalHolds.js +114 -29
  88. package/dist/hitl/askClassPair.d.ts +2 -2
  89. package/dist/hitl/askClassPair.js +16 -0
  90. package/dist/hitl/askGateWire.js +2 -1
  91. package/dist/hitl/askSettlementLine.d.ts +14 -4
  92. package/dist/hitl/askSettlementLine.js +67 -47
  93. package/dist/hitl/attributionLadder.d.ts +23 -0
  94. package/dist/hitl/attributionLadder.js +67 -0
  95. package/dist/hitl/automaticAnswerVerdict.d.ts +2 -1
  96. package/dist/hitl/automaticAnswerVerdict.js +8 -8
  97. package/dist/hitl/crashConvergedNotice.d.ts +5 -4
  98. package/dist/hitl/crashConvergedNotice.js +28 -41
  99. package/dist/hitl/decisionLedger.d.ts +55 -0
  100. package/dist/hitl/decisionLedger.js +156 -0
  101. package/dist/hitl/decisionRefusal.d.ts +1 -0
  102. package/dist/hitl/decisionRefusal.js +1 -1
  103. package/dist/hitl/decisionSend.d.ts +113 -0
  104. package/dist/hitl/decisionSend.js +579 -0
  105. package/dist/hitl/frameRouter.js +7 -8
  106. package/dist/hitl/hitlBridge.d.ts +1 -0
  107. package/dist/hitl/hitlBridge.js +21 -9
  108. package/dist/hitl/persistedRulesWire.d.ts +6 -5
  109. package/dist/hitl/persistedRulesWire.js +55 -73
  110. package/dist/hitl/planReviewWire.d.ts +5 -0
  111. package/dist/hitl/planReviewWire.js +53 -76
  112. package/dist/hitl/sessionPolicyDeliverable.d.ts +2 -0
  113. package/dist/hitl/sessionPolicyDeliverable.js +49 -9
  114. package/dist/hitl/sessionPolicyWire.d.ts +2 -1
  115. package/dist/hitl/sessionPolicyWire.js +23 -24
  116. package/dist/hitl/suspendedReopen.d.ts +2 -1
  117. package/dist/hitl/suspendedReopen.js +7 -10
  118. package/dist/hitl/toolApprovalWire.d.ts +17 -5
  119. package/dist/hitl/toolApprovalWire.js +120 -147
  120. package/dist/hooksWireCaps.js +145 -56
  121. package/dist/host.d.ts +21 -0
  122. package/dist/hostTurnSettings.d.ts +110 -0
  123. package/dist/hostTurnSettings.js +692 -0
  124. package/dist/humanTurn.d.ts +15 -1
  125. package/dist/humanTurn.js +100 -12
  126. package/dist/humanTurnRead.d.ts +2 -0
  127. package/dist/humanTurnRead.js +22 -1
  128. package/dist/i18n/messages.en.d.ts +713 -0
  129. package/dist/i18n/messages.en.js +713 -0
  130. package/dist/i18n/messages.zh.js +854 -1
  131. package/dist/index.d.ts +45 -13
  132. package/dist/index.js +27 -9
  133. package/dist/inheritEnvCapability.d.ts +4 -2
  134. package/dist/inheritEnvCapability.js +12 -5
  135. package/dist/inheritEnvWire.d.ts +3 -2
  136. package/dist/inheritEnvWire.js +14 -16
  137. package/dist/injectionLaneNotice.d.ts +5 -0
  138. package/dist/injectionLaneNotice.js +46 -0
  139. package/dist/interactiveHalt.js +17 -6
  140. package/dist/liveModelCatalog.d.ts +2 -1
  141. package/dist/liveModelCatalog.js +14 -8
  142. package/dist/mcpPanel.d.ts +10 -1
  143. package/dist/mcpPanel.js +42 -13
  144. package/dist/mcpProbeCapability.d.ts +2 -1
  145. package/dist/mcpProbeCapability.js +7 -11
  146. package/dist/mcpProbeWire.d.ts +3 -1
  147. package/dist/mcpProbeWire.js +5 -0
  148. package/dist/mcpReconnect.js +2 -2
  149. package/dist/mcpToolToggles.d.ts +6 -0
  150. package/dist/mcpToolToggles.js +46 -0
  151. package/dist/mcpWireCaps.d.ts +43 -3
  152. package/dist/mcpWireCaps.js +194 -59
  153. package/dist/mcpWireTransport.d.ts +4 -0
  154. package/dist/mcpWireTransport.js +18 -0
  155. package/dist/memoryEntriesWire.js +5 -10
  156. package/dist/model/onboardJudgement.d.ts +93 -0
  157. package/dist/model/onboardJudgement.js +415 -0
  158. package/dist/model/tierVocabulary.d.ts +2 -0
  159. package/dist/model/tierVocabulary.js +17 -5
  160. package/dist/modelCapabilityProbe.d.ts +65 -0
  161. package/dist/modelCapabilityProbe.js +601 -0
  162. package/dist/modelIdentityResolvability.d.ts +5 -0
  163. package/dist/modelIdentityResolvability.js +49 -22
  164. package/dist/ownKey.d.ts +33 -0
  165. package/dist/ownKey.js +109 -0
  166. package/dist/panelReduce.d.ts +11 -1
  167. package/dist/panelReduce.js +95 -16
  168. package/dist/panelStateHolder.d.ts +1 -0
  169. package/dist/panelStateHolder.js +10 -1
  170. package/dist/permissionRuleIssue.d.ts +2 -1
  171. package/dist/permissionRuleIssue.js +23 -20
  172. package/dist/permissionRulesWriteCapability.d.ts +2 -1
  173. package/dist/permissionRulesWriteCapability.js +8 -6
  174. package/dist/pluginHooksWire.d.ts +46 -3
  175. package/dist/pluginHooksWire.js +220 -12
  176. package/dist/prepareRefusal.d.ts +8 -0
  177. package/dist/prepareRefusal.js +72 -0
  178. package/dist/printModelStatus.d.ts +63 -0
  179. package/dist/printModelStatus.js +155 -0
  180. package/dist/request/taskRequest.d.ts +16 -10
  181. package/dist/request/taskRequest.js +195 -58
  182. package/dist/resumeRefusalCopy.d.ts +14 -9
  183. package/dist/resumeRefusalCopy.js +89 -144
  184. package/dist/retryStatus.d.ts +55 -0
  185. package/dist/retryStatus.js +155 -19
  186. package/dist/ruleRefusalSentence.d.ts +4 -0
  187. package/dist/ruleRefusalSentence.js +58 -0
  188. package/dist/sandboxWire.d.ts +2 -1
  189. package/dist/sandboxWire.js +55 -21
  190. package/dist/scenarioRefusal.d.ts +10 -0
  191. package/dist/scenarioRefusal.js +111 -0
  192. package/dist/seam.d.ts +48 -9
  193. package/dist/seam.js +54 -5
  194. package/dist/seatContract.d.ts +272 -14
  195. package/dist/seatContract.js +711 -23
  196. package/dist/selfOrchestrationDenial.js +7 -19
  197. package/dist/sessionIdSegment.d.ts +6 -0
  198. package/dist/sessionIdSegment.js +24 -0
  199. package/dist/sessionMemoryStatus.js +6 -11
  200. package/dist/sessionPolicyCapability.d.ts +2 -1
  201. package/dist/sessionPolicyCapability.js +8 -6
  202. package/dist/settingsCredentialKeyPaths.d.ts +8 -0
  203. package/dist/settingsCredentialKeyPaths.js +219 -0
  204. package/dist/settingsHooksSalvage.d.ts +44 -0
  205. package/dist/settingsHooksSalvage.js +211 -0
  206. package/dist/skillToolListsCapability.d.ts +2 -1
  207. package/dist/skillToolListsCapability.js +8 -6
  208. package/dist/skillsWireCaps.d.ts +0 -3
  209. package/dist/skillsWireCaps.js +1 -2
  210. package/dist/sseIdleTriage.js +3 -2
  211. package/dist/subagent/engineSubagentResume.js +15 -9
  212. package/dist/subagentContentStore.d.ts +4 -0
  213. package/dist/subagentContentStore.js +157 -27
  214. package/dist/toolHistoryMismatch.js +3 -2
  215. package/dist/toolRoster.d.ts +3 -2
  216. package/dist/toolRoster.js +21 -20
  217. package/dist/toolsFlagNames.d.ts +8 -0
  218. package/dist/toolsFlagNames.js +110 -0
  219. package/dist/turnFailurePresentation.d.ts +12 -1
  220. package/dist/turnFailurePresentation.js +220 -15
  221. package/dist/usageAnalytics.js +6 -11
  222. package/dist/userAttachmentEnvelope.d.ts +1 -0
  223. package/dist/userAttachmentEnvelope.js +37 -7
  224. package/dist/userAttachmentSeat.d.ts +21 -0
  225. package/dist/userAttachmentSeat.js +75 -0
  226. package/dist/userInvokedSkillsCapability.d.ts +11 -1
  227. package/dist/userInvokedSkillsCapability.js +31 -7
  228. package/dist/wireErrorTriage.d.ts +7 -0
  229. package/dist/wireErrorTriage.js +23 -1
  230. package/dist/wireFailureShape.js +2 -1
  231. package/dist/wireRefusalCopy.d.ts +62 -16
  232. package/dist/wireRefusalCopy.js +307 -148
  233. package/dist/workflowsJournalCapability.d.ts +2 -1
  234. package/dist/workflowsJournalCapability.js +8 -6
  235. package/docs/INTEGRATION-CLIENTS.md +951 -42
  236. package/package.json +5 -5
@@ -1,8 +1,11 @@
1
1
  import { CONFIG_LEGACY_TOOL_NAME } from '../engineErrorCodes.js';
2
2
  import { rosterMountedNames } from '../rosterMountedNames.js';
3
3
  import { ruleCompileVerdict } from '../ruleCompileVerdict.js';
4
+ import { readRuleEntry } from '../coreValuePorts.js';
5
+ import { readOwnDataValue } from '../ownKey.js';
4
6
  import { ruleToolNameVerdictOf } from '../protocolSegment.js';
5
- import { PREFIXES_IN_PROSE, REFUSED_NAME_CLASSES, REFUSED_NAME_FIX } from './refusedToolNameProse.js';
7
+ import { PREFIXES_IN_PROSE, REFUSED_NAME_FIX } from './refusedToolNameProse.js';
8
+ import { prepareRefusalNoteOf } from '../prepareRefusal.js';
6
9
  import { CORE_PROTOCOL_PREFIXES } from '../generated/toolNameTables.js';
7
10
  const COVERING_NAMESPACE_PREFIXES = CORE_PROTOCOL_PREFIXES;
8
11
  const WITHHELD_NOTICE = {
@@ -90,8 +93,9 @@ export function sessionPolicyDeliverable(behavior, rules, opts) {
90
93
  continue;
91
94
  }
92
95
  let why = withheldWhyOf(r);
96
+ const engineAsked = why === undefined;
93
97
  let currentName;
94
- if (why === undefined) {
98
+ if (engineAsked) {
95
99
  const verdict = ruleToolNameVerdictOf(r);
96
100
  if (verdict.kind === 'unknown')
97
101
  return unreadable();
@@ -103,6 +107,17 @@ export function sessionPolicyDeliverable(behavior, rules, opts) {
103
107
  else if (verdict.kind === 'unmintable_segment')
104
108
  why = 'not_a_tool_name';
105
109
  }
110
+ let inertReason;
111
+ if (engineAsked) {
112
+ const reading = entryReadingOf(r);
113
+ if (reading === 'unknown')
114
+ return unreadable();
115
+ if (reading !== 'row') {
116
+ inertReason = reading.reason;
117
+ if (why === undefined)
118
+ why = reading.why;
119
+ }
120
+ }
106
121
  if (why === undefined) {
107
122
  const grammar = ruleCompileVerdict(r, 'deny').kind;
108
123
  if (grammar === 'unknown')
@@ -115,22 +130,47 @@ export function sessionPolicyDeliverable(behavior, rules, opts) {
115
130
  if (why === undefined)
116
131
  exact.push(r);
117
132
  else {
118
- withheld.push(why === 'legacy_tool_name' && currentName !== undefined ? { rule: r, why, currentName } : { rule: r, why });
133
+ withheld.push({
134
+ rule: r,
135
+ why,
136
+ ...(why === 'legacy_tool_name' && currentName !== undefined ? { currentName } : {}),
137
+ ...(inertReason !== undefined ? { inertReason } : {}),
138
+ });
119
139
  }
120
140
  }
121
- if (withheld.length > 0 || exact.length === 0)
141
+ const blocking = withheld.some((w) => w.inertReason === undefined);
142
+ if (blocking || exact.length === 0)
122
143
  return { deliverable: {}, withheld };
123
144
  return { deliverable: { toolDeny: exact }, withheld };
124
145
  }
146
+ function entryReadingOf(rule) {
147
+ try {
148
+ const reading = readRuleEntry(rule, 'deny');
149
+ if (typeof reading !== 'object' || reading === null)
150
+ return 'unknown';
151
+ const kind = readOwnDataValue(reading, 'kind');
152
+ if (kind === 'row') {
153
+ const compiled = readOwnDataValue(reading, 'compiled');
154
+ return typeof compiled === 'object' && compiled !== null ? 'row' : 'unknown';
155
+ }
156
+ if (kind !== 'inert')
157
+ return 'unknown';
158
+ const reason = readOwnDataValue(reading, 'reason');
159
+ if (reason === 'grammar' || reason === 'content_unsupported')
160
+ return { why: 'not_a_tool_name', reason };
161
+ if (reason === 'wildcard_all' || reason === 'namespace_wildcard')
162
+ return { why: 'wildcard', reason };
163
+ return 'unknown';
164
+ }
165
+ catch {
166
+ return 'unknown';
167
+ }
168
+ }
125
169
  export function sessionPolicyWithheldNotice(why) {
126
170
  return typeof why === 'string' && Object.hasOwn(WITHHELD_NOTICE, why)
127
171
  ? WITHHELD_NOTICE[why]
128
172
  : 'Not written to this session’s rule record.';
129
173
  }
130
- const LEGACY_TOOL_NAME_FAILURE_NOTE = `This run did not start: a tool rule applied to it names a tool the engine refuses — ${REFUSED_NAME_CLASSES} (the engine's own error text names the entry). ` +
131
- 'Every later run fails the same way until that entry is removed from wherever it is set: this session’s rule record, the settings sent with the run, a parent session’s rule record, or the deployment’s own tool rules.';
132
174
  export function legacyToolNameFailureNoteOf(code) {
133
- if (code === CONFIG_LEGACY_TOOL_NAME)
134
- return LEGACY_TOOL_NAME_FAILURE_NOTE;
135
- return undefined;
175
+ return code === CONFIG_LEGACY_TOOL_NAME ? prepareRefusalNoteOf(code) : undefined;
136
176
  }
@@ -1,4 +1,5 @@
1
1
  import type { SessionPermissionRules, StoredSessionRules } from '@sema-agent/sdk';
2
+ import type { UiLanguage } from '../env/uiLanguage.js';
2
3
  import type { SessionPolicyReading } from '../sessionPolicyCapability.js';
3
4
  import type { ToolRosterView } from '../toolRoster.js';
4
5
  import { CORE_ALLOW_ENTRY_INERT_REASONS, CORE_RULE_TOOL_NAME_VERDICTS } from '../generated/engineFactTables.js';
@@ -127,7 +128,7 @@ export interface SessionPolicyInertEntryRefusal {
127
128
  export declare function tightenSessionPolicy(facade: SessionPolicyFacade, req: SessionPolicyTightenRequest, opts?: {
128
129
  signal?: AbortSignal;
129
130
  }): Promise<SessionPolicyTightenOutcome>;
130
- export declare function sessionPolicyTightenNotice(outcome: SessionPolicyTightenOutcome): string;
131
+ export declare function sessionPolicyTightenNotice(outcome: SessionPolicyTightenOutcome, lang?: UiLanguage): string;
131
132
  export declare function sessionPolicyReadNotice(outcome: Exclude<SessionPolicyReadOutcome, {
132
133
  kind: 'present';
133
134
  }> | {
@@ -1,5 +1,6 @@
1
1
  import { wireFailureShapeOf } from '../wireFailureShape.js';
2
2
  import { hostLog } from '../host.js';
3
+ import { msg, renderMessage } from '../i18n/translate.js';
3
4
  import { ruleToolNameVerdictOf } from '../protocolSegment.js';
4
5
  import { RULES_INERT_ENTRY, RULES_INVALID_SHAPE, isRulesRefusalCode } from '../engineErrorCodes.js';
5
6
  import { deniedEntryToolName } from '../engineToolDirectory.js';
@@ -411,50 +412,48 @@ export async function tightenSessionPolicy(facade, req, opts) {
411
412
  return second.done;
412
413
  return { kind: 'conflict', rev: second.retryAtRev };
413
414
  }
414
- const SESSION_POLICY_INERT_ENTRY_WRITE_NOTE = 'The engine refused to write these session rules, and the stored record was not changed at all: one entry in them reads as matching nothing — written in, it would neither block nor allow any call (the engine’s own error text names the entry and why). Correct that entry or take it out, then write the rules again. If that entry was already in this session’s rule record, it has to be removed from the record before the record can be written again.';
415
- const SESSION_POLICY_EARLIER_GRAMMAR_NOTE = 'Nothing was written: this session’s rules were saved before the current rule grammar, when an allow entry written in a tool’s own rule form (such as Bash(git:*)) was read as a plain tool name and so allowed nothing. Writing the record back now would read those entries in the current grammar, where they do allow calls — a widening nobody asked for — so the record was left as it is. Rewrite this session’s allow entries in the current form, or take those entries out, before changing its rules here.';
416
- export function sessionPolicyTightenNotice(outcome) {
415
+ const earlierGrammarNote = (lang) => renderMessage(msg('rules.sessionPolicy.tighten.earlierGrammar'), lang);
416
+ export function sessionPolicyTightenNotice(outcome, lang) {
417
+ const say = (key, params) => renderMessage(msg(key, params), lang);
417
418
  switch (outcome.kind) {
418
419
  case 'written':
419
- return `Session rules saved (version ${outcome.rev}) — the record now holds everything it already had plus the entries sent here, and it applies from this session’s next tool gate onward; the step already running is not interrupted.`;
420
+ return say('rules.sessionPolicy.tighten.written', { rev: outcome.rev });
420
421
  case 'conflict':
421
- return 'Session rules were changed by someone else while this tightening was being written, twice in a row — nothing was written. Re-read the current rules and try again, or let the other writer finish first.';
422
+ return say('rules.sessionPolicy.tighten.conflict');
422
423
  case 'loosen_forbidden':
423
- return 'The engine refused this write because it would relax the session rules: at least one entry sent here widens what is allowed rather than narrowing it. Only entries that add restrictions are accepted on this path.';
424
+ return say('rules.sessionPolicy.tighten.loosenForbidden');
424
425
  case 'capability_absent':
425
- return outcome.why === 'absent'
426
- ? 'This deployment does not keep per-session tool rules, so there is nothing to tighten here.'
427
- : 'This engine does not say whether it keeps per-session tool rules — it predates that answer — so the tightening entry stays hidden rather than being written blind.';
426
+ return outcome.why === 'absent' ? say('rules.sessionPolicy.tighten.capabilityAbsent') : say('rules.sessionPolicy.tighten.capabilityNotReported');
428
427
  case 'refused':
429
- return SESSION_POLICY_EARLIER_GRAMMAR_NOTE;
428
+ return earlierGrammarNote(lang);
430
429
  case 'inert_entry':
431
- return SESSION_POLICY_INERT_ENTRY_WRITE_NOTE;
430
+ return say('rules.sessionPolicy.tighten.inertEntry');
432
431
  case 'unknown':
433
432
  switch (outcome.why) {
434
433
  case 'face_unavailable':
435
- return 'This deployment does not keep per-session tool rules, so nothing was written.';
434
+ return say('rules.sessionPolicy.tighten.unknown.faceUnavailable');
436
435
  case 'session_not_found':
437
- return 'This session is not readable from here — it may not exist, or it may belong to someone else (the engine answers both the same way, so this client cannot tell which); nothing was written.';
436
+ return say('rules.sessionPolicy.tighten.unknown.sessionNotFound');
438
437
  case 'session_ownerless':
439
- return 'This session has no owner, so a rule written for it could never be read back; nothing was written. Attach an identity to the session and try again.';
438
+ return say('rules.sessionPolicy.tighten.unknown.sessionOwnerless');
440
439
  case 'unauthorized':
441
- return 'This call could not present a verifiable identity, so nothing was written.';
440
+ return say('rules.sessionPolicy.tighten.unknown.unauthorized');
442
441
  case 'request_rejected':
443
- return 'The engine rejected the shape of this rule record, so nothing was written. Fix the entries before sending them again.';
442
+ return say('rules.sessionPolicy.tighten.unknown.requestRejected');
444
443
  case 'store_corrupt':
445
- return 'The engine could not establish which version this session’s rules are at and refused to stamp a new one, so nothing was written. The entries sent here are not the problem — this needs an operator to look at the rule store.';
444
+ return say('rules.sessionPolicy.tighten.unknown.storeCorrupt');
446
445
  case 'read_unreadable':
447
- return 'The session’s current rules could not be read, so nothing was written — writing over a record that cannot be read would replace real restrictions with an empty one.';
446
+ return say('rules.sessionPolicy.tighten.unknown.readUnreadable');
448
447
  case 'read_failed':
449
- return 'The session’s current rules could not be fetched, so nothing was written.';
448
+ return say('rules.sessionPolicy.tighten.unknown.readFailed');
450
449
  case 'write_refused':
451
- return 'The engine refused this write, so nothing was written. Re-read the current rules before trying again.';
450
+ return say('rules.sessionPolicy.tighten.unknown.writeRefused');
452
451
  case 'write_indeterminate':
453
- return 'The write never came back with an answer from the engine — it may or may not have taken effect. Re-read the current rules before writing anything else.';
452
+ return say('rules.sessionPolicy.tighten.unknown.writeIndeterminate');
454
453
  case 'write_receipt_unreadable':
455
- return 'The tightening was sent but the engine’s answer could not be read — it may already be in effect. Re-read the current rules before writing anything else.';
454
+ return say('rules.sessionPolicy.tighten.unknown.writeReceiptUnreadable');
456
455
  case 'write_receipt_mismatch':
457
- return 'The tightening was sent but the engine’s answer does not account for it (the version did not advance, the entries sent here are not in the returned record, or the record came back without the rule-grammar mark it was sent with, so its entries may now read differently) — it may already be in effect. Re-read the current rules before writing anything else.';
456
+ return say('rules.sessionPolicy.tighten.unknown.writeReceiptMismatch');
458
457
  }
459
458
  }
460
459
  }
@@ -718,7 +717,7 @@ export function sessionPolicyRemovalNotice(outcome) {
718
717
  case 'write_unconfirmed':
719
718
  return 'The removal was sent but no clear answer came back from the engine — it may already be in effect. Run the removal again: it re-reads the record, and reports nothing left to remove if it did take effect.';
720
719
  case 'refused':
721
- return SESSION_POLICY_EARLIER_GRAMMAR_NOTE;
720
+ return earlierGrammarNote();
722
721
  case 'inert_entry':
723
722
  return 'Nothing was changed: the engine refused to write this session’s rule record back, because an entry this removal keeps reads as matching nothing (the engine’s own error text names the entry and why). This removal only takes out names the engine refuses to start a run with, so it leaves that entry for a person to correct or remove; while the record holds it, it cannot be written, so the entries this removal meant to take out stay in it as well.';
724
723
  default:
@@ -1,3 +1,4 @@
1
+ import type { UiLanguage } from '../env/uiLanguage.js';
1
2
  export type SuspendedReopenReading = {
2
3
  readonly kind: 'reopened';
3
4
  readonly code: string;
@@ -13,4 +14,4 @@ export interface ResumeReopenDetail {
13
14
  retriable: true;
14
15
  }
15
16
  export declare function resumeReopenFromError(err: unknown): ResumeReopenDetail | null;
16
- export declare function resumeReopenContent(detail: ResumeReopenDetail): string;
17
+ export declare function resumeReopenContent(detail: ResumeReopenDetail, lang?: UiLanguage): string;
@@ -1,4 +1,5 @@
1
1
  import { RESUME_REOPEN_CODES, RESUME_ENV_FAILED, RESUME_TOOL_UNAVAILABLE, refusalSaysStillPending } from '../engineErrorCodes.js';
2
+ import { msg, renderMessage } from '../i18n/translate.js';
2
3
  import { guardedRead, ownDataField } from '../ownKey.js';
3
4
  const UNSTATED = Object.freeze({ kind: 'unstated' });
4
5
  const NOT_REOPENED = Object.freeze({ kind: 'not_reopened' });
@@ -31,15 +32,11 @@ export function resumeReopenFromError(err) {
31
32
  const reason = code.slice('resume.'.length);
32
33
  return { code, reason, retriable: true };
33
34
  }
34
- export function resumeReopenContent(detail) {
35
- const first = detail.code === RESUME_ENV_FAILED
36
- ? 'The execution environment for this parked work could not be brought back'
35
+ export function resumeReopenContent(detail, lang) {
36
+ const first = msg(detail.code === RESUME_ENV_FAILED
37
+ ? 'resume.reopen.first.envFailed'
37
38
  : detail.code === RESUME_TOOL_UNAVAILABLE
38
- ? 'The tool this approval was granted for is not available on this engine'
39
- : 'The tool this approval was granted for has changed since the approval was recorded';
40
- return [
41
- first,
42
- 'The engine re-parked the work before consuming anything — the approval is still pending and your decision was not consumed',
43
- 'Re-fetch the pending approvals and decide again on an engine where the same tool is available',
44
- ].join(' · ');
39
+ ? 'resume.reopen.first.toolUnavailable'
40
+ : 'resume.reopen.first.toolContractMismatch');
41
+ return renderMessage(msg('resume.reopen.content', { first }), lang);
45
42
  }
@@ -1,5 +1,7 @@
1
1
  import { type HitlClientLike, type DecideOperationObserver } from './hitlBridge.js';
2
2
  import { type ApprovalAllowRuleShadow } from './allowRuleShadow.js';
3
+ import type { UiLanguage } from '../env/uiLanguage.js';
4
+ import type { SessionRuleInertReason } from './sessionPolicyWire.js';
3
5
  import { type ApprovalCardClaim } from './approvalHolds.js';
4
6
  import { type ApprovalResolution } from './approvalResolution.js';
5
7
  import { type ApprovalMandateWord } from '../gateVocabulary.js';
@@ -243,14 +245,21 @@ export declare function decisionAttributionKeyOf(reading: ApprovalDecidedByReadi
243
245
  settledBy: 'policy';
244
246
  } | Record<never, never>;
245
247
  export declare function isToolApprovalFrame(ev: unknown): ev is ToolApprovalFrame;
246
- export declare function askProbeReasonDetail(card: Pick<ApprovalCardRequest, 'probeReason' | 'probeCause'> | null | undefined): string | undefined;
248
+ export declare function askProbeReasonDetail(card: Pick<ApprovalCardRequest, 'probeReason' | 'probeCause'> | null | undefined, lang?: UiLanguage): string | undefined;
247
249
  export declare function readApprovalRememberRefused(v: unknown): boolean;
248
250
  export declare function readApprovalBoundGrants(v: unknown): BoundSkillGrantsWire | undefined;
251
+ export type BoundGrantEntryReading = {
252
+ readonly kind: 'rule';
253
+ } | {
254
+ readonly kind: 'reads_as_nothing';
255
+ readonly reason?: SessionRuleInertReason;
256
+ };
257
+ export declare function readBoundGrantEntry(entry: string): BoundGrantEntryReading | undefined;
249
258
  export type ApprovalGrantBinding = 'bound' | 'none' | 'unreadable';
250
259
  export declare function readApprovalClassifierNoRuling(v: unknown): string | undefined;
251
- export declare function classifierNoRulingDetail(word: string | undefined): string;
252
- export declare function approvalBoundGrantsDetail(grants: BoundSkillGrantsWire | null | undefined): string | undefined;
253
- export declare function approvalPriorCardsDetail(card: Pick<ApprovalCardRequest, 'priorCardsForCall' | 'origin'> | null | undefined): string | undefined;
260
+ export declare function classifierNoRulingDetail(word: string | undefined, lang?: UiLanguage): string;
261
+ export declare function approvalBoundGrantsDetail(grants: BoundSkillGrantsWire | null | undefined, lang?: UiLanguage): string | undefined;
262
+ export declare function approvalPriorCardsDetail(card: Pick<ApprovalCardRequest, 'priorCardsForCall' | 'origin'> | null | undefined, lang?: UiLanguage): string | undefined;
254
263
  export declare function approvalSupersedesDetail(card: Pick<ApprovalCardRequest, 'supersedes'> | null | undefined): string | undefined;
255
264
  export declare function readDenialLimitFallback(v: unknown): DenialLimitFallback | undefined;
256
265
  export declare function readRuleOffers(v: unknown): RuleOfferReading[] | undefined;
@@ -289,5 +298,8 @@ export type ApprovalHolderJoin = {
289
298
  readonly kind: 'free';
290
299
  };
291
300
  export declare function joinApprovalHolder(identity: ApprovalHolderIdentity, signal?: AbortSignal): Promise<ApprovalHolderJoin>;
292
- export declare function claimApprovalCard(identity: ApprovalHolderIdentity, signal?: AbortSignal): Promise<ApprovalCardClaim>;
301
+ export interface ApprovalCardClaimOptions {
302
+ readonly signal?: AbortSignal;
303
+ }
304
+ export declare function claimApprovalCard(identity: ApprovalHolderIdentity, options?: ApprovalCardClaimOptions): Promise<ApprovalCardClaim>;
293
305
  export type { ApprovalCardClaim, HostApprovalCardHold } from './approvalHolds.js';