@sema-agent/client-core 0.95.0 → 0.96.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 (181) hide show
  1. package/CHANGELOG.md +180 -0
  2. package/README.md +49 -25
  3. package/dist/adapt/arms.js +7 -1
  4. package/dist/adapt/toolCards.d.ts +1 -0
  5. package/dist/adapt/toolCards.js +16 -3
  6. package/dist/adapt/wireShapes.js +2 -16
  7. package/dist/adapter/activeRunSelfHeal.d.ts +4 -0
  8. package/dist/adapter/activeRunSelfHeal.js +30 -4
  9. package/dist/adapter/downstream/eventToSdkMessage.js +11 -3
  10. package/dist/adapter/downstream/terminalToSdkResult.js +8 -9
  11. package/dist/adapter/runStream.js +30 -47
  12. package/dist/agentSession/engineAgentRegistryRead.js +5 -4
  13. package/dist/agentSession/engineSessionBackgroundStop.js +22 -15
  14. package/dist/agentsWireCaps.js +13 -2
  15. package/dist/callerCwdCapability.d.ts +0 -4
  16. package/dist/callerCwdCapability.js +0 -6
  17. package/dist/centerWiringCapability.d.ts +0 -4
  18. package/dist/centerWiringCapability.js +0 -6
  19. package/dist/classifierVerdictWire.js +4 -16
  20. package/dist/clientSlice.js +1 -1
  21. package/dist/cloudConfigWireCaps.d.ts +3 -3
  22. package/dist/cloudConfigWireCaps.js +65 -45
  23. package/dist/coreValuePorts.d.ts +11 -7
  24. package/dist/coreValuePorts.js +5 -8
  25. package/dist/credentialProvenance.d.ts +28 -0
  26. package/dist/credentialProvenance.js +76 -0
  27. package/dist/decideFailureNote.js +3 -1
  28. package/dist/decideReceipt.js +7 -10
  29. package/dist/declared/supportFloorDeclared.js +3 -3
  30. package/dist/displayUntrusted.d.ts +7 -3
  31. package/dist/displayUntrusted.js +356 -60
  32. package/dist/engineCapsCache.d.ts +6 -0
  33. package/dist/engineCapsCache.js +226 -32
  34. package/dist/engineDirectory.d.ts +79 -0
  35. package/dist/engineDirectory.js +186 -0
  36. package/dist/engineErrorCodes.d.ts +14 -1
  37. package/dist/engineErrorCodes.js +37 -15
  38. package/dist/engineNoticeCodes.d.ts +17 -0
  39. package/dist/engineNoticeCodes.js +57 -3
  40. package/dist/engineWordRenames.d.ts +8 -0
  41. package/dist/engineWordRenames.js +13 -0
  42. package/dist/fileHistoryCaptureCapability.d.ts +14 -0
  43. package/dist/fileHistoryCaptureCapability.js +70 -0
  44. package/dist/fleet/bgSubagentRow.d.ts +15 -0
  45. package/dist/fleet/bgSubagentRow.js +67 -0
  46. package/dist/fleet/fleetLedger.d.ts +1 -0
  47. package/dist/fleet/fleetLedger.js +103 -89
  48. package/dist/fleet/fleetProjection.d.ts +1 -0
  49. package/dist/fleet/fleetProjection.js +10 -3
  50. package/dist/fleetTaskDesc.js +4 -17
  51. package/dist/gateOutcome.d.ts +12 -1
  52. package/dist/gateOutcome.js +58 -1
  53. package/dist/gateVocabulary.d.ts +7 -2
  54. package/dist/gateVocabulary.js +5 -1
  55. package/dist/generated/engineAskFaceTables.js +1 -1
  56. package/dist/generated/engineFactTables.d.ts +5 -3
  57. package/dist/generated/engineFactTables.js +17 -4
  58. package/dist/generated/engineNoticeTables.js +12 -3
  59. package/dist/generated/settingsSchemaFns.d.ts +3 -0
  60. package/dist/generated/settingsSchemaFns.js +53 -0
  61. package/dist/generated/toolNameTables.d.ts +1 -0
  62. package/dist/generated/toolNameTables.js +1 -0
  63. package/dist/hitl/approvalEndingCause.d.ts +2 -0
  64. package/dist/hitl/approvalEndingCause.js +31 -21
  65. package/dist/hitl/askParkRowRouting.js +1 -1
  66. package/dist/hitl/automaticAnswerVerdict.d.ts +1 -1
  67. package/dist/hitl/automaticAnswerVerdict.js +13 -8
  68. package/dist/hitl/decisionConflict.js +0 -2
  69. package/dist/hitl/decisionRefusal.d.ts +8 -0
  70. package/dist/hitl/decisionRefusal.js +48 -14
  71. package/dist/hitl/frameRouter.d.ts +0 -1
  72. package/dist/hitl/frameRouter.js +6 -14
  73. package/dist/hitl/hitlBridge.d.ts +6 -2
  74. package/dist/hitl/hitlBridge.js +28 -7
  75. package/dist/hitl/localAllowRule.d.ts +1 -0
  76. package/dist/hitl/localAllowRule.js +2 -2
  77. package/dist/hitl/noAllowCause.d.ts +2 -1
  78. package/dist/hitl/noAllowCause.js +3 -2
  79. package/dist/hitl/parkResolver.d.ts +1 -0
  80. package/dist/hitl/parkResolver.js +8 -54
  81. package/dist/hitl/parkRowBirthWait.d.ts +1 -0
  82. package/dist/hitl/parkRowBirthWait.js +2 -2
  83. package/dist/hitl/planReviewWire.d.ts +1 -0
  84. package/dist/hitl/planReviewWire.js +98 -20
  85. package/dist/hitl/replayedApproval.d.ts +1 -0
  86. package/dist/hitl/replayedApproval.js +14 -0
  87. package/dist/hitl/sessionPolicyDeliverable.js +8 -6
  88. package/dist/hitl/standingRows.d.ts +18 -0
  89. package/dist/hitl/standingRows.js +127 -0
  90. package/dist/hitl/toolApprovalWire.d.ts +15 -3
  91. package/dist/hitl/toolApprovalWire.js +238 -25
  92. package/dist/hookMatcherVerdict.d.ts +1 -9
  93. package/dist/hookMatcherVerdict.js +21 -61
  94. package/dist/hooksWireCaps.js +2 -2
  95. package/dist/hostCallbackGuard.d.ts +1 -0
  96. package/dist/hostCallbackGuard.js +6 -0
  97. package/dist/index.d.ts +21 -9
  98. package/dist/index.js +17 -8
  99. package/dist/mcpProbeCapability.d.ts +0 -4
  100. package/dist/mcpProbeCapability.js +0 -6
  101. package/dist/memoryComplianceCapability.d.ts +0 -4
  102. package/dist/memoryComplianceCapability.js +0 -6
  103. package/dist/memoryOriginCapability.d.ts +0 -4
  104. package/dist/memoryOriginCapability.js +0 -6
  105. package/dist/memorySpecWire.js +2 -2
  106. package/dist/modelIdentityResolvability.d.ts +2 -2
  107. package/dist/modelIdentityResolvability.js +12 -3
  108. package/dist/noticePresentation.d.ts +68 -0
  109. package/dist/noticePresentation.js +247 -0
  110. package/dist/outputStyleSeatCapability.d.ts +0 -1
  111. package/dist/outputStyleSeatCapability.js +0 -3
  112. package/dist/ownKey.d.ts +2 -0
  113. package/dist/ownKey.js +18 -0
  114. package/dist/peerFrames.js +13 -9
  115. package/dist/permissionModesCapability.d.ts +0 -4
  116. package/dist/permissionModesCapability.js +0 -6
  117. package/dist/permissionRuleIssue.js +0 -3
  118. package/dist/permissionsDeclaration.d.ts +2 -0
  119. package/dist/permissionsDeclaration.js +56 -41
  120. package/dist/printPermissionOutcome.d.ts +12 -0
  121. package/dist/printPermissionOutcome.js +50 -0
  122. package/dist/printToolResultFrame.d.ts +1 -0
  123. package/dist/printToolResultFrame.js +5 -9
  124. package/dist/promptBlockedCopy.d.ts +5 -0
  125. package/dist/promptBlockedCopy.js +35 -0
  126. package/dist/protocolSegment.d.ts +9 -6
  127. package/dist/protocolSegment.js +31 -21
  128. package/dist/providerRejection.d.ts +4 -0
  129. package/dist/providerRejection.js +75 -14
  130. package/dist/replayBody.d.ts +12 -0
  131. package/dist/replayBody.js +25 -0
  132. package/dist/resumeRefusalCopy.js +5 -21
  133. package/dist/retryStatus.d.ts +9 -1
  134. package/dist/retryStatus.js +9 -2
  135. package/dist/rewindArchiveCapability.d.ts +3 -13
  136. package/dist/rewindArchiveCapability.js +7 -58
  137. package/dist/rewindArchiveReading.d.ts +15 -0
  138. package/dist/rewindArchiveReading.js +56 -0
  139. package/dist/ruleCompileVerdict.d.ts +9 -1
  140. package/dist/ruleCompileVerdict.js +29 -4
  141. package/dist/runTerminal.d.ts +15 -1
  142. package/dist/runTerminal.js +56 -8
  143. package/dist/sandboxWire.js +13 -0
  144. package/dist/sealedKeyCapability.d.ts +0 -4
  145. package/dist/sealedKeyCapability.js +0 -6
  146. package/dist/seam.js +4 -2
  147. package/dist/seatContract.d.ts +73 -11
  148. package/dist/seatContract.js +195 -14
  149. package/dist/sessionReadRedactionCapability.d.ts +0 -4
  150. package/dist/sessionReadRedactionCapability.js +0 -6
  151. package/dist/sessionSyncFileHistory.d.ts +4 -0
  152. package/dist/sessionSyncFileHistory.js +66 -0
  153. package/dist/sessionSyncFileHistoryCapability.d.ts +0 -1
  154. package/dist/sessionSyncFileHistoryCapability.js +0 -3
  155. package/dist/skillToolListsCapability.d.ts +0 -1
  156. package/dist/skillToolListsCapability.js +0 -3
  157. package/dist/steerPriorityCapability.d.ts +0 -1
  158. package/dist/steerPriorityCapability.js +0 -3
  159. package/dist/storePostureCapability.d.ts +0 -4
  160. package/dist/storePostureCapability.js +0 -6
  161. package/dist/subagent/engineSubagentSteer.js +7 -5
  162. package/dist/subagentContentStore.js +4 -15
  163. package/dist/supportFloor.d.ts +1 -0
  164. package/dist/supportFloor.js +13 -9
  165. package/dist/systemReminderTag.d.ts +1 -0
  166. package/dist/systemReminderTag.js +8 -0
  167. package/dist/toolHistoryMismatch.d.ts +0 -3
  168. package/dist/toolHistoryMismatch.js +3 -7
  169. package/dist/toolResult.d.ts +1 -1
  170. package/dist/toolResult.js +2 -1
  171. package/dist/toolResultContent.d.ts +2 -0
  172. package/dist/toolResultContent.js +63 -0
  173. package/dist/usageAnalytics.js +40 -16
  174. package/dist/userInvokedSkillsCapability.d.ts +0 -1
  175. package/dist/userInvokedSkillsCapability.js +0 -3
  176. package/dist/wireErrorTriage.d.ts +2 -0
  177. package/dist/wireErrorTriage.js +34 -5
  178. package/dist/wireFailureShape.d.ts +19 -2
  179. package/dist/wireFailureShape.js +55 -50
  180. package/docs/INTEGRATION-CLIENTS.md +1262 -17
  181. package/package.json +5 -5
@@ -13,6 +13,10 @@ import { projectTasks, projectWorkflows, wireCycleSeq, wireParentId, } from './f
13
13
  import { isInStreamDrainingEnd } from '../wireErrorTriage.js';
14
14
  import { cycleSeqOrder, cycleSeqValue } from '../cycleOrder.js';
15
15
  export const TERMINAL_RETAIN_MS = 60_000;
16
+ function hasRowId(row) {
17
+ const id = row?.id;
18
+ return typeof id === 'string' && id.length > 0;
19
+ }
16
20
  const liveBgViews = new Map();
17
21
  function viewsFor(sessionKey) {
18
22
  return liveBgViews.get(sessionKey) ?? new Set();
@@ -111,6 +115,25 @@ export function createFleetLedger(hooks = {}, opts = {}) {
111
115
  }
112
116
  cycleWatermark.set(tail, gen);
113
117
  }
118
+ const settledTerminal = new Map();
119
+ const SETTLED_TERMINAL_MAX = 512;
120
+ function noteSettledTerminal(tail, row) {
121
+ if (tail.length === 0 || typeof row.status !== 'string')
122
+ return;
123
+ const gen = wireCycleSeq(row);
124
+ const recordedGen = settledTerminal.get(tail)?.cycleSeq;
125
+ if (cycleSeqOrder(gen, recordedGen) === 'before')
126
+ return;
127
+ if (cycleSeqOrder(gen, cycleWatermark.get(tail)) === 'before')
128
+ return;
129
+ settledTerminal.delete(tail);
130
+ if (settledTerminal.size >= SETTLED_TERMINAL_MAX) {
131
+ const oldest = settledTerminal.keys().next().value;
132
+ if (oldest !== undefined)
133
+ settledTerminal.delete(oldest);
134
+ }
135
+ settledTerminal.set(tail, { status: row.status, cycleSeq: gen });
136
+ }
114
137
  let droppedMalformed = 0;
115
138
  let droppedUnknownFrame = 0;
116
139
  let droppedForeignBgNotification = 0;
@@ -140,28 +163,48 @@ export function createFleetLedger(hooks = {}, opts = {}) {
140
163
  ...(typeof r.name === 'string' && r.name.length > 0 ? { name: r.name } : {}),
141
164
  status: r.status ?? 'unknown',
142
165
  ...(parentId !== undefined ? { parentId } : {}),
166
+ ...(typeof r.sourceLane === 'string' && r.sourceLane.length > 0 ? { sourceLane: r.sourceLane } : {}),
143
167
  ...(retired ? { retiredByNotification: true } : {}),
144
168
  };
145
169
  };
170
+ function settleTerminalRow(row, receivedAtMs) {
171
+ taskMap.delete(row.id);
172
+ rowMeta.delete(row.id);
173
+ retained.set(row.id, { row, expireAt: receivedAtMs + TERMINAL_RETAIN_MS });
174
+ const tail = rowIdTail(row.id);
175
+ for (const id of [...retained.keys()]) {
176
+ if (id !== row.id && rowIdTail(id) === tail)
177
+ retained.delete(id);
178
+ }
179
+ noteSettledTerminal(tail, row);
180
+ }
181
+ function admitRow(row, receivedAtMs) {
182
+ if (isSdkFleetTaskTerminal(row.status)) {
183
+ settleTerminalRow(row, receivedAtMs);
184
+ return;
185
+ }
186
+ taskMap.set(row.id, row);
187
+ rowMeta.set(row.id, { receivedAtMs });
188
+ const tail = rowIdTail(row.id);
189
+ for (const id of [...retained.keys()]) {
190
+ if (rowIdTail(id) === tail)
191
+ retained.delete(id);
192
+ }
193
+ settledTerminal.delete(tail);
194
+ clearBgTerminalFacts(tail);
195
+ }
146
196
  function forgetSettledTerminalRowOf(id) {
147
- const live = taskMap.get(id);
148
- if (live !== undefined && !isSdkFleetTaskTerminal(live.status))
197
+ if (taskMap.has(id))
149
198
  return false;
150
199
  const pooled = retained.get(id);
151
- if (pooled?.retiredByNotification === true)
200
+ if (pooled === undefined || pooled.retiredByNotification === true)
152
201
  return false;
153
- if (live === undefined && pooled === undefined)
154
- return false;
155
- taskMap.delete(id);
156
- rowMeta.delete(id);
157
202
  retained.delete(id);
158
203
  return true;
159
204
  }
160
205
  const bgView = {
161
206
  read: () => {
162
- const rows = [...taskMap.values()]
163
- .filter(r => !isSdkFleetTaskTerminal(r.status))
164
- .map(r => toBgTask(r, false));
207
+ const rows = [...taskMap.values()].map(r => toBgTask(r, false));
165
208
  const nowMs = nowFn();
166
209
  for (const [id, r] of retained) {
167
210
  if (r.retiredByNotification !== true)
@@ -204,33 +247,35 @@ export function createFleetLedger(hooks = {}, opts = {}) {
204
247
  wfMap.clear();
205
248
  rowMeta.clear();
206
249
  const receivedAtMs = nowFn();
250
+ const rows = [];
207
251
  for (const row of frame.tasks) {
208
- taskMap.set(row.id, row);
209
- rowMeta.set(row.id, { receivedAtMs });
210
- if (!isSdkFleetTaskTerminal(row.status)) {
211
- const tail = rowIdTail(row.id);
212
- for (const id of [...retained.keys()]) {
213
- if (rowIdTail(id) === tail)
214
- retained.delete(id);
215
- }
216
- clearBgTerminalFacts(tail);
252
+ if (!hasRowId(row)) {
253
+ droppedMalformed++;
254
+ debug('[fleet-frame] MALFORMED snapshot task row dropped(row 或 row.id 缺席 / 非串)');
255
+ continue;
217
256
  }
257
+ rows.push(row);
218
258
  }
259
+ for (const row of rows)
260
+ if (isSdkFleetTaskTerminal(row.status))
261
+ admitRow(row, receivedAtMs);
262
+ for (const row of rows)
263
+ if (!isSdkFleetTaskTerminal(row.status))
264
+ admitRow(row, receivedAtMs);
219
265
  for (const row of frame.workflows)
220
266
  wfMap.set(row.id, row);
221
267
  break;
222
268
  }
223
269
  case 'task': {
224
270
  const row = frame.row;
225
- if (!row?.id) {
271
+ if (!hasRowId(row)) {
226
272
  droppedMalformed++;
227
- debug('[fleet-frame] MALFORMED task frame dropped(row 或 row.id 缺席)');
273
+ debug('[fleet-frame] MALFORMED task frame dropped(row 或 row.id 缺席 / 非串)');
228
274
  break;
229
275
  }
230
276
  const receivedAtMs = nowFn();
231
- taskMap.set(row.id, row);
277
+ admitRow(row, receivedAtMs);
232
278
  raiseCycleWatermark(rowIdTail(row.id), wireCycleSeq(row));
233
- rowMeta.set(row.id, { receivedAtMs });
234
279
  debug(`[fleet-row] id=${row.id} parent=${row.parentId ?? '-'} agentType=${row.agentType ?? '-'}` +
235
280
  ` agentName=${row.agentName ?? '-'} name=${row.name ?? '-'} status=${row.status ?? '-'}` +
236
281
  ` tokens=${row.tokens ?? '-'} parentToolCallId=${row.parentToolCallId ?? '-'}`);
@@ -252,29 +297,13 @@ export function createFleetLedger(hooks = {}, opts = {}) {
252
297
  recordEngineTranscriptId(rowIdTail(row.id), row.transcriptId);
253
298
  }
254
299
  recordFleetRowAgentType(rowIdTail(row.id), row.agentType);
255
- if (isSdkFleetTaskTerminal(row.status)) {
256
- retained.set(row.id, { row, expireAt: receivedAtMs + TERMINAL_RETAIN_MS });
257
- const tailT = rowIdTail(row.id);
258
- for (const id of [...retained.keys()]) {
259
- if (id !== row.id && rowIdTail(id) === tailT)
260
- retained.delete(id);
261
- }
262
- }
263
- else {
264
- retained.delete(row.id);
265
- const tail = rowIdTail(row.id);
266
- for (const id of [...retained.keys()]) {
267
- if (id !== row.id && rowIdTail(id) === tail)
268
- retained.delete(id);
269
- }
270
- clearBgTerminalFacts(tail);
271
- }
272
300
  break;
273
301
  }
274
302
  case 'task_remove': {
275
303
  const fr = frame;
276
304
  const removedGen = cycleSeqValue(fr.cycleSeq);
277
- const held = taskMap.get(frame.id);
305
+ const pooledHeld = retained.get(frame.id);
306
+ const held = taskMap.get(frame.id) ?? (pooledHeld !== undefined && pooledHeld.retiredByNotification !== true ? pooledHeld.row : undefined);
278
307
  const heldGen = held !== undefined ? wireCycleSeq(held) : undefined;
279
308
  const stale = cycleSeqOrder(removedGen, heldGen) === 'before';
280
309
  const reason = typeof fr.removeReason === 'string' && fr.removeReason.length > 0 ? fr.removeReason : undefined;
@@ -410,43 +439,26 @@ export function createFleetLedger(hooks = {}, opts = {}) {
410
439
  debug(`[fleet-frame] bg_notification stale-cycle ignored(row=${id} row-cycle=${heldGen} notif-seq=${notifSeq})`);
411
440
  continue;
412
441
  }
413
- const rowStatus = known.status ?? '';
414
- if (isSdkFleetTaskTerminal(rowStatus)) {
415
- if (isWashGreen(rowStatus, n.status)) {
416
- washBlocked = true;
417
- debug(`[fleet-frame] bg_notification WASH-GREEN blocked(row=${id} row-status=${rowStatus} notif=${n.status})`);
418
- continue;
419
- }
420
- if (rowStatus !== n.status) {
421
- const upgraded = { ...known, status: coerced };
422
- retained.set(id, { row: upgraded, expireAt: nowMs + TERMINAL_RETAIN_MS });
423
- taskMap.set(id, upgraded);
424
- }
425
- writtenIds.add(id);
426
- applied = true;
427
- }
428
- else {
429
- const started = known.startedAt;
430
- const meta = rowMeta.get(id);
431
- const frozenElapsed = typeof started === 'number' && started > 0 && started <= nowMs
432
- ? nowMs - started
433
- : meta !== undefined && isElapsedBase(known.elapsedMs)
434
- ? known.elapsedMs + Math.max(0, nowMs - meta.receivedAtMs)
435
- : known.elapsedMs;
436
- taskMap.delete(id);
437
- rowMeta.delete(id);
438
- retained.set(id, {
439
- row: {
440
- ...known,
441
- status: coerced,
442
- ...(typeof frozenElapsed === 'number' ? { elapsedMs: frozenElapsed } : {}),
443
- },
444
- expireAt: nowMs + TERMINAL_RETAIN_MS,
445
- retiredByNotification: true,
446
- });
447
- writtenIds.add(id);
448
- applied = true;
449
- }
442
+ const started = known.startedAt;
443
+ const meta = rowMeta.get(id);
444
+ const frozenElapsed = typeof started === 'number' && started > 0 && started <= nowMs
445
+ ? nowMs - started
446
+ : meta !== undefined && isElapsedBase(known.elapsedMs)
447
+ ? known.elapsedMs + Math.max(0, nowMs - meta.receivedAtMs)
448
+ : known.elapsedMs;
449
+ taskMap.delete(id);
450
+ rowMeta.delete(id);
451
+ retained.set(id, {
452
+ row: {
453
+ ...known,
454
+ status: coerced,
455
+ ...(typeof frozenElapsed === 'number' ? { elapsedMs: frozenElapsed } : {}),
456
+ },
457
+ expireAt: nowMs + TERMINAL_RETAIN_MS,
458
+ retiredByNotification: true,
459
+ });
460
+ writtenIds.add(id);
461
+ applied = true;
450
462
  }
451
463
  for (const [id, entry] of retained) {
452
464
  if (writtenIds.has(id))
@@ -480,15 +492,18 @@ export function createFleetLedger(hooks = {}, opts = {}) {
480
492
  (applied ||
481
493
  (!washBlocked &&
482
494
  (() => {
483
- const prior = getBgTerminalFacts(n.taskId);
484
- if (prior === undefined)
485
- return true;
486
- const order = cycleSeqOrder(notifSeq, prior.cycleSeq);
487
- if (order === 'before')
488
- return false;
489
- if (order === 'after')
490
- return true;
491
- return !isWashGreen(prior.status, n.status);
495
+ for (const prior of [getBgTerminalFacts(n.taskId), settledTerminal.get(notifTail)]) {
496
+ if (prior === undefined)
497
+ continue;
498
+ const order = cycleSeqOrder(notifSeq, prior.cycleSeq);
499
+ if (order === 'before')
500
+ return false;
501
+ if (order === 'after')
502
+ continue;
503
+ if (isWashGreen(prior.status, n.status))
504
+ return false;
505
+ }
506
+ return true;
492
507
  })()));
493
508
  if (factsAccepted)
494
509
  raiseCycleWatermark(n.taskId, notifSeq);
@@ -525,8 +540,6 @@ export function createFleetLedger(hooks = {}, opts = {}) {
525
540
  function project(nowMs, opts) {
526
541
  const viewingTaskId = opts.viewingTaskId;
527
542
  const liveRows = [...taskMap.values()].map(r => {
528
- if (isSdkFleetTaskTerminal(r.status))
529
- return r;
530
543
  const started = r.startedAt;
531
544
  if (typeof started === 'number' && started > 0 && started <= nowMs) {
532
545
  return { ...r, elapsedMs: nowMs - started };
@@ -620,6 +633,7 @@ export function createFleetLedger(hooks = {}, opts = {}) {
620
633
  wfMap.clear();
621
634
  rowMeta.clear();
622
635
  retained.clear();
636
+ settledTerminal.clear();
623
637
  contentAnchorSet = false;
624
638
  contentAnchor = undefined;
625
639
  debug(`[fleet-frame] 会话锚变更(${from ?? '-'} → ${to ?? '-'})⇒ 清上一会话的行/留存` +
@@ -30,6 +30,7 @@ export interface FleetTaskView {
30
30
  }>;
31
31
  cycleSeq?: number;
32
32
  retiredBy?: string;
33
+ workspaceSnapshot?: 'failed';
33
34
  }
34
35
  export interface FleetRowUsage {
35
36
  totalTokens?: number;
@@ -132,6 +132,9 @@ function wireRetiredBy(r) {
132
132
  const v = r.retiredBy;
133
133
  return typeof v === 'string' && v.length > 0 ? v : undefined;
134
134
  }
135
+ function wireWorkspaceSnapshot(r) {
136
+ return r.workspaceSnapshot === 'failed' ? 'failed' : undefined;
137
+ }
135
138
  export function wireResumable(r) {
136
139
  return typeof r.resumable === 'boolean' ? r.resumable : undefined;
137
140
  }
@@ -167,6 +170,7 @@ export function projectTasks(allRows, opts) {
167
170
  const editedFiles = wireEditedFiles(r);
168
171
  const cycleSeq = wireCycleSeq(r);
169
172
  const retiredBy = wireRetiredBy(r);
173
+ const workspaceSnapshot = wireWorkspaceSnapshot(r);
170
174
  const task = {
171
175
  id: r.id,
172
176
  name: deriveAgentLabel(r.agentType, r.agentName, r.name, r.id),
@@ -191,6 +195,7 @@ export function projectTasks(allRows, opts) {
191
195
  ...(editedFiles !== undefined ? { editedFiles } : {}),
192
196
  ...(cycleSeq !== undefined ? { cycleSeq } : {}),
193
197
  ...(retiredBy !== undefined ? { retiredBy } : {}),
198
+ ...(workspaceSnapshot !== undefined ? { workspaceSnapshot } : {}),
194
199
  };
195
200
  return task;
196
201
  });
@@ -245,6 +250,7 @@ const FLEET_TASK_VIEW_KEY_TUPLE = [
245
250
  'editedFiles',
246
251
  'cycleSeq',
247
252
  'retiredBy',
253
+ 'workspaceSnapshot',
248
254
  ];
249
255
  export const FLEET_TASK_VIEW_KEYS = FLEET_TASK_VIEW_KEY_TUPLE;
250
256
  const FLEET_WORKFLOW_VIEW_KEY_TUPLE = [
@@ -286,6 +292,7 @@ const FLEET_TASK_ROW_WIRE_KEY_TUPLE = [
286
292
  'editedFiles',
287
293
  'cycleSeq',
288
294
  'retiredBy',
295
+ 'workspaceSnapshot',
289
296
  ];
290
297
  export const FLEET_TASK_ROW_WIRE_KEYS = FLEET_TASK_ROW_WIRE_KEY_TUPLE;
291
298
  const FLEET_WORKFLOW_ROW_WIRE_KEY_TUPLE = [
@@ -305,9 +312,9 @@ export const FLEET_TASK_ROW_KEYS_NOT_PROJECTED = {
305
312
  sourceLane: {
306
313
  kind: 'by-design',
307
314
  owner: 'client-core 规范重构轮',
308
- reason: 'SDK 3.0.0 新键([2070]① 让位半场:前台 delegation 复合 id 行带 "run-leg" 标)。两仓现零消费面 ——' +
309
- '#95 纪律:没人读的键不盲投。已知潜在消费方=壳 wf-panel 的双生行过滤(现走 taskId 台账补偿),' +
310
- '若迁到本键判别则届时投影并删本条(那是行为改动,单独批)。',
315
+ reason: 'SDK 3.0.0 新键([2070]① 让位半场:前台 delegation 复合 id 行带 "run-leg" 标)。**渲染视图**(FleetTaskView)不投 —— 渲染面没有按车道分支的需求,' +
316
+ '#95 纪律:没人读的键不盲投。🆕 0.96.0 CC-643 起它有了消费者,但住在另一张读面:在飞 bg 读面行(EngineActiveBgTask)投了它,' +
317
+ '「这一行是不是后台子代」的单一判定口 isBackgroundSubagentRow 读它(见 fleet/bgSubagentRow.ts);视图不投的理由不变,不是第二份真源。',
311
318
  },
312
319
  agentType: {
313
320
  kind: 'by-design',
@@ -1,25 +1,12 @@
1
- import { applyDisplayFace, LEGACY_ESCAPE_FACE, LEGACY_LABEL_FACE } from './displayUntrusted.js';
1
+ import { applyDisplayFace, ESCAPE_FACE, LABEL_FACE, paintAndCap } from './displayUntrusted.js';
2
2
  export function escapeDisplayControlChars(s) {
3
- return applyDisplayFace(s, LEGACY_ESCAPE_FACE);
3
+ return applyDisplayFace(s, ESCAPE_FACE);
4
4
  }
5
5
  export function capForDisplay(raw, max) {
6
- const escaped = escapeDisplayControlChars(raw);
7
- if (escaped.length <= max)
8
- return escaped;
9
- let cut = max;
10
- const tokenStart = escaped.lastIndexOf('\\', cut - 1);
11
- if (tokenStart >= 0 && tokenStart + 6 > cut && /^\\u[0-9A-F]{4}$/.test(escaped.slice(tokenStart, tokenStart + 6))) {
12
- cut = tokenStart;
13
- }
14
- if (cut > 0) {
15
- const code = escaped.charCodeAt(cut - 1);
16
- if (code >= 0xd800 && code <= 0xdbff)
17
- cut -= 1;
18
- }
19
- return cut > 0 ? escaped.slice(0, cut) : '';
6
+ return paintAndCap(raw, ESCAPE_FACE, typeof max === 'number' && max > 0 ? max : 0);
20
7
  }
21
8
  export function collapseLabel(s) {
22
- return applyDisplayFace(s, LEGACY_LABEL_FACE);
9
+ return applyDisplayFace(s, LABEL_FACE);
23
10
  }
24
11
  export function taskDescFromName(name, agentType, agentName) {
25
12
  if (!name || !agentType)
@@ -32,9 +32,20 @@ export interface GateModeReleaseView {
32
32
  mandate?: string;
33
33
  reason?: string;
34
34
  }
35
- export declare const GATE_MODE_RELEASE_REASON_WORDS: readonly ["rule_unreadable", "write_protection_unresolved"];
35
+ export declare const GATE_MODE_RELEASE_REASON_WORDS: readonly ["rule_unreadable", "target_unresolved"];
36
36
  export type GateModeReleaseReasonWord = (typeof CORE_MODE_RELEASE_REASONS)[number];
37
37
  export declare function isGateModeReleaseReasonWord(v: unknown): v is GateModeReleaseReasonWord;
38
+ export declare function modeReleaseReasonSentence(reason: string | null | undefined): string | undefined;
39
+ export interface ReleaseDisclosureIdentity {
40
+ readonly toolCallId?: string;
41
+ readonly callKey?: string;
42
+ readonly epoch?: string | number;
43
+ }
44
+ export interface ReleaseDisclosureLedger {
45
+ readonly has: (identity: ReleaseDisclosureIdentity | null | undefined) => boolean;
46
+ readonly mark: (identity: ReleaseDisclosureIdentity | null | undefined) => void;
47
+ }
48
+ export declare function createReleaseDisclosureLedger(): ReleaseDisclosureLedger;
38
49
  export interface SettlementWhoView {
39
50
  party: string;
40
51
  approver?: string;
@@ -1,7 +1,8 @@
1
1
  import { ccToolDenialKindForSettledBy, isCcToolDenialKind, isGateDeniedByWord } from './gateVocabulary.js';
2
2
  import { GATE_PARKED_ERROR_CODE } from './engineErrorCodes.js';
3
3
  import { CORE_MODE_RELEASE_REASONS, CORE_SETTLEMENT_KINDS } from './generated/engineFactTables.js';
4
- import { readAskOrigin } from './ownKey.js';
4
+ import { currentEngineWord } from './engineWordRenames.js';
5
+ import { readAskOrigin, readOwnDataNonEmptyString, readOwnDataValue } from './ownKey.js';
5
6
  function str(v) {
6
7
  return typeof v === 'string' && v.length > 0 ? v : undefined;
7
8
  }
@@ -9,6 +10,62 @@ export const GATE_MODE_RELEASE_REASON_WORDS = CORE_MODE_RELEASE_REASONS;
9
10
  export function isGateModeReleaseReasonWord(v) {
10
11
  return typeof v === 'string' && CORE_MODE_RELEASE_REASONS.includes(v);
11
12
  }
13
+ const MODE_RELEASE_SENTENCE_BY_REASON = Object.freeze({
14
+ rule_unreadable: 'The permission mode let this call run without asking, even though it could not be checked against your saved permission rules.',
15
+ target_unresolved: 'The permission mode let this call run without asking, even though it could not be determined where its write lands on disk, so whether it lands on a guarded location is unknown.',
16
+ });
17
+ const MODE_RELEASE_UNRECOGNISED_SENTENCE = 'The permission mode let this call run without asking, for a reason this client does not recognise.';
18
+ export function modeReleaseReasonSentence(reason) {
19
+ try {
20
+ if (typeof reason !== 'string' || reason === '')
21
+ return undefined;
22
+ const word = currentEngineWord(reason);
23
+ return Object.hasOwn(MODE_RELEASE_SENTENCE_BY_REASON, word)
24
+ ? MODE_RELEASE_SENTENCE_BY_REASON[word]
25
+ : MODE_RELEASE_UNRECOGNISED_SENTENCE;
26
+ }
27
+ catch {
28
+ return undefined;
29
+ }
30
+ }
31
+ const RELEASE_DISCLOSURE_LEDGER_MAX = 256;
32
+ function releaseDisclosureKeyOf(identity) {
33
+ try {
34
+ if (typeof identity !== 'object' || identity === null)
35
+ return undefined;
36
+ const callId = readOwnDataNonEmptyString(identity, 'toolCallId');
37
+ if (callId !== undefined) {
38
+ const epoch = readOwnDataValue(identity, 'epoch');
39
+ const scope = typeof epoch === 'string' ? epoch : typeof epoch === 'number' && Number.isFinite(epoch) ? String(epoch) : '';
40
+ return JSON.stringify(['call', scope, callId]);
41
+ }
42
+ const cardKey = readOwnDataNonEmptyString(identity, 'callKey');
43
+ return cardKey !== undefined ? JSON.stringify(['card', cardKey]) : undefined;
44
+ }
45
+ catch {
46
+ return undefined;
47
+ }
48
+ }
49
+ export function createReleaseDisclosureLedger() {
50
+ const said = new Set();
51
+ return Object.freeze({
52
+ has(identity) {
53
+ const key = releaseDisclosureKeyOf(identity);
54
+ return key !== undefined && said.has(key);
55
+ },
56
+ mark(identity) {
57
+ const key = releaseDisclosureKeyOf(identity);
58
+ if (key === undefined || said.has(key))
59
+ return;
60
+ said.add(key);
61
+ if (said.size > RELEASE_DISCLOSURE_LEDGER_MAX) {
62
+ const oldest = said.values().next();
63
+ if (oldest.done !== true)
64
+ said.delete(oldest.value);
65
+ }
66
+ },
67
+ });
68
+ }
12
69
  export const SETTLEMENT_KIND_WORDS = CORE_SETTLEMENT_KINDS;
13
70
  function readWho(v) {
14
71
  if (typeof v !== 'object' || v === null || Array.isArray(v))
@@ -1,5 +1,5 @@
1
- import { CORE_DENIED_BY_VALUES } from './generated/engineFactTables.js';
2
- import type { APPROVAL_MANDATE_WORDS } from './hitl/toolApprovalWire.js';
1
+ import { CORE_DENIED_BY_VALUES, CORE_PERSISTED_RULE_MANDATES } from './generated/engineFactTables.js';
2
+ import { PRIOR_ENGINE_WORD_RENAMES, type PriorEngineWord } from './engineWordRenames.js';
3
3
  export declare const CC_TOOL_DENIAL_KINDS: readonly ["user-rejected", "permission-rule", "automode-blocked", "automode-unavailable", "automode-parsing-error", "interrupted", "cancelled"];
4
4
  export type CcToolDenialKind = (typeof CC_TOOL_DENIAL_KINDS)[number];
5
5
  export declare function isCcToolDenialKind(v: unknown): v is CcToolDenialKind;
@@ -11,6 +11,11 @@ export declare function isGateDeniedByWord(v: unknown): v is GateDeniedByWord;
11
11
  export declare function gateDeniedByDetail(deniedBy: unknown): string;
12
12
  export declare function askOriginDetail(origin: unknown): string;
13
13
  export declare function mandatedApprovalDetail(): string;
14
+ type RetiredMandateWord = {
15
+ [K in PriorEngineWord]: (typeof PRIOR_ENGINE_WORD_RENAMES)[K] extends (typeof CORE_PERSISTED_RULE_MANDATES)[number] ? K : never;
16
+ }[PriorEngineWord];
17
+ export declare const APPROVAL_MANDATE_WORDS: readonly ((typeof CORE_PERSISTED_RULE_MANDATES)[number] | RetiredMandateWord)[];
14
18
  export type ApprovalMandateWord = (typeof APPROVAL_MANDATE_WORDS)[number];
15
19
  export declare function isApprovalMandateWord(v: unknown): v is ApprovalMandateWord;
16
20
  export declare function approvalMandateDetail(word: ApprovalMandateWord): string;
21
+ export {};
@@ -1,4 +1,5 @@
1
- import { CORE_DENIED_BY_VALUES } from './generated/engineFactTables.js';
1
+ import { CORE_DENIED_BY_VALUES, CORE_PERSISTED_RULE_MANDATES } from './generated/engineFactTables.js';
2
+ import { PRIOR_ENGINE_WORD_RENAMES } from './engineWordRenames.js';
2
3
  export const CC_TOOL_DENIAL_KINDS = Object.freeze([
3
4
  'user-rejected',
4
5
  'permission-rule',
@@ -71,6 +72,8 @@ export function askOriginDetail(origin) {
71
72
  export function mandatedApprovalDetail() {
72
73
  return 'no saved allow rule and no remembered answer can retire this question; each call is settled on its own — by you here or by an automatic check the deployment runs — and an answer covers only that call';
73
74
  }
75
+ const RETIRED_MANDATE_WORDS = Object.freeze(Object.keys(PRIOR_ENGINE_WORD_RENAMES).filter((k) => CORE_PERSISTED_RULE_MANDATES.includes(PRIOR_ENGINE_WORD_RENAMES[k])));
76
+ export const APPROVAL_MANDATE_WORDS = Object.freeze([...CORE_PERSISTED_RULE_MANDATES, ...RETIRED_MANDATE_WORDS]);
74
77
  const _mandateWordsPin = true;
75
78
  void _mandateWordsPin;
76
79
  export function isApprovalMandateWord(v) {
@@ -82,6 +85,7 @@ const APPROVAL_MANDATE_SENTENCES = Object.freeze({
82
85
  probe_mandate: 'the check run on this call marked it as needing its own confirmation (the built-in shell check does so for a read outside the directories allowed for this session)',
83
86
  probe_unanswered: 'the check run on this call did not answer (it timed out or failed; this client cannot tell which), so whether the call stays inside the directories allowed for this session is unknown',
84
87
  write_protection: "this change lands on a protected location (the agent's own configuration), which is confirmed one change at a time",
88
+ target_unresolved: 'where this change lands on disk could not be determined (a link on the way could not be examined, or the target could not be resolved), so whether it lands on a guarded location is unknown',
85
89
  write_protection_unresolved: 'the protected-location check could not tell where this change lands, so whether it touches a protected location is unknown',
86
90
  });
87
91
  const APPROVAL_MANDATE_SET = new Set(Object.keys(APPROVAL_MANDATE_SENTENCES));
@@ -7,6 +7,6 @@ export const CORE_SHELL_FACE_TOOL_NAMES = Object.freeze([
7
7
  "Monitor",
8
8
  ]);
9
9
  export const CORE_RELEASABLE_ASK_CLASSES_BY_FACE = Object.freeze({
10
- "shell": Object.freeze(["transcript_write", "rule_unreadable", "write_protection_unresolved", "probe", "write_protection", "tool_marks_mcp", "tool_marks_a2a", "artifact_shared_read", "mode", "unstated", "ordinary"]),
10
+ "shell": Object.freeze(["transcript_write", "rule_unreadable", "target_unresolved", "probe", "write_protection", "tool_marks_mcp", "tool_marks_a2a", "artifact_shared_read", "mode", "unstated", "ordinary"]),
11
11
  "other": Object.freeze(["transcript_write", "rule_unreadable", "probe", "write_protection", "tool_marks_mcp", "tool_marks_a2a", "artifact_shared_read", "mode", "unstated", "ordinary"]),
12
12
  });
@@ -8,7 +8,7 @@ export declare const CORE_DENIED_BY_VALUES: readonly ["policy", "hook", "org", "
8
8
  export declare const CORE_PERMISSION_MODE_FOLD_REASONS: readonly string[];
9
9
  export declare const CORE_ENGINE_CARD_TYPES: readonly string[];
10
10
  export declare const CORE_TOOL_DECLARATION_CODES: readonly string[];
11
- export declare const CORE_MODE_RELEASE_REASONS: readonly ["rule_unreadable", "write_protection_unresolved"];
11
+ export declare const CORE_MODE_RELEASE_REASONS: readonly ["rule_unreadable", "target_unresolved"];
12
12
  export declare const CORE_HOOK_TOOL_ALIASES: Readonly<Record<string, string>>;
13
13
  export declare const CORE_ASK_EVIDENCE_ABSENCE_VALUES: readonly ["not_wired", "not_adjudicated", "unavailable", "no_match", "not_reported"];
14
14
  export declare const CORE_SYSTEM_INJECTION_PRIORITIES: readonly ["now", "next", "later"];
@@ -21,9 +21,9 @@ export interface CoreModeArbitrationRow {
21
21
  readonly ruleMayClear: boolean;
22
22
  readonly hookAskFloor: boolean;
23
23
  }
24
- export declare const CORE_MODE_ARBITRATION: Readonly<Record<"content_question" | "hook" | "ancestor" | "dangerous_delete" | "unverifiable_delete" | "transcript_write" | "org_rule" | "governance_unavailable" | "rule_unreadable" | "ask_rule" | "denial_limit_fallback" | "classifier_no_ruling" | "requires_user_interaction" | "operator_forced" | "shell_floor" | "write_protection_unresolved" | "probe" | "write_protection" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "mode" | "unstated" | "ordinary", CoreModeArbitrationRow>>;
24
+ export declare const CORE_MODE_ARBITRATION: Readonly<Record<"content_question" | "hook" | "ancestor" | "dangerous_delete" | "unverifiable_delete" | "unverifiable_shell_text" | "transcript_write" | "org_rule" | "governance_unavailable" | "rule_unreadable" | "ask_rule" | "denial_limit_fallback" | "classifier_no_ruling" | "requires_user_interaction" | "operator_forced" | "shell_floor" | "target_unresolved" | "probe" | "write_protection" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "mode" | "unstated" | "ordinary", CoreModeArbitrationRow>>;
25
25
  export declare const CORE_SKILL_GRANT_ORIGINS: readonly ["model", "user", "inherited"];
26
- export declare const CORE_ALLOW_ENTRY_INERT_REASONS: readonly ["wildcard_all", "namespace_wildcard", "path_pattern", "domain", "content_unsupported", "grammar", "tool_name", "near_miss"];
26
+ export declare const CORE_ALLOW_ENTRY_INERT_REASONS: readonly ["wildcard_all", "namespace_wildcard", "content_unsupported", "grammar", "tool_name", "near_miss"];
27
27
  export declare const CORE_ALLOW_RULE_MEMBERS: readonly ["hook", "deployment", "persisted", "skill", "request"];
28
28
  export declare const CORE_RULE_TOOL_NAME_VERDICTS: readonly ["current", "retired", "unprefixed_namespace", "unmintable_segment"];
29
29
  export declare const CORE_SETTLEMENT_KINDS: readonly ["human_allowed", "human_refused", "approval_window_expired", "denial_limit_window_expired", "park_sla_expired", "no_approver", "approver_unavailable", "approver_error", "approver_contract", "presentation_failed", "blanket_allow_refused", "policy_allowed", "policy_refused", "task_aborted"];
@@ -32,6 +32,7 @@ export declare const CORE_AUTO_MODE_UNAVAILABLE_CAUSES: readonly ["error", "time
32
32
  export declare const CORE_DEFAULT_TIER_ORDER: readonly ["ultra", "max", "pro", "flash", "lite"];
33
33
  export declare const CORE_CC_MODEL_TIER_ALIASES: Readonly<Record<"fable" | "mythos" | "opus" | "sonnet" | "haiku", (typeof CORE_DEFAULT_TIER_ORDER)[number]>>;
34
34
  export declare const CORE_DURABLE_AGENT_HANDLE_RE: RegExp;
35
+ export declare const CORE_TASK_HANDLE_PREFIXES: Readonly<Record<"background_bash" | "workflow" | "background_agent" | "monitor", string>>;
35
36
  export declare const CORE_PERMISSION_MODE_CLASSES: readonly ["bypass", "prompting"];
36
37
  export declare const CORE_MCP_LIVENESS_STATES: readonly ["reachable", "unreachable", "unknown"];
37
38
  export declare const CORE_RULE_BEHAVIORS: readonly ["deny", "ask", "allow"];
@@ -40,3 +41,4 @@ export declare const CORE_MAX_PENDING_STEER_CHARS: number;
40
41
  export declare const CORE_PROMPT_BLOCK_CAUSES: readonly ["block", "crashed", "timeout", "cancelled"];
41
42
  export declare const CORE_PERMISSION_MODES: readonly ["default", "acceptEdits", "plan", "auto", "bypassPermissions", "dontAsk"];
42
43
  export declare const CORE_APPROVAL_REACH: readonly ["none"];
44
+ export declare const CORE_PERSISTED_RULE_MANDATES: readonly ["operator_always", "tool_marks", "probe_mandate", "probe_unanswered", "write_protection", "target_unresolved"];
@@ -113,7 +113,7 @@ export const CORE_TOOL_DECLARATION_CODES = Object.freeze([
113
113
  ]);
114
114
  export const CORE_MODE_RELEASE_REASONS = Object.freeze([
115
115
  "rule_unreadable",
116
- "write_protection_unresolved",
116
+ "target_unresolved",
117
117
  ]);
118
118
  export const CORE_HOOK_TOOL_ALIASES = Object.freeze(Object.assign(Object.create(null), Object.fromEntries([
119
119
  ["ListPeers", "ListAgents"],
@@ -147,6 +147,7 @@ export const CORE_MODE_ARBITRATION = Object.freeze({
147
147
  "ancestor": Object.freeze({ bypassImmune: true, classifierEligible: false, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: false }),
148
148
  "dangerous_delete": Object.freeze({ bypassImmune: true, classifierEligible: false, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: true }),
149
149
  "unverifiable_delete": Object.freeze({ bypassImmune: true, classifierEligible: true, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: true }),
150
+ "unverifiable_shell_text": Object.freeze({ bypassImmune: true, classifierEligible: false, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: true }),
150
151
  "transcript_write": Object.freeze({ bypassImmune: false, classifierEligible: true, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: true }),
151
152
  "org_rule": Object.freeze({ bypassImmune: true, classifierEligible: false, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: false }),
152
153
  "governance_unavailable": Object.freeze({ bypassImmune: true, classifierEligible: false, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: false }),
@@ -157,7 +158,7 @@ export const CORE_MODE_ARBITRATION = Object.freeze({
157
158
  "requires_user_interaction": Object.freeze({ bypassImmune: true, classifierEligible: false, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: true }),
158
159
  "operator_forced": Object.freeze({ bypassImmune: true, classifierEligible: true, sandboxAdmission: true, ruleMayClear: false, hookAskFloor: false }),
159
160
  "shell_floor": Object.freeze({ bypassImmune: true, classifierEligible: true, sandboxAdmission: true, ruleMayClear: false, hookAskFloor: false }),
160
- "write_protection_unresolved": Object.freeze({ bypassImmune: true, classifierEligible: false, sandboxAdmission: true, ruleMayClear: false, hookAskFloor: true }),
161
+ "target_unresolved": Object.freeze({ bypassImmune: true, classifierEligible: false, sandboxAdmission: true, ruleMayClear: false, hookAskFloor: true }),
161
162
  "probe": Object.freeze({ bypassImmune: false, classifierEligible: true, sandboxAdmission: false, ruleMayClear: false, hookAskFloor: false }),
162
163
  "write_protection": Object.freeze({ bypassImmune: false, classifierEligible: true, sandboxAdmission: true, ruleMayClear: false, hookAskFloor: true }),
163
164
  "tool_marks_mcp": Object.freeze({ bypassImmune: false, classifierEligible: true, sandboxAdmission: true, ruleMayClear: false, hookAskFloor: false }),
@@ -176,8 +177,6 @@ export const CORE_SKILL_GRANT_ORIGINS = Object.freeze([
176
177
  export const CORE_ALLOW_ENTRY_INERT_REASONS = Object.freeze([
177
178
  "wildcard_all",
178
179
  "namespace_wildcard",
179
- "path_pattern",
180
- "domain",
181
180
  "content_unsupported",
182
181
  "grammar",
183
182
  "tool_name",
@@ -235,6 +234,12 @@ export const CORE_CC_MODEL_TIER_ALIASES = Object.freeze({
235
234
  "haiku": "lite",
236
235
  });
237
236
  export const CORE_DURABLE_AGENT_HANDLE_RE = Object.freeze(/^a[0-9a-f]{6,32}$/);
237
+ export const CORE_TASK_HANDLE_PREFIXES = Object.freeze({
238
+ "background_bash": "b",
239
+ "workflow": "w",
240
+ "background_agent": "a",
241
+ "monitor": "m",
242
+ });
238
243
  export const CORE_PERMISSION_MODE_CLASSES = Object.freeze([
239
244
  "bypass",
240
245
  "prompting",
@@ -268,3 +273,11 @@ export const CORE_PERMISSION_MODES = Object.freeze([
268
273
  export const CORE_APPROVAL_REACH = Object.freeze([
269
274
  "none",
270
275
  ]);
276
+ export const CORE_PERSISTED_RULE_MANDATES = Object.freeze([
277
+ "operator_always",
278
+ "tool_marks",
279
+ "probe_mandate",
280
+ "probe_unanswered",
281
+ "write_protection",
282
+ "target_unresolved",
283
+ ]);