@sema-agent/client-core 0.108.0 → 0.110.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 (179) hide show
  1. package/CHANGELOG.md +294 -0
  2. package/README.md +77 -40
  3. package/dist/adapt/arms.js +41 -13
  4. package/dist/adapt/textStream.d.ts +2 -0
  5. package/dist/adapt/textStream.js +37 -16
  6. package/dist/adapter/activeRunSelfHeal.js +1 -1
  7. package/dist/adapter/downstream/eventToSdkMessage.js +11 -5
  8. package/dist/agentSession/engineAgentRegistryRead.js +2 -0
  9. package/dist/bashExitReading.d.ts +12 -0
  10. package/dist/bashExitReading.js +44 -0
  11. package/dist/checkpointRowVerdict.d.ts +1 -1
  12. package/dist/checkpointRowVerdict.js +4 -2
  13. package/dist/compensations.js +1 -1
  14. package/dist/declared/supportFloorDeclared.js +1 -1
  15. package/dist/displayUntrusted.js +132 -14
  16. package/dist/engineAgentAbsence.d.ts +2 -0
  17. package/dist/engineAgentAbsence.js +28 -0
  18. package/dist/engineErrorCodes.d.ts +7 -0
  19. package/dist/engineErrorCodes.js +7 -0
  20. package/dist/engineHealthFacts.d.ts +26 -0
  21. package/dist/engineHealthFacts.js +63 -4
  22. package/dist/engineInlineTaskStats.d.ts +4 -3
  23. package/dist/engineInlineTaskStats.js +18 -2
  24. package/dist/engineNoticeCodes.d.ts +138 -0
  25. package/dist/engineNoticeCodes.js +662 -55
  26. package/dist/engineRepoint.d.ts +140 -0
  27. package/dist/engineRepoint.js +285 -0
  28. package/dist/engineRowRef.js +2 -0
  29. package/dist/engineSessionMessages.d.ts +2 -1
  30. package/dist/engineSessionMessages.js +5 -0
  31. package/dist/errorSupplementRoles.js +5 -1
  32. package/dist/fleet/fleetProjection.js +3 -2
  33. package/dist/fleetTaskDesc.js +3 -3
  34. package/dist/generated/engineFactTables.d.ts +3 -0
  35. package/dist/generated/engineFactTables.js +18 -0
  36. package/dist/generated/engineNoticeTables.js +3 -0
  37. package/dist/generated/sdkFactTables.d.ts +1 -0
  38. package/dist/generated/sdkFactTables.js +4 -0
  39. package/dist/hitl/approvalAskers.d.ts +6 -0
  40. package/dist/hitl/approvalAskers.js +30 -0
  41. package/dist/hitl/approvalCardReasons.js +25 -4
  42. package/dist/hitl/approvalRequestFrameReading.d.ts +21 -0
  43. package/dist/hitl/approvalRequestFrameReading.js +90 -0
  44. package/dist/hitl/approvalResolution.d.ts +8 -1
  45. package/dist/hitl/approvalResolution.js +4 -0
  46. package/dist/hitl/approvalsFeed.js +1 -1
  47. package/dist/hitl/askGateWire.js +0 -2
  48. package/dist/hitl/askParkRowRouting.js +5 -2
  49. package/dist/hitl/automaticAnswerVerdict.d.ts +5 -2
  50. package/dist/hitl/automaticAnswerVerdict.js +18 -4
  51. package/dist/hitl/decisionConflict.d.ts +2 -1
  52. package/dist/hitl/decisionConflict.js +10 -4
  53. package/dist/hitl/decisionRefusal.js +1 -0
  54. package/dist/hitl/decisionSend.d.ts +3 -0
  55. package/dist/hitl/decisionSend.js +29 -11
  56. package/dist/hitl/editedApprovalAcceptance.d.ts +25 -0
  57. package/dist/hitl/editedApprovalAcceptance.js +26 -0
  58. package/dist/hitl/frameRouter.js +13 -19
  59. package/dist/hitl/gateLedger.d.ts +0 -4
  60. package/dist/hitl/gateLedger.js +0 -19
  61. package/dist/hitl/hitlBridge.d.ts +5 -0
  62. package/dist/hitl/hitlBridge.js +13 -9
  63. package/dist/hitl/hitlHostSurface.d.ts +1 -0
  64. package/dist/hitl/hitlHostSurface.js +7 -2
  65. package/dist/hitl/hostWithdrawal.d.ts +15 -0
  66. package/dist/hitl/hostWithdrawal.js +38 -0
  67. package/dist/hitl/livePendingAsk.js +17 -16
  68. package/dist/hitl/localAllowRule.js +2 -1
  69. package/dist/hitl/noAllowCause.d.ts +1 -1
  70. package/dist/hitl/noAllowCause.js +4 -2
  71. package/dist/hitl/parkExpiryJudgements.js +26 -1
  72. package/dist/hitl/parkOwnership.d.ts +2 -0
  73. package/dist/hitl/parkOwnership.js +48 -8
  74. package/dist/hitl/parkResolver.js +32 -16
  75. package/dist/hitl/parkedUnresumable.d.ts +13 -0
  76. package/dist/hitl/parkedUnresumable.js +80 -0
  77. package/dist/hitl/permissionRuleScope.d.ts +4 -0
  78. package/dist/hitl/permissionRuleScope.js +31 -0
  79. package/dist/hitl/persistedRulesWire.d.ts +2 -0
  80. package/dist/hitl/persistedRulesWire.js +13 -12
  81. package/dist/hitl/planReviewWire.js +14 -4
  82. package/dist/hitl/sessionAllowRoute.js +5 -4
  83. package/dist/hitl/sessionPolicyWire.js +6 -4
  84. package/dist/hitl/standingRows.d.ts +2 -5
  85. package/dist/hitl/standingRows.js +30 -15
  86. package/dist/hitl/toolApprovalWire.d.ts +42 -9
  87. package/dist/hitl/toolApprovalWire.js +267 -44
  88. package/dist/hooksWireCaps.js +35 -4
  89. package/dist/hostSettingsSource.js +2 -0
  90. package/dist/hostTurnSettings.d.ts +10 -4
  91. package/dist/hostTurnSettings.js +112 -5
  92. package/dist/i18n/messages.en.d.ts +251 -0
  93. package/dist/i18n/messages.en.js +254 -2
  94. package/dist/i18n/messages.zh.js +264 -2
  95. package/dist/index.d.ts +48 -12
  96. package/dist/index.js +29 -7
  97. package/dist/inheritEnvCapability.js +2 -0
  98. package/dist/inputAuthor.d.ts +16 -0
  99. package/dist/inputAuthor.js +44 -0
  100. package/dist/interruptRefusalNote.d.ts +2 -0
  101. package/dist/interruptRefusalNote.js +17 -0
  102. package/dist/liveModelCatalog.d.ts +2 -0
  103. package/dist/liveModelCatalog.js +21 -7
  104. package/dist/liveQuestionStore.d.ts +4 -1
  105. package/dist/liveQuestionStore.js +12 -3
  106. package/dist/localEngineJudge.d.ts +75 -0
  107. package/dist/localEngineJudge.js +242 -0
  108. package/dist/localEngineOccupancy.d.ts +88 -0
  109. package/dist/localEngineOccupancy.js +269 -0
  110. package/dist/localEngineSeatReading.d.ts +29 -0
  111. package/dist/localEngineSeatReading.js +294 -0
  112. package/dist/localEngineSpawn.d.ts +113 -0
  113. package/dist/localEngineSpawn.js +486 -0
  114. package/dist/localEngineStep.d.ts +286 -0
  115. package/dist/localEngineStep.js +1086 -0
  116. package/dist/localEngineStopLadder.d.ts +29 -0
  117. package/dist/localEngineStopLadder.js +139 -0
  118. package/dist/localEngineSwapCard.d.ts +43 -0
  119. package/dist/localEngineSwapCard.js +205 -0
  120. package/dist/localEngineTiming.d.ts +8 -0
  121. package/dist/localEngineTiming.js +8 -0
  122. package/dist/mcpEngineLeg.d.ts +3 -0
  123. package/dist/mcpEngineLeg.js +38 -1
  124. package/dist/mcpPanel.js +2 -0
  125. package/dist/mcpReconnect.d.ts +9 -1
  126. package/dist/mcpReconnect.js +132 -20
  127. package/dist/mcpWireCaps.js +2 -2
  128. package/dist/memoryEntriesWire.d.ts +1 -1
  129. package/dist/memoryEntriesWire.js +5 -0
  130. package/dist/modelCapabilityProbe.js +4 -3
  131. package/dist/modsFace.d.ts +8 -1
  132. package/dist/modsFace.js +27 -0
  133. package/dist/noticePresentation.d.ts +2 -0
  134. package/dist/noticePresentation.js +79 -1
  135. package/dist/notifications.d.ts +17 -6
  136. package/dist/notifications.js +67 -19
  137. package/dist/ownKey.d.ts +5 -0
  138. package/dist/ownKey.js +8 -1
  139. package/dist/peerFrames.d.ts +40 -2
  140. package/dist/peerFrames.js +158 -3
  141. package/dist/pluginHooksWire.d.ts +2 -1
  142. package/dist/pluginHooksWire.js +56 -1
  143. package/dist/replayBody.js +10 -2
  144. package/dist/request/taskRequest.d.ts +5 -0
  145. package/dist/request/taskRequest.js +138 -21
  146. package/dist/resumeRefusalCopy.d.ts +1 -3
  147. package/dist/resumeRefusalCopy.js +2 -1
  148. package/dist/retryStatus.d.ts +2 -2
  149. package/dist/retryStatus.js +2 -0
  150. package/dist/ruleReadings.js +1 -1
  151. package/dist/seam.d.ts +24 -2
  152. package/dist/seam.js +15 -2
  153. package/dist/seatContract.d.ts +125 -10
  154. package/dist/seatContract.js +373 -7
  155. package/dist/sessionBackground.js +4 -1
  156. package/dist/sessionBackgroundHandoff.js +2 -1
  157. package/dist/sessionEngine.d.ts +2 -0
  158. package/dist/sessionEngine.js +111 -0
  159. package/dist/sessionMemoryStatus.d.ts +2 -1
  160. package/dist/sessionSyncFileHistory.d.ts +4 -0
  161. package/dist/sessionSyncFileHistory.js +28 -0
  162. package/dist/sseIdleTriage.d.ts +13 -1
  163. package/dist/sseIdleTriage.js +24 -6
  164. package/dist/subagent/engineSubagentTail.js +6 -0
  165. package/dist/subagentContentStore.d.ts +12 -0
  166. package/dist/subagentContentStore.js +72 -11
  167. package/dist/terminalStatuses.d.ts +1 -0
  168. package/dist/terminalStatuses.js +4 -1
  169. package/dist/toolResult.js +18 -5
  170. package/dist/turnFailurePresentation.js +9 -2
  171. package/dist/typePins.d.ts +11 -0
  172. package/dist/usageAnalytics.d.ts +17 -0
  173. package/dist/usageAnalytics.js +44 -2
  174. package/dist/wireFailureShape.d.ts +22 -5
  175. package/dist/wireFailureShape.js +47 -26
  176. package/dist/wireRefusalCopy.d.ts +31 -1
  177. package/dist/wireRefusalCopy.js +167 -2
  178. package/docs/INTEGRATION-CLIENTS.md +3269 -21
  179. package/package.json +5 -5
@@ -117,6 +117,7 @@ const EN = {
117
117
  'model.subagent.ambiguous': "Subagent model {word} matches more than one model name that differ only in case — spell it exactly; the subagent will run on its parent's model.",
118
118
  'model.catalogDefault.refused.named': 'A task that names no model would be refused: the engine cannot resolve a default model from its model configuration (the settings default is {name}) · Set a default model the engine can run, or add or fix one',
119
119
  'model.catalogDefault.refused.select': 'A task that names no model would be refused: the engine cannot resolve a default model from its model configuration (the settings default is a selection) · Change the selection, or add or fix a model the engine can run',
120
+ 'session.sync.pushRowBitsWriterSide': 'The session was pushed · At the destination it is a read-only mirror, so its title and pin stay with the side that writes it and were not changed there',
120
121
  'session.devices.laneAbsent': 'This backend has no remote-control lane',
121
122
  'session.devices.laneUnreported': "This backend doesn't report a remote-control lane",
122
123
  'session.devices.verbsOff': "This backend's device lane is on, but its device-management verbs are off — devices can't be listed or changed here",
@@ -124,12 +125,30 @@ const EN = {
124
125
  'session.devices.probeFailedTransport': "Couldn't reach the engine to check for a remote-control lane — try again",
125
126
  'session.devices.probeFailedRefused': 'The engine refused the device-list check — try again',
126
127
  'session.devices.probeFailedUnreadable': "The engine's device list couldn't be read — try again",
127
- 'session.engine.selfNotLocal': "This session runs on the engine this app started on this device, but it was started as a Cloud session. Nothing was changed — check how this session was opened.",
128
+ 'session.engine.selfNotLocal': "This session runs on this device's local engine, but it was started as a Cloud session. Nothing was changed — check how this session was opened.",
128
129
  'session.engine.dispatch.notWired': "This session's engine isn't connected right now, so nothing was sent. Connect to that engine, then try again.",
129
130
  'session.engine.dispatch.scopeMismatch': "This session belongs to an engine in a different space from the one you're signed in to, so nothing was sent. Switch to that space, then try again.",
130
131
  'session.engine.dispatch.scopeUnproven': "Your current sign-in can't be confirmed to reach this session's engine, so nothing was sent. Sign in to that engine's space (or connect to the engine directly), then try again.",
131
132
  'session.engine.dispatch.unresolved': "This session's engine isn't known yet, so nothing was sent. Choose the engine for this session once, then try again.",
132
133
  'session.engine.dispatch.sessionAmbiguous': 'This session is registered on two engines at once, so nothing was sent. Stop here and resolve which engine it belongs to first.',
134
+ 'session.mcpReconnect.notRunning': 'No run of this session is live on this engine right now (it may be waiting for an answer, have finished, or be running elsewhere), so {server} was not re-dialed; a run that starts or resumes dials its declared servers again.',
135
+ 'session.mcpReconnect.unsupported': 'This engine does not support re-dialing an MCP server during a session; {server} was not re-dialed.',
136
+ 'session.mcpReconnect.notFound': 'The engine did not find this session, so {server} was not re-dialed.',
137
+ 'session.mcpReconnect.invalid': 'The re-dial request for {server} was not valid (the session id or the server name was unusable), so it was not re-dialed.',
138
+ 'session.mcpReconnect.failed': 'Could not re-dial {server} on the engine: the request did not complete.',
139
+ 'session.mcpReconnect.noSession': 'There is no engine session yet, so {server} was not re-dialed on the engine.',
140
+ 'session.mcpReconnect.unavailable': 'Re-dialing {server} on the engine is not available here.',
141
+ 'session.mcpReconnect.accepted.one': 'MCP server {server} was re-dialed: {toolCount} tool mounted for this run ({added} added, {removed} removed)',
142
+ 'session.mcpReconnect.accepted.other': 'MCP server {server} was re-dialed: {toolCount} tools mounted for this run ({added} added, {removed} removed)',
143
+ 'session.mcpReconnect.refused.untouched': 'MCP server {server} was NOT re-dialed; its connection and tools were left untouched{why}',
144
+ 'session.mcpReconnect.refused.noTools': "MCP server {server} was NOT re-dialed; this run's tool list has no tools from it right now (the dial failed, or this run's tool settings let none of its tools through){why}",
145
+ 'session.mcpReconnect.refused.listed.one': 'MCP server {server} was NOT re-dialed; the engine reports {toolCount} tool for it after this attempt{why}',
146
+ 'session.mcpReconnect.refused.listed.other': 'MCP server {server} was NOT re-dialed; the engine reports {toolCount} tools for it after this attempt{why}',
147
+ 'session.mcpReconnect.undeclared': 'This run declared no MCP servers, so there is nothing to re-dial ({server} is not part of this run){why}',
148
+ 'session.mcpReconnect.unsettled': "The MCP re-dial did not settle within the time this request waits, so there is no result yet: the re-dial was not cancelled and may still be running. Check the server's state before re-dialing it again — a second request that arrives after the dial has settled closes the connection and dials once more.",
149
+ 'session.mcpReconnect.reasonTail': ' — {reason}',
150
+ 'session.mcpFailure.reauthorizeSuffix': ' (re-authorize)',
151
+ 'session.mcpFailure.serverDownSuffix': ' (the server is down)',
133
152
  'config.cloudLogin.accessDenied': 'Sign-in was declined.',
134
153
  'config.cloudLogin.expiredToken': 'The sign-in code expired before it was approved — start again.',
135
154
  'config.cloudLogin.invalidGrant': 'The Cloud sign-in can no longer be renewed — sign in again.',
@@ -252,6 +271,7 @@ const EN = {
252
271
  'approval.settle.cause.streamDisconnected': 'the connection carrying this card dropped',
253
272
  'approval.settle.cause.undeliverable': 'it could not be delivered to any approval surface',
254
273
  'approval.resolution.engineUnavailable': 'The engine is temporarily unavailable — answer this once the engine is back.',
274
+ 'approval.allowNote.notCarried': "This engine can't take a note on Yes — a note written here is not sent to the model.",
255
275
  'approval.decide.requiresBinding': 'This decision was sent without the binding that ties it to the exact action on the approval card, so the engine refused it · Nothing was decided and the approval is still pending · Fetch the pending approvals again and decide from the card as it is listed now; if the listed card itself carries no binding, {wayOut}',
256
276
  'approval.decide.unboundWayOut.armed': 'it cannot be decided here — cancel the run or let the approval expire',
257
277
  'approval.decide.unboundWayOut.none': 'it cannot be decided here — cancel the run (this approval has no expiry timer)',
@@ -261,11 +281,18 @@ const EN = {
261
281
  'approval.rowUnresumable.askNotSurfaced': 'the pending row (task {taskId}) cannot be continued by this engine, so it is not surfaced as a card that can be answered: {sentence}',
262
282
  'approval.park.stillParked': '{gate} gate could not be answered: {reason} — the run is still parked on this approval.',
263
283
  'approval.park.refusedNotResumable': '{gate} gate could not be answered: {reason} — this engine cannot resume this approval as things stand; cancel the run if it is still parked.',
284
+ 'approval.park.resume.card': '{gate} gate could not be answered: {reason} — the run is still parked on this approval: decide it on the card when it is shown again, or cancel the run.',
285
+ 'approval.park.resume.speak': '{gate} gate could not be answered: {reason} — the run is still parked on this approval: send a message to reopen the card, then decide it there, or cancel the run.',
286
+ 'approval.park.argsFromModelCall': "the pending approval record has no tool arguments that will run, so the arguments shown are the model's original call from the conversation — if they were changed after that call (for example by a hook), what runs differs from what is shown. Edits are not accepted on this card: the arguments shown are not the ones that will run",
287
+ 'approval.park.questionsFromModelCall': "the pending approval record has no questions to present, so the questions shown are the model's original call from the conversation — if they were changed after that call (for example by a hook), the question the engine is actually asking may differ from what is shown",
264
288
  'approval.policyDeny.denyRule': 'Permission for this tool use was denied by a deny rule in the permission settings. {tail}',
265
289
  'approval.policyDeny.dontAsk': 'Permission for this tool use was denied: this session no longer asks for approval, so a call that would need approval is refused. {tail}',
266
290
  'approval.policyDeny.engineFloor': 'Permission for this tool use was denied by a safeguard on the engine side that permission settings cannot override. {tail}',
267
291
  'approval.policyDeny.tail': 'The action was NOT performed. Do not claim it succeeded, and do not retry it in this session — report the limitation to the user, or suggest an alternative.',
268
292
  'approval.decision.grantChanged': 'The engine refused this approval because the skill grant it was bound to has changed since the card was shown · Nothing was decided and the request is still waiting, but approving it again will be refused the same way · Deny this request so the model can activate the skill again',
293
+ 'approval.decision.answerInvalid': 'The engine rejected the answer itself because it does not fit the question that was asked · Nothing was decided and the question is still waiting · Correct the answer and send it again',
294
+ 'approval.editRefusal.line': 'That approval was NOT sent: this request does not expose its tool arguments here, so an edited approval cannot be applied. ' +
295
+ 'The request is still waiting — approve or deny it as it is.',
269
296
  'approval.decision.settledElsewhereContrary.deniedFirst': 'This request was already answered elsewhere and denied, so your approval did not take effect.',
270
297
  'approval.decision.settledElsewhereContrary.approvedFirst': 'This request was already answered elsewhere and approved, so your denial did not take effect.',
271
298
  'approval.decision.unconfirmedAfterRetry': "It is not known whether your answer took effect: an earlier attempt to send it was not confirmed, and by the time it was sent again the request was no longer waiting · Check the task's current state before acting on it",
@@ -550,6 +577,9 @@ const EN = {
550
577
  'approval.mandate.wayOut.crossBoundaryTaint': "an allow that comes from configuration — a setting that allows everything, or a policy's own answer — is refused for this call, so what you approve or deny here is what settles it",
551
578
  'approval.mandate.unknownWord': 'the reason reported for this confirmation is not one this client recognises, so it shows no reason',
552
579
  'approval.card.payloadUnreadable': 'This client cannot read the format of this approval card, so only its basic facts are shown — decide from those, or deny it if you are not sure what it will do.',
580
+ 'approval.card.payloadUnreadable.versionUnknown': 'This client does not recognise the format version of this approval request, so only its essential facts are shown — decide from those, or deny it if you are not sure what it will do.',
581
+ 'approval.card.payloadUnreadable.fieldsMalformed': 'This approval request uses a format version this client knows, but some of its fields are malformed and could not be read, so only its essential facts are shown — decide from those, or deny it if you are not sure what it will do.',
582
+ 'approval.card.payloadUnreadable.partUnknown': 'This client cannot read one part of this approval request, so only its essential facts are shown — decide from those, or deny it if you are not sure what it will do.',
553
583
  'approval.card.more.one': '1 more reason for this card is not shown.',
554
584
  'approval.card.more.other': '{count} more reasons for this card are not shown.',
555
585
  'approval.card.denialLimit.plain': 'auto-deny limit reached — auto mode denied enough calls on its own that the engine now wants a real human decision; {consecutive} consecutive / {total} total automatic denials so far; the limit that tripped: {limit}',
@@ -628,6 +658,8 @@ const EN = {
628
658
  'session.hostSettings.heldPrevious': 'A settings file could not be read cleanly just now (it may be in the middle of being saved), so the permission rules from the last clean read are still applied.',
629
659
  'session.hostSettings.styleMissing': 'The output style "{name}" selected in your settings could not be found or read, so it is not applied to this request.',
630
660
  'session.hostSettings.styleSafeMode': 'Safe mode is on, so the output style from your settings is not applied.',
661
+ 'session.hostSettings.styleOversize': 'Your output style was not applied to this request: together with the built-in product context it is longer than the {limit}-character limit. Shorten the style to apply it.',
662
+ 'session.hostSettings.styleUnreadable': 'Your output style could not be read as text, so it is not applied to this request.',
631
663
  'model.identity.lane.processEnv': 'the environment this client was started with',
632
664
  'model.identity.lane.settingsEnv': "this client's settings file",
633
665
  'model.identity.lane.modelCatalogFile': 'the local model catalog file',
@@ -653,6 +685,105 @@ const EN = {
653
685
  'notice.userInputUndrained.approvalFeedback.other': '{count} notes you wrote when approving a tool call never reached the model and will not be delivered. Send them again if you still need them.',
654
686
  'notice.askUnresolvable.remedy.approver': 'Way out: connect an approver who can answer requests like this one, or make the connected approver reachable, then try again',
655
687
  'notice.askUnresolvable.remedy.permissionMode': 'Another way out, if this deployment allows it: the {mode} permission mode lets requests like this one through without anyone answering them, and each request let through this way is marked on the tool call it applied to',
688
+ 'notice.durableGate.lead': 'Durable approval is not available in this session — {mandate}, but {cause}, so approval requests cannot be saved to be answered later.',
689
+ 'notice.durableGate.mandate.forceDurableGate': 'this account requires it',
690
+ 'notice.durableGate.mandate.durableApproval': 'this task asked for it',
691
+ 'notice.durableGate.mandate.other': 'it was required',
692
+ 'notice.durableGate.cause.noDeploymentStore': 'no checkpoint store is set up on this deployment',
693
+ 'notice.durableGate.cause.taskStoreDisabled': 'this task turned its checkpoint store off',
694
+ 'notice.durableGate.cause.other': 'no checkpoint store is available for it',
695
+ 'notice.durableGate.approver.live': 'Permission requests are answered live in this session instead.',
696
+ 'notice.durableGate.approver.noneAttached': "No live approver is attached to this session, so permission requests follow the engine's configured posture instead.",
697
+ 'notice.durableGate.approver.unreported': "Permission requests follow the engine's configured posture instead.",
698
+ 'notice.durableGate.question.refused': 'Questions the assistant would ask you cannot be shown here, so they are refused.',
699
+ 'notice.durableGate.exit.noDeploymentStore': 'To use durable approval, the deployment needs a checkpoint store.',
700
+ 'notice.durableGate.exit.taskStoreDisabled': 'To use durable approval, run the task with its checkpoint store turned on.',
701
+ 'notice.durableGate.exit.other': 'To use durable approval, a checkpoint store has to be available.',
702
+ 'notice.durableGate.exitAlt.forceDurableGate': 'Or ask whoever runs the deployment to drop the requirement for this account.',
703
+ 'notice.durableGate.exitAlt.durableApproval': 'Or run the task where a live approver is attached.',
704
+ 'notice.memory.sessionPolluted': 'Memory for this session is marked externally exposed ({reason}). From here on, memory it writes may be held back for review instead of being saved to the long-term library; what each batch actually held back is announced separately.',
705
+ 'notice.memory.harvestQuarantined.counts': 'Memory harvest held back entry files written or changed in this session instead of adding them to the long-term library — withheld {count}, moved aside for review {moved}, flagged for follow-up {escalated}; the last two counts can overlap.',
706
+ 'notice.memory.harvestQuarantined.indexOnly': "Memory harvest rolled this session's changes to the memory index back to where they started; no entry files were withheld.",
707
+ 'notice.memory.harvestQuarantined.indexAlso': 'The memory index was also rolled back.',
708
+ 'notice.memory.delegationWaived.lead': "A delegation would have marked this session's memory as polluted, but it was not marked: this deployment does not mark on a delegation's static tool check alone, so that check was waived.",
709
+ 'notice.memory.delegationWaived.agentType': 'Agent type: {agentType}.',
710
+ 'notice.memory.delegationWaived.reason': 'What the check found: "{reason}".',
711
+ 'notice.memory.delegationWaived.tail': 'Other pollution findings, and any memory capture opt-out on this session, are not affected.',
712
+ 'notice.memory.captureOptedOut.flipVerb': 'Memory capture is off for this session from this point on — anything it produced before the switch was still subject to the usual capture.',
713
+ 'notice.memory.captureOptedOut.standingRecord': 'Memory capture stays off for this session — a standing opt-out record from an earlier leg governs it, and a later leg cannot turn it back on.',
714
+ 'notice.memory.captureOptedOut.delegationFloor': 'Memory capture is off for this delegated session — the opt-out of the session that started it is a floor a child cannot loosen (this session did not declare it).',
715
+ 'notice.memory.captureOptedOut.forkOrigin': "Memory capture is off for this forked session — it continues an opted-out session, and that session's one-way opt-out governs the copy (this session did not declare it).",
716
+ 'notice.memory.captureOptedOut.declaration': 'Memory capture is off for this session, as declared when it was submitted.',
717
+ 'notice.memory.captureOptedOut.other': 'Memory capture is off for this session.',
718
+ 'notice.memory.captureOptedOut.tail': 'Nothing it produces is committed to the long-term memory store. Entries committed before the opt-out stay in the library and stay retrievable; deleting them is a separate action, never a side effect of this switch. The switch is one-way: start a new session to capture again.',
719
+ 'notice.memory.captureOptoutUnpersisted.lead': 'The memory capture opt-out for this session could not be durably recorded (the control-plane write failed).',
720
+ 'notice.memory.captureOptoutUnpersisted.declaration': 'So the session was refused rather than run under a switch that would silently stop holding at the next resume: nothing ran and nothing was captured. Repair the control plane (or wire a capture record store), then start a new session.',
721
+ 'notice.memory.captureOptoutUnpersisted.flipVerb': 'So only the request was rejected: this run keeps going and its memory capture is still on. Nothing was recorded, so an identical retry fails the same way; stop the run if this session must not be captured.',
722
+ 'notice.memory.captureOptoutUnpersisted.other': "So it was not honored. This notice alone does not say whether anything stopped — read the run's own outcome for that. Nothing was recorded, so an identical retry fails the same way.",
723
+ 'notice.peer.subject.message': 'An incoming cross-session message #{seq}',
724
+ 'notice.peer.subject.messageFrom': 'An incoming cross-session message #{seq} from {from}',
725
+ 'notice.peer.subject.notice': 'An incoming cross-session notice #{seq}',
726
+ 'notice.peer.subject.noticeFrom': 'An incoming cross-session notice #{seq} from {from}',
727
+ 'notice.peer.subject.held': 'Held cross-session message #{seq}',
728
+ 'notice.peer.subject.heldFrom': 'Held cross-session message #{seq} from {from}',
729
+ 'notice.peer.inbound.refused': "{subject} was refused by this session's policy and was never delivered.",
730
+ 'notice.peer.inbound.admissionRefused': '{subject} was refused at admission.',
731
+ 'notice.peer.inbound.held': '{subject} is held for the next round — it has not been delivered yet, and it has not been rejected.',
732
+ 'notice.peer.inbound.noticeUnrouted': '{subject} had nowhere to be delivered.',
733
+ 'notice.peer.inbound.noticeUserOnly': '{subject} was shown to you only — the model did not read it.',
734
+ 'notice.peer.inbound.resupplyExhausted': "{subject} may never have been read by the model: context compaction dropped it from the model's context twice, and the sender was not told.",
735
+ 'notice.peer.inbound.other': '{subject} was reported with a disposition this version does not recognize.',
736
+ 'notice.peer.inbound.cause': 'Cause: {cause}.',
737
+ 'notice.sessionBox.peer.another': 'another session',
738
+ 'notice.sessionBox.peer.anotherStart': 'Another session',
739
+ 'notice.sessionBox.inbox.one': '1 cross-session message waiting',
740
+ 'notice.sessionBox.inbox.many': '{pending} cross-session messages waiting',
741
+ 'notice.sessionBox.inbox.urgent': '({urgent} urgent)',
742
+ 'notice.sessionBox.inbox.resupplied': '(resupplied {resupplied})',
743
+ 'notice.sessionBox.delivery.delivered': 'Your message to {peer} was delivered.',
744
+ 'notice.sessionBox.delivery.held': "Your message to {peer} is waiting for that session's approval.",
745
+ 'notice.sessionBox.delivery.heldByPolicy': "Your message to {peer} is held by that session's own settings; nobody there is asked to approve it.",
746
+ 'notice.sessionBox.delivery.denied': 'Your message to {peer} was declined by that session.',
747
+ 'notice.sessionBox.delivery.refused': '{peer} is not accepting cross-session messages; your message was not delivered.',
748
+ 'notice.sessionBox.delivery.expired': 'Your message to {peer} expired before it was approved.',
749
+ 'notice.sessionBox.delivery.dropped': 'Your message to {peer} was dropped ({reason}).',
750
+ 'notice.sessionBox.delivery.droppedPlain': 'Your message to {peer} was dropped.',
751
+ 'notice.sessionBox.delivery.other': 'There is a delivery update for your message to {peer}.',
752
+ 'notice.sessionBox.idle.finished': '{peer} finished its turn.',
753
+ 'notice.sessionBox.idle.finishedDetail': '{peer} finished its turn: {detail}',
754
+ 'notice.sessionBox.idle.exited': '{peer} has exited.',
755
+ 'notice.sessionBox.idle.unavailable': '{peer} is unavailable.',
756
+ 'notice.sessionBox.idle.expired': '{peer} did not answer before the wait ran out.',
757
+ 'notice.sessionBox.idle.other': 'There is a status update from {peer}.',
758
+ 'notice.peer.held.deliveredApproved': '{subject} was approved and delivered.',
759
+ 'notice.peer.held.deliveredRejudged': '{subject} was re-judged and delivered, because the policy now accepts it.',
760
+ 'notice.peer.held.droppedRejudged': '{subject} was approved, but the policy now refuses it, so it was dropped.',
761
+ 'notice.peer.held.droppedInjectFailed': '{subject} was approved, but the injection lane refused it when it was released, so it was dropped.',
762
+ 'notice.peer.held.evicted': '{subject} was expired to make room: the held queue is full ({heldCount} still held).',
763
+ 'notice.peer.held.expiredDeadline': '{subject} expired at the review deadline and was not delivered.',
764
+ 'notice.peer.held.expiredCancelled': '{subject} was cancelled and not delivered.',
765
+ 'notice.peer.held.expiredShutdown': '{subject} was expired at shutdown and not delivered.',
766
+ 'notice.peer.held.denied': '{subject} was denied and not delivered.',
767
+ 'notice.peer.held.refused': '{subject} was refused by policy and not delivered.',
768
+ 'notice.peer.held.retiredSuperseded': '{subject} left the held queue without a decision here: another consumer already settled it.',
769
+ 'notice.peer.held.decidedElsewhere': '{subject} was decided by another consumer of the box first.',
770
+ 'notice.peer.held.retiredOther': "{subject} left this session's held queue without a decision here.",
771
+ 'notice.peer.held.other': "{subject} left this session's held queue (this version does not recognize the outcome).",
772
+ 'notice.peer.idle.recorded': 'The session {from} asked to be told when this session is next idle; the request was recorded.',
773
+ 'notice.peer.idle.refreshed': 'The session {from} asked again to be told when this session is next idle; its earlier request was refreshed.',
774
+ 'notice.peer.idle.full': "The session {from} asked to be told when this session is next idle, but this session's subscription list is full, so the request was declined.",
775
+ 'notice.peer.idle.refused': 'The session {from} asked to be told when this session is next idle, but this session refuses messages from other sessions, so the request was declined.',
776
+ 'notice.peer.idle.other': 'The session {from} asked to be told when this session is next idle.',
777
+ 'notice.peer.idle.waiting': 'Subscribers now waiting on this session: {live}.',
778
+ 'notice.classifier.denialLimit.consecutive': "The run was stopped: the permission classifier blocked {count} tool calls in a row and hit its denial limit, and nobody judged the follow-up request for a person's decision.",
779
+ 'notice.classifier.denialLimit.total': "The run was stopped: the permission classifier blocked {count} tool calls in this run and hit its denial limit, and nobody judged the follow-up request for a person's decision.",
780
+ 'notice.classifier.denialLimit.other': "The run was stopped: the permission classifier hit its denial limit, and nobody judged the follow-up request for a person's decision.",
781
+ 'notice.classifier.denialLimit.tool': 'Latest blocked action: {tool}.',
782
+ 'notice.classifier.denialLimit.tail': 'Review the transcript, then change the step that keeps getting blocked or make an approver available, and run it again.',
783
+ 'notice.task.lateApproval': 'Your approval for "{tool}" was not consumed: a run or turn interrupt released that request before your decision landed, so the tool did not run and nothing was settled by your answer. This is a timing fact, not an error; ask again if that step is still needed.',
784
+ 'notice.task.haltUnconsumed': "Your stop request did not cut anything: the run was already ending for its own reason when it arrived, so nothing was stopped by it and the run's own ending stands.",
785
+ 'notice.steering.parkedInputBlocked': "An instruction you sent while this run was paused was blocked when the run resumed: this deployment's input screen withheld it, so it never reached the model. Send it again if it still applies.",
786
+ 'notice.model.capabilityDowngraded.image': 'The images in this conversation were not sent to {model}: its catalog entry declares that it does not take image input, so each image reaches it as a one-line placeholder. If it can read images, declare that in the model entry (input: ["text", "image"]); otherwise switch to a model that can.',
656
787
  'rules.refusal.sentence.one': 'permissions: 1 rule will not be enforced — {list}',
657
788
  'rules.refusal.sentence.other': 'permissions: {count} rules will not be enforced — {list}',
658
789
  'rules.refusal.item': '{rule} ({reason})',
@@ -735,6 +866,10 @@ const EN = {
735
866
  'session.steerRefusal.advice': '{happened} — {nextStep}',
736
867
  'session.steerRefusal.hostQueue.queued': 'it stays queued and will be submitted as-is when this turn ends',
737
868
  'session.steerRefusal.hostQueue.dropped': 'it was not kept; {nextStep}',
869
+ 'session.interruptRefusal.nothingInFlight': 'The interrupt was not accepted: this run is waiting on a pending decision, so there is no turn in flight to cut · The run itself was not changed and is still waiting · To end it, stop the whole run; to give it a message, send one — it is delivered when the run resumes',
870
+ 'session.interruptRefusal.notHeld': 'The interrupt was not accepted: this server has no live turn it can cut for this run — the run may be running on another server, or on a path that exposes no live turn · The run itself was not changed · To end it, stop the whole run',
871
+ 'session.interruptRefusal.notRunning': 'The interrupt was not accepted: this run is not running any more — it has just finished, or it no longer takes an interrupt · Nothing was cut or changed · Check its current state before doing anything else',
872
+ 'session.interruptRefusal.unrecognised': 'The interrupt was not accepted, for a reason this version cannot name · Do not assume the run has stopped or that any turn was cut · Check its current state; if this keeps happening, report the error code (if the engine gave one)',
738
873
  'session.permissionModeSwitch.applied': 'The running turn now uses the {mode} permission mode.',
739
874
  'session.permissionModeSwitch.folded': 'The running turn now uses the {mode} permission mode instead of the one you chose — {reason}.',
740
875
  'session.permissionModeSwitch.reason.entryFloor': 'this deployment does not allow a looser mode than its floor',
@@ -871,6 +1006,8 @@ const EN = {
871
1006
  'notice.failure.headline.parked': 'The event stream ended while the run had not reached a terminal state — the run is likely parked waiting for a decision, not crashed. Check its status and decide anything pending; the turn did not complete here.',
872
1007
  'notice.failure.headline.internal': 'This client hit an internal error — it is a bug in the client, not an engine outage, and the turn did not complete.',
873
1008
  'notice.failure.headline.causeUnreadable': 'The reason for this failure could not be read (part of the error object was unreadable) — it is not known whether the engine received your message. Check the run’s status, or reattach to it, before sending it again.',
1009
+ 'notice.streamEnded.emptyLegs.headline': 'The event stream came back empty twice in a row and ended while the run had not reached a terminal state — the run is likely parked waiting for a decision, not crashed. Check its status and decide anything pending; the turn did not complete here.',
1010
+ 'notice.streamEnded.consecutiveFailures.headline': 'The event stream kept ending without progress and the client stopped re-opening it — it is not known whether the run is still going or is waiting for a decision. Check its status, or reattach to it, before sending again; the turn did not complete here.',
874
1011
  'notice.failure.quota.fiveHour': 'Your 5-hour quota is used up',
875
1012
  'notice.failure.quota.weekly': 'Your weekly quota is used up',
876
1013
  'notice.failure.quota.budgetPersonal': 'Your personal budget is used up',
@@ -1017,6 +1154,24 @@ const EN = {
1017
1154
  'notice.wireRefusal.autonomyLane': 'The engine did not start this leader run: this deployment runs in plan-only autonomy, and a leader run has no way to have its plan reviewed, so nothing was started · Submit the work as a regular run instead, or ask whoever operates the engine to change its autonomy setting',
1018
1155
  'notice.wireRefusal.sessionArchiveStamped': "This session's stored archive still carries an owner stamp written by an earlier server version, so it cannot be forked or have its log replaced; nothing was written · Delete the session and push it again",
1019
1156
  'notice.wireRefusal.sessionArchiveStamped.fork': "This session's stored archive still carries an owner stamp written by an earlier server version, so it cannot be forked or have its log replaced; nothing was written · This conversation keeps running on its own history; to fork it, delete the session and push it again",
1157
+ 'notice.wireRefusal.envCredential': 'The engine did not accept this request: its settings.env carries credentials, and the engine does not take credentials from a request',
1158
+ 'notice.wireRefusal.envCredential.folded': 'This parked work cannot continue: the request saved for it carries credentials in settings.env, and the engine does not take credentials from a request; nothing was resumed',
1159
+ 'notice.wireRefusal.envCredential.names': 'Entries: {names}',
1160
+ 'notice.wireRefusal.envCredential.remedy': "Put the credentials in the engine's own process environment, then send the request again without those entries",
1161
+ 'notice.wireRefusal.sessionIdRetired': 'The engine did not accept this request: its session id belonged to a session that was deleted on this server, and work under that id now runs only for the session\'s earlier owner · Use a new session',
1162
+ 'notice.wireRefusal.sessionIdRetired.folded': 'This parked work cannot continue: its session id belonged to a session that was deleted on this server, and work under that id now runs only for the session\'s earlier owner; nothing was resumed and the card is still waiting',
1163
+ 'notice.wireRefusal.runConcurrencyCap.head': 'This deployment already has as many runs in flight as it allows, so the engine did not accept this request · Nothing is wrong with the request itself',
1164
+ 'notice.wireRefusal.runConcurrencyCap.unknownWait': 'Send it again once one of the runs in flight has finished',
1165
+ 'notice.wireRefusal.unreadMembers': 'The engine did not accept this request: it carries {part} that this server version cannot read as written, and running it would silently leave that part out',
1166
+ 'notice.wireRefusal.unreadMembers.folded': 'This parked work cannot continue: the request saved for it carries {part} that this server version cannot read as written, and continuing would silently leave that part out; nothing was resumed and the card is still waiting',
1167
+ 'notice.wireRefusal.unreadMembers.where': 'Where: {where}',
1168
+ 'notice.wireRefusal.unreadMembers.remedy': 'Send the request again with that part in the current form',
1169
+ 'notice.wireRefusal.unreadMembers.folded.remedy': 'Cancel the work if it is still suspended, then submit it again as a new request with that part in the current form',
1170
+ 'notice.wireRefusal.unreadMembers.part.settingsHooks': 'hook settings',
1171
+ 'notice.wireRefusal.unreadMembers.part.settingsEnv': 'environment variables',
1172
+ 'notice.wireRefusal.unreadMembers.part.settingsOther': 'a setting',
1173
+ 'notice.wireRefusal.unreadMembers.part.mcpTransport': "an MCP server's connection settings",
1174
+ 'notice.wireRefusal.unreadMembers.part.a2aHeaders': "an A2A peer's request headers",
1020
1175
  'notice.wireRefusal.unsupportedRule': 'The engine refused this request, so none of it took effect: a rule in it is a form the engine does not support — {detail} · Remove or rewrite that rule (to stop a tool altogether, write its name alone), then send it again',
1021
1176
  'notice.wireRefusal.unsupportedRule.other': 'The engine refused this request, so none of it took effect: {count} rules in it are forms the engine does not support — {detail} · Remove or rewrite those rules (to stop a tool altogether, write its name alone), then send it again',
1022
1177
  'notice.wireRefusal.unsupportedRule.stored': 'The engine refused to continue this work: the request stored for it has a rule in it that is a form the engine does not support — {detail} · It cannot continue as stored. Remove or rewrite that rule (to stop a tool altogether, write its name alone), cancel the work if it is still suspended, then submit it again as a new request',
@@ -1078,15 +1233,20 @@ const EN = {
1078
1233
  'session.subagent.delegatedPrompt.absence.forbidden': "This subagent's prompt cannot be shown: the engine refused access to its conversation.",
1079
1234
  'session.subagent.delegatedPrompt.absence.promptAbsent': "This subagent's conversation was read, but it holds no delegated prompt to show.",
1080
1235
  'session.subagent.delegatedPrompt.absence.unknown': "This subagent's prompt could not be read just now.",
1236
+ 'rules.sessionPolicy.remove.loosenForbiddenStem': 'The engine refused to take these entries out of this session’s rule record, so the record is unchanged: it counts at least one of them as written by an operator rather than added by the session’s owner, and an owner can take back only the entries the owner added.',
1237
+ 'rules.sessionPolicy.remove.loosenForbidden': '{stem} Ask an operator to remove them, or continue in a new session.',
1081
1238
  'rules.sessionPolicy.tighten.unknown.sessionOwnerless.noIdentity': 'This session has no owner, so a rule written for it could never be read back; nothing was written.',
1082
1239
  'rules.sessionPolicy.tighten.unknown.storeCorrupt.noOperator': '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 deployment has no operator to look at the rule store, so whoever runs it has to.',
1083
1240
  'rules.sessionPolicy.deployment.noOperator.readStoreCorrupt': 'The engine could not establish which version this session’s rules are at, so it would not hand the record over. This deployment has no operator to look at the rule store — whoever runs it has to.',
1084
- 'rules.sessionPolicy.deployment.noOperator.removeLoosenForbidden': 'The engine refused to take these entries out of this session’s rule record: on this engine only an operator can remove entries from it, and this deployment has none, so the record is unchanged. Continue in a new session.',
1241
+ 'rules.sessionPolicy.deployment.noOperator.removeLoosenForbidden': '{stem} This deployment has no operator to remove them. Continue in a new session.',
1085
1242
  'rules.sessionPolicy.deployment.noOperator.removeReadStoreCorrupt': 'The engine could not establish which version this session’s rules are at, so nothing was changed. This deployment has no operator to look at the rule store — whoever runs it has to.',
1086
1243
  'rules.sessionPolicy.deployment.noOperator.removeWriteStoreCorrupt': 'The engine could not establish which version this session’s rules are at and refused to stamp a new one, so nothing was changed. This deployment has no operator to look at the rule store — whoever runs it has to.',
1087
1244
  'config.hooks.plan.reason.compactionLocalFallback': 'this compaction is summarized on this client because the engine session is unavailable, so the engine will not run it and this client runs it itself',
1088
1245
  'config.hooks.plan.reason.keyNotRead': 'the connected server does not read a key written on this hook (remove the key, or use a server that reads it)',
1089
1246
  'config.hooks.plan.disableAllHooks': 'All hooks are turned off by managed settings (disableAllHooks).',
1247
+ 'config.hooks.plan.reason.closedUntrusted': 'this workspace is not trusted, so no hooks run in it',
1248
+ 'config.hooks.plan.reason.closedGovernanceUnreadable': 'the managed policy could not be read, so no hooks run this turn',
1249
+ 'config.hooks.plan.reason.closedDisableAll': 'managed settings turn off all hooks (disableAllHooks)',
1090
1250
  'config.hooks.plan.keyNotRead.oneKey': '{layer}: {hooks} will not run — the connected server does not read the key {coordinates}. Remove the key, or use a server that reads it.',
1091
1251
  'config.hooks.plan.keyNotRead.manyKeys': '{layer}: {hooks} will not run — the connected server does not read the keys {coordinates}. Remove those keys, or use a server that reads them.',
1092
1252
  'config.hooks.plan.keyNotRead.more': '{shown} and {rest} more',
@@ -1133,8 +1293,11 @@ const EN = {
1133
1293
  'config.mods.loader.failed': '{name} could not be loaded: {reason}',
1134
1294
  'config.mods.loader.failedNoReason': '{name} could not be loaded',
1135
1295
  'config.mods.refusal.by': 'Refused by {by}',
1296
+ 'config.mods.request.by': 'Requested by {by}',
1136
1297
  'config.mods.rewrite.resultInPlace': 'Answered by {by} in place of the tool',
1137
1298
  'config.mods.rewrite.inputBy': 'Arguments changed by {by} before the call was let through',
1299
+ 'config.mods.session.unreadable': "The mods used by this conversation's last run couldn't be read",
1300
+ 'config.mods.session.unarmed': 'Mods show up here once this conversation has run on this engine',
1138
1301
  'follow.notFollowed.headRun': 'This screen is no longer following run {taskId}{reason}{ending}{exit}',
1139
1302
  'follow.notFollowed.headTurn': "This screen is no longer following this turn's run{reason}{ending}{exit}",
1140
1303
  'follow.notFollowed.reason.exhaustedDraining': ": the engine instance serving it was going down when its last event stream closed, and this client's re-attach allowance has run out.",
@@ -1169,5 +1332,94 @@ const EN = {
1169
1332
  'approval.planReview.decision.gateUntrusted': "The engine could not recognise this review's gate id (the server's record of it looks damaged; an operator should check it). The card still shows the plan that is waiting: answering again sends the answer without the gate id, and that answer is not protected against the plan having changed.",
1170
1333
  'approval.planReview.option.askAgain.label': 'No, ask for the plan to be presented again',
1171
1334
  'approval.planReview.option.askAgain.description': 'Do not approve; ask the model to present the plan again',
1335
+ 'localEngine.behind.cliUpdate': 'The local engine (version {running}) is newer than this Sema ({own}), so this Sema cannot start new work on it. Run `sema update`, then reopen this session.',
1336
+ 'localEngine.behind.appUpdate': 'The local engine (version {running}) is newer than this Sema ({own}), so this Sema cannot start new work on it. Update this app to version {running} or later, then restart it.',
1337
+ 'localEngine.versionUnknown': "The local engine's version could not be read, so it will not be replaced automatically.",
1338
+ 'localEngine.legacyBelowFloor': 'The local engine (version {running}) is older than the oldest version this Sema supports ({floor}); it has to be replaced before this Sema can use it.',
1339
+ 'localEngine.card.title.version': 'Replace the local engine with the newer version?',
1340
+ 'localEngine.card.title.config': 'Restart the local engine to apply the changed configuration?',
1341
+ 'localEngine.card.title.credential': 'Restart the local engine to use the changed credentials?',
1342
+ 'localEngine.card.title.modelDefault': 'Restart the local engine to apply the changed default model?',
1343
+ 'localEngine.card.title.user': 'Restart the local engine now?',
1344
+ 'localEngine.card.title.unresponsive': 'The local engine is not responding. Restart it?',
1345
+ 'localEngine.card.versions': 'Running engine: version {running}. This Sema: version {own}.',
1346
+ 'localEngine.card.others.one': '{total} other Sema client is using the engine ({midTurn} in the middle of a turn).',
1347
+ 'localEngine.card.others.other': '{total} other Sema clients are using the engine ({midTurn} in the middle of a turn).',
1348
+ 'localEngine.card.others.unknown': 'Other Sema clients using the engine: could not be read.',
1349
+ 'localEngine.card.inflight.one': '{count} run is in progress on the engine.',
1350
+ 'localEngine.card.inflight.other': '{count} runs are in progress on the engine.',
1351
+ 'localEngine.card.inflight.unknown': 'Runs in progress on the engine: could not be read.',
1352
+ 'localEngine.card.background.one': '{count} background task or workflow is running.',
1353
+ 'localEngine.card.background.other': '{count} background tasks or workflows are running.',
1354
+ 'localEngine.card.background.unknown': 'Background tasks and workflows: could not be read.',
1355
+ 'localEngine.card.overlap': 'A run that is running in the background may be counted in both lines above.',
1356
+ 'localEngine.card.selfUnknown': 'What this Sema is doing right now could not be read.',
1357
+ 'localEngine.card.parked': "If you go ahead now, work in progress ends by being parked or interrupted. Parked work continues under the engine's durable resume, the same guarantee as when the engine stops on its own; until it is resumed or cancelled in its session, new messages to that session are refused.",
1358
+ 'localEngine.card.force': 'Go ahead now: work in progress ends within about {seconds} seconds.',
1359
+ 'localEngine.card.wait': 'Not now: the current engine keeps running.',
1360
+ 'localEngine.exitFate.peers': 'The local engine keeps running: other Sema clients are still using it.',
1361
+ 'localEngine.exitFate.lease': 'The local engine keeps running for now and stops by itself once nothing is using it.',
1362
+ 'localEngine.exitFate.unknown': 'The local engine keeps running; whether other Sema clients are still using it could not be read.',
1363
+ 'localEngine.principalOverrideIgnored': 'The principal set in the environment (`SEMA_LIVE_PRINCIPAL`) does not apply to the local engine; Sema uses the one in the env block of your settings, so every Sema app on this computer acts as the same principal. To change it, change it in your settings.',
1364
+ 'localEngine.principalUnknown': 'Sema could not read {layer}, so local sessions are paused: the principal they run as may be set there. Fix that file, then restart Sema.',
1365
+ 'localEngine.settingsLayer.userSettings': 'your settings file',
1366
+ 'localEngine.settingsLayer.flagSettings': 'the settings file given at startup',
1367
+ 'localEngine.settingsLayer.policySettings': 'the managed settings',
1368
+ 'localEngine.settingsLayer.unspecified': 'a settings file',
1369
+ 'localEngine.bootRefusal': 'The local engine refused to start: {reason}',
1370
+ 'localEngine.firstShare': "Sema now shares one local engine with the other Sema apps on this computer. Local sessions from this app's earlier private engine are not shown in the list; their data has been left in place.",
1371
+ 'localEngine.phase.starting': 'Starting the local engine…',
1372
+ 'localEngine.phase.dormant': 'The local engine is not running; it starts when a session needs it.',
1373
+ 'localEngine.phase.draining': 'The local engine is finishing its work before it stops; Sema reconnects when it is back.',
1374
+ 'localEngine.phase.unanswered': "A process holds the local engine's port but is not answering; Sema is waiting for it.",
1375
+ 'localEngine.phase.unverifiable': "A process answers on the local engine's port but its identity cannot be verified, so Sema neither starts a second engine nor stops it.",
1376
+ 'localEngine.phase.pendingBlocked': 'This Sema cannot use the running local engine until it is replaced.',
1377
+ 'localEngine.phase.swappingIdle': 'Replacing the local engine while nothing is using it…',
1378
+ 'localEngine.phase.swappingForced': 'Replacing the local engine now; work in progress is being parked or interrupted.',
1379
+ 'localEngine.waitingPeer': 'Another Sema is starting or replacing the local engine; waiting for it.',
1380
+ 'localEngine.banner.pending': 'A local engine restart is pending; it happens once nothing is using the engine.',
1381
+ 'localEngine.down.lockUnavailable': 'Another Sema holds the local engine start lock and did not finish in time; try again.',
1382
+ 'localEngine.down.spawnFailed': 'The local engine did not start.',
1383
+ 'localEngine.down.spawnRefused': 'The local engine was not started: the preparation step did not pass.',
1384
+ 'localEngine.down.stopFailed': 'The old local engine did not stop in time, so it was not replaced.',
1385
+ 'localEngine.down.crashLoop': 'The local engine keeps stopping unexpectedly, so automatic restarts are paused.',
1386
+ 'localEngine.down.highWaterUnreadable': 'The record of the newest engine version used on this machine cannot be read, so the local engine is not started; check the engine data directory.',
1387
+ 'localEngine.crashLoop.retry': 'The local engine keeps stopping unexpectedly; Sema tries again in about {seconds} seconds.',
1388
+ 'localEngine.crashLoop.stopped': 'The local engine keeps stopping unexpectedly; Sema has stopped retrying on its own. Restart it manually.',
1389
+ 'localEngine.crashLoop.retrying': 'Trying to start the local engine again.',
1390
+ 'localEngine.drainOverdue': 'The local engine is taking longer than expected to finish its work.',
1391
+ 'localEngine.engineExited.unexpected': 'The local engine stopped unexpectedly; Sema starts it again when it is needed.',
1392
+ 'localEngine.engineExited.crashLoop': 'The local engine stopped unexpectedly again; automatic restarts are paused.',
1393
+ 'localEngine.engineExited.quiet': 'The local engine exited; Sema starts it again when it is needed.',
1394
+ 'localEngine.cannotVerifyEngine': 'The running local engine cannot be verified, so Sema will not stop it.',
1395
+ 'localEngine.lockUnavailable': 'Another Sema holds the local engine start lock; the current engine keeps running.',
1396
+ 'localEngine.prepareFailed.reason': 'The local engine was not replaced; the current engine keeps running. Reason: {reason}',
1397
+ 'localEngine.prepareFailed.timeout': 'The local engine was not replaced because preparing the replacement took too long; the current engine keeps running.',
1398
+ 'localEngine.spawnFailed.timeout': 'The new local engine did not answer in time.',
1399
+ 'localEngine.lockLost': 'Sema lost the local engine start lock; it sends no further signals and checks again.',
1400
+ 'localEngine.forcedLine': 'The local engine was replaced now; work that was in progress was parked or interrupted.',
1401
+ 'localEngine.headless.behind': 'The local engine is newer than this Sema; update Sema and run the command again.',
1402
+ 'localEngine.headless.legacyBelowFloor': 'The local engine is older than this Sema supports; open Sema interactively to replace it, then run the command again.',
1403
+ 'localEngine.headless.unresponsive': 'The local engine is not responding; open Sema interactively to restart it, then run the command again.',
1404
+ 'localEngine.headless.swapPending': 'The local engine has to be restarted before this command can run; open Sema interactively to confirm, then run the command again.',
1405
+ 'localEngine.headless.drainOverdue': 'The local engine did not finish stopping in time; run the command again later.',
1406
+ 'localEngine.headless.unverifiable': "A process answers on the local engine's port but its identity cannot be verified; the command stops here.",
1407
+ 'localEngine.restartOutcome.skippedNoDemand': 'The change takes effect the next time the local engine starts.',
1408
+ 'localEngine.restartOutcome.pendingCard': 'Other sessions are using the local engine; confirm the restart on the card.',
1409
+ 'localEngine.restartOutcome.pendingBusy': 'Other sessions are using the local engine; it restarts once nothing is using it.',
1410
+ 'localEngine.restartOutcome.failedPrepare': 'The local engine was not restarted; the current engine keeps running.',
1411
+ 'localEngine.restartOutcome.failedDown': 'The local engine could not be restarted: {detail}',
1412
+ 'session.devices.repoint.done': "Done: this machine's device record and sessions now follow the new engine address. The device kept its identity — nothing was enrolled again.",
1413
+ 'session.devices.repoint.unverified': "Nothing was changed: the new address could not be confirmed to hold this device. If it is the same engine, check that you are signed in as the device's owner and try again. Otherwise enroll this machine again at the engine's own address, then remove the old device from the engine's device list.",
1414
+ 'session.devices.repoint.undetermined': "Nothing was changed: a check against the new address could not be read, so it is not known whether this device is registered there. Try again. Or enroll this machine again at the engine's own address, then remove the old device from the engine's device list.",
1415
+ 'session.devices.repoint.partial': 'The device record now follows the new address, but not every session could be updated. Run the same command again to finish — sessions that were already updated are left as they are.',
1416
+ 'session.devices.repoint.storeFailed': "The device record could not be moved, so nothing was changed. Run the command again; if it keeps failing, enroll this machine again at the engine's own address.",
1417
+ 'session.devices.repoint.refused.addressInvalid': 'Nothing was changed: an address is not usable. Give the full https:// address of the engine (plain http:// is only accepted for this machine).',
1418
+ 'session.devices.repoint.refused.sameAddress': 'Nothing was changed: the new address is the same engine address as the old one.',
1419
+ 'session.devices.repoint.refused.recordAbsent': 'Nothing was changed: this machine has no device record for the old address.',
1420
+ 'session.devices.repoint.refused.recordNotActive': "Nothing was changed: the device record for this address is not an active enrollment (it is still being enrolled, or the device was removed). Enroll again at the engine's own address.",
1421
+ 'session.devices.repoint.refused.recordUnreadable': 'Nothing was changed: a device record could not be read, so it was left alone.',
1422
+ 'session.devices.repoint.refused.targetOccupied': 'Nothing was changed: this machine already has a different device record for the new address.',
1423
+ 'session.devices.repoint.refused.unarmed': 'Nothing was changed: this app is not set up to move the device record and its sessions.',
1172
1424
  };
1173
1425
  export const EN_MESSAGES = Object.freeze(EN);