@sema-agent/client-core 0.99.0 → 0.100.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/CHANGELOG.md +177 -0
  2. package/README.md +32 -19
  3. package/dist/adapt/arms.js +60 -36
  4. package/dist/adapt/panelTasks.d.ts +2 -1
  5. package/dist/adapt/panelTasks.js +32 -9
  6. package/dist/adapt/textStream.d.ts +1 -1
  7. package/dist/adapt/textStream.js +51 -28
  8. package/dist/adapter/activeRunSelfHeal.d.ts +7 -0
  9. package/dist/adapter/activeRunSelfHeal.js +58 -11
  10. package/dist/adapter/downstream/eventToSdkMessage.d.ts +25 -6
  11. package/dist/adapter/downstream/eventToSdkMessage.js +125 -9
  12. package/dist/adapter/downstream/terminalToSdkResult.js +10 -0
  13. package/dist/adapter/downstream/wiringManifestView.d.ts +3 -1
  14. package/dist/adapter/downstream/wiringManifestView.js +1 -0
  15. package/dist/adapter/runStream.js +32 -5
  16. package/dist/adapter/types.d.ts +2 -0
  17. package/dist/agentsWireCaps.d.ts +7 -0
  18. package/dist/agentsWireCaps.js +100 -15
  19. package/dist/cloudConfigWireCaps.d.ts +10 -1
  20. package/dist/cloudConfigWireCaps.js +156 -62
  21. package/dist/compactionStatus.d.ts +34 -0
  22. package/dist/compactionStatus.js +196 -0
  23. package/dist/decideFailureNote.js +3 -3
  24. package/dist/displayUntrusted.js +150 -5
  25. package/dist/engineAgentPanelStore.d.ts +7 -4
  26. package/dist/engineErrorCodes.d.ts +9 -1
  27. package/dist/engineErrorCodes.js +9 -5
  28. package/dist/engineRowRef.js +1 -0
  29. package/dist/engineToolDirectory.d.ts +3 -0
  30. package/dist/engineToolDirectory.js +4 -2
  31. package/dist/eventLeg.d.ts +1 -7
  32. package/dist/eventLeg.js +7 -8
  33. package/dist/fileHistoryCaptureCapability.d.ts +0 -3
  34. package/dist/fileHistoryCaptureCapability.js +0 -4
  35. package/dist/generated/engineFactTables.d.ts +1 -0
  36. package/dist/generated/engineFactTables.js +27 -0
  37. package/dist/generated/engineNoticeTables.js +3 -0
  38. package/dist/generated/settingsSchemaFns.d.ts +12 -0
  39. package/dist/generated/settingsSchemaFns.js +13 -0
  40. package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -0
  41. package/dist/generated/settingsSchemaMcpRequestEntry.js +162 -0
  42. package/dist/generated/settingsSchemaTables.d.ts +1 -0
  43. package/dist/generated/settingsSchemaTables.js +5 -0
  44. package/dist/generated/settingsSchemaTypes.d.ts +28 -0
  45. package/dist/hitl/allowRuleShadow.js +2 -2
  46. package/dist/hitl/approvalCardReasons.js +2 -2
  47. package/dist/hitl/approvalHolds.d.ts +14 -0
  48. package/dist/hitl/approvalHolds.js +41 -0
  49. package/dist/hitl/askClassPair.d.ts +2 -2
  50. package/dist/hitl/askClassPair.js +2 -2
  51. package/dist/hitl/attributionLadder.d.ts +23 -0
  52. package/dist/hitl/attributionLadder.js +67 -0
  53. package/dist/hitl/decisionLedger.d.ts +55 -0
  54. package/dist/hitl/decisionLedger.js +156 -0
  55. package/dist/hitl/decisionRefusal.d.ts +1 -0
  56. package/dist/hitl/decisionRefusal.js +1 -1
  57. package/dist/hitl/decisionSend.d.ts +113 -0
  58. package/dist/hitl/decisionSend.js +579 -0
  59. package/dist/hitl/hitlBridge.js +18 -6
  60. package/dist/hitl/planReviewWire.js +45 -76
  61. package/dist/hitl/sessionPolicyDeliverable.js +3 -6
  62. package/dist/hitl/toolApprovalWire.js +43 -109
  63. package/dist/hostTurnSettings.d.ts +46 -7
  64. package/dist/hostTurnSettings.js +408 -7
  65. package/dist/humanTurn.d.ts +2 -1
  66. package/dist/humanTurn.js +3 -3
  67. package/dist/i18n/messages.en.d.ts +131 -0
  68. package/dist/i18n/messages.en.js +143 -12
  69. package/dist/i18n/messages.zh.js +148 -12
  70. package/dist/index.d.ts +18 -2
  71. package/dist/index.js +10 -1
  72. package/dist/inheritEnvCapability.d.ts +1 -0
  73. package/dist/inheritEnvCapability.js +9 -2
  74. package/dist/inheritEnvWire.js +2 -2
  75. package/dist/injectionLaneNotice.d.ts +5 -0
  76. package/dist/injectionLaneNotice.js +46 -0
  77. package/dist/mcpPanel.js +2 -0
  78. package/dist/mcpReconnect.js +2 -2
  79. package/dist/mcpToolToggles.d.ts +6 -0
  80. package/dist/mcpToolToggles.js +46 -0
  81. package/dist/mcpWireCaps.d.ts +10 -4
  82. package/dist/mcpWireCaps.js +106 -71
  83. package/dist/mcpWireTransport.d.ts +4 -0
  84. package/dist/mcpWireTransport.js +18 -0
  85. package/dist/modelCapabilityProbe.d.ts +2 -1
  86. package/dist/modelCapabilityProbe.js +10 -9
  87. package/dist/modelIdentityResolvability.d.ts +2 -0
  88. package/dist/modelIdentityResolvability.js +23 -5
  89. package/dist/ownKey.d.ts +26 -0
  90. package/dist/ownKey.js +75 -0
  91. package/dist/panelReduce.d.ts +5 -0
  92. package/dist/panelReduce.js +45 -13
  93. package/dist/panelStateHolder.d.ts +1 -0
  94. package/dist/panelStateHolder.js +10 -1
  95. package/dist/permissionRuleIssue.d.ts +2 -1
  96. package/dist/permissionRuleIssue.js +22 -21
  97. package/dist/pluginHooksWire.js +12 -10
  98. package/dist/prepareRefusal.d.ts +8 -0
  99. package/dist/prepareRefusal.js +72 -0
  100. package/dist/request/taskRequest.d.ts +10 -10
  101. package/dist/request/taskRequest.js +106 -65
  102. package/dist/resumeRefusalCopy.d.ts +3 -1
  103. package/dist/resumeRefusalCopy.js +22 -4
  104. package/dist/retryStatus.d.ts +18 -0
  105. package/dist/retryStatus.js +76 -19
  106. package/dist/ruleRefusalSentence.d.ts +4 -0
  107. package/dist/ruleRefusalSentence.js +58 -0
  108. package/dist/sandboxWire.d.ts +2 -1
  109. package/dist/sandboxWire.js +55 -21
  110. package/dist/scenarioRefusal.d.ts +2 -1
  111. package/dist/scenarioRefusal.js +5 -5
  112. package/dist/seam.d.ts +24 -9
  113. package/dist/seam.js +44 -4
  114. package/dist/seatContract.d.ts +16 -8
  115. package/dist/seatContract.js +21 -6
  116. package/dist/settingsCredentialKeyPaths.d.ts +8 -0
  117. package/dist/settingsCredentialKeyPaths.js +219 -0
  118. package/dist/skillsWireCaps.d.ts +0 -3
  119. package/dist/skillsWireCaps.js +1 -2
  120. package/dist/subagentContentStore.d.ts +1 -0
  121. package/dist/subagentContentStore.js +135 -27
  122. package/dist/toolsFlagNames.d.ts +8 -0
  123. package/dist/toolsFlagNames.js +110 -0
  124. package/dist/turnFailurePresentation.js +15 -7
  125. package/dist/wireRefusalCopy.d.ts +51 -17
  126. package/dist/wireRefusalCopy.js +298 -135
  127. package/docs/INTEGRATION-CLIENTS.md +423 -26
  128. package/package.json +4 -4
@@ -11,6 +11,7 @@ import { readOwnDataNonEmptyString, readOwnDataValue } from '../ownKey.js';
11
11
  import { checkpointUnsupportedVersionContent, checkpointUnsupportedVersionFromError, resumeContextUnavailableContent, resumeContextUnavailableFromError } from '../resumeRefusalCopy.js';
12
12
  import { REQUEST_FIELD_CONFLICT } from '../engineErrorCodes.js';
13
13
  import { refusalDeliveryOf } from './decisionRefusal.js';
14
+ import { __resetDecisionLedgerForTests, decisionInFlightOf, decisionKeyInFlight, decisionLedgerKeysOf, decisionOpsWithKey, decisionReadMark, dropDecisionOp, latestDecisionHandedMark, markLatestDecisionNotApplied, openDecisionOp, planDecisionKey, readMarkOf, settleDecisionOp, settleDecisionOpsOnGateLeft, } from './decisionLedger.js';
14
15
  import { denyReasonForWire, isPlanReviewModeAfter } from './hitlBridge.js';
15
16
  import { planReviewQuestionId, REOPEN_ID_TAIL, taskIdFromPlanReviewQuestionId } from './gateIdentity.js';
16
17
  import { notePlanReviewAnswered, notePlanReviewAnsweredFor, planReviewArmedKeyFor, waitForGateArmedFor, wasGateArmedFor, } from './armedGateRegistry.js';
@@ -457,42 +458,21 @@ function usablePlanReviewWireClient(client) {
457
458
  return clientHasVerbs(client, [['assistant', 'planReview'], ['runs', 'get']]);
458
459
  }
459
460
  const PLAN_REVIEW_INJECTED_REPULL_TIMEOUT_MS = 15_000;
460
- const planReviewDecisionOps = [];
461
- const MAX_PLAN_REVIEW_DECISION_OPS = 32;
462
- let planReviewLedgerClock = 0;
463
- let decideDispatchSeq = 0;
464
- function planReviewOpsOf(taskId) {
465
- return planReviewDecisionOps.filter((op) => op.taskId === taskId);
466
- }
467
- function settlePlanReviewDecisionOp(op, by) {
468
- if (op.settledAt !== null)
469
- return;
470
- op.settledAt = ++planReviewLedgerClock;
471
- op.settler = by;
472
- }
473
- function pushPlanReviewDecisionOp(op) {
474
- planReviewDecisionOps.push(op);
475
- while (planReviewDecisionOps.length > MAX_PLAN_REVIEW_DECISION_OPS) {
476
- let victim = planReviewDecisionOps.findIndex((o) => o.settledAt !== null && !o.ownCallOpen);
477
- if (victim < 0)
478
- victim = planReviewDecisionOps.findIndex((o) => o !== op && o.phase === 'handed');
479
- if (victim < 0)
480
- break;
481
- planReviewDecisionOps.splice(victim, 1);
482
- }
461
+ function planReviewLedgerKeys(taskId) {
462
+ return taskId === '' ? [planDecisionKey('')] : decisionLedgerKeysOf({ taskId, planTaskId: taskId });
483
463
  }
484
- function dropPlanReviewDecisionOp(op) {
485
- const i = planReviewDecisionOps.indexOf(op);
486
- if (i >= 0)
487
- planReviewDecisionOps.splice(i, 1);
464
+ function planReviewOpsOf(taskId) {
465
+ return decisionOpsWithKey('plan_review', planDecisionKey(taskId));
488
466
  }
467
+ let decideDispatchSeq = 0;
489
468
  function claimablePlanReviewDecisionOp(taskId) {
490
- const open = planReviewDecisionOps.find((o) => o.taskId === taskId && o.phase === 'handed' && o.settledAt === null);
469
+ const ops = planReviewOpsOf(taskId);
470
+ const open = ops.find((o) => o.phase === 'handed' && o.settledAt === null);
491
471
  if (open !== undefined)
492
472
  return open;
493
473
  let leftBehind;
494
- for (const o of planReviewDecisionOps) {
495
- if (o.taskId !== taskId || o.phase !== 'handed' || o.settler !== 'gate_left')
474
+ for (const o of ops) {
475
+ if (o.phase !== 'handed' || o.settler !== 'gate_left')
496
476
  continue;
497
477
  if (leftBehind === undefined || o.handedAt > leftBehind.handedAt)
498
478
  leftBehind = o;
@@ -502,62 +482,47 @@ function claimablePlanReviewDecisionOp(taskId) {
502
482
  export function notePlanReviewDecisionHandedOver(taskId) {
503
483
  if (typeof taskId !== 'string' || taskId === '')
504
484
  return null;
505
- if (planReviewDecisionOps.some((op) => op.taskId === taskId && op.settledAt === null))
485
+ if (planReviewOpsOf(taskId).some((op) => op.settledAt === null))
506
486
  return null;
507
- const op = { taskId, handedAt: ++planReviewLedgerClock, settledAt: null, settler: null, phase: 'handed', notApplied: false, ownCallOpen: false };
508
- pushPlanReviewDecisionOp(op);
487
+ const op = openDecisionOp('plan_review', planReviewLedgerKeys(taskId), 'handed', false);
509
488
  return {
510
489
  settle: () => {
511
490
  if (op.phase !== 'handed')
512
491
  return;
513
- settlePlanReviewDecisionOp(op, 'host');
492
+ settleDecisionOp(op, 'host');
514
493
  },
515
494
  revoke: () => {
516
495
  if (op.phase !== 'handed' || op.settledAt !== null)
517
496
  return;
518
- dropPlanReviewDecisionOp(op);
497
+ dropDecisionOp(op);
519
498
  },
520
499
  };
521
500
  }
522
501
  export function planReviewPendingReadMark() {
523
- return ++planReviewLedgerClock;
502
+ return decisionReadMark();
524
503
  }
525
504
  export function planReviewDecisionInFlight(taskId, pendingReadStartedAt) {
526
505
  if (typeof taskId !== 'string' || taskId === '')
527
506
  return false;
528
- const mark = typeof pendingReadStartedAt === 'number' && Number.isFinite(pendingReadStartedAt) ? pendingReadStartedAt : undefined;
529
- return planReviewDecisionOps.some((op) => op.taskId === taskId && (op.settledAt === null || (mark !== undefined && op.settledAt > mark && !op.notApplied)));
507
+ return decisionKeyInFlight(planDecisionKey(taskId), readMarkOf(pendingReadStartedAt));
530
508
  }
531
509
  export function notePlanReviewDecisionNotApplied(taskId) {
532
510
  if (typeof taskId !== 'string' || taskId === '')
533
511
  return;
534
- const ops = planReviewOpsOf(taskId);
535
- if (ops.some((op) => op.settledAt === null))
536
- return;
537
- let latest;
538
- for (const op of ops)
539
- if (latest === undefined || op.handedAt > latest.handedAt)
540
- latest = op;
541
- if (latest !== undefined)
542
- latest.notApplied = true;
512
+ markLatestDecisionNotApplied('plan_review', planDecisionKey(taskId));
543
513
  }
544
514
  export function notePlanReviewGateLeft(taskId) {
545
515
  if (typeof taskId !== 'string' || taskId === '')
546
516
  return;
547
- for (const op of planReviewOpsOf(taskId))
548
- settlePlanReviewDecisionOp(op, 'gate_left');
517
+ settleDecisionOpsOnGateLeft('plan_review', planDecisionKey(taskId));
549
518
  }
550
519
  export function latestPlanReviewDecisionMark(taskId) {
551
520
  if (typeof taskId !== 'string' || taskId === '')
552
521
  return null;
553
- let mark = null;
554
- for (const op of planReviewOpsOf(taskId))
555
- if (mark === null || op.handedAt > mark)
556
- mark = op.handedAt;
557
- return mark;
522
+ return latestDecisionHandedMark('plan_review', planDecisionKey(taskId));
558
523
  }
559
524
  export function __resetPlanReviewDecisionLatchForTests() {
560
- planReviewDecisionOps.length = 0;
525
+ __resetDecisionLedgerForTests('plan_review');
561
526
  }
562
527
  export async function decidePlanReview(taskId, decision, permissionModeAfter, opts) {
563
528
  return decidePlanReviewFor(taskId, decision, permissionModeAfter, opts, parkedGateIdentityOf(opts));
@@ -609,14 +574,13 @@ function bodySaysReparked(body) {
609
574
  }
610
575
  }
611
576
  async function decidePlanReviewFor(taskId, decision, permissionModeAfter, opts, gateBefore) {
612
- if (typeof taskId === 'string' && planReviewDecisionOps.some((op) => op.taskId === taskId && op.phase === 'posting')) {
577
+ if (typeof taskId === 'string' && planReviewOpsOf(taskId).some((op) => op.phase === 'posting')) {
613
578
  hostLog('error', `planReviewWire: decidePlanReview(${decision}) for task ${taskId} REFUSED — a decision for this task is already in flight (duplicate delivery latched)`);
614
579
  return;
615
580
  }
616
- let op = claimablePlanReviewDecisionOp(taskId);
581
+ let op = typeof taskId === 'string' ? claimablePlanReviewDecisionOp(taskId) : undefined;
617
582
  if (op === undefined) {
618
- op = { taskId: typeof taskId === 'string' ? taskId : String(taskId), handedAt: ++planReviewLedgerClock, settledAt: null, settler: null, phase: 'posting', notApplied: false, ownCallOpen: true };
619
- pushPlanReviewDecisionOp(op);
583
+ op = openDecisionOp('plan_review', planReviewLedgerKeys(typeof taskId === 'string' ? taskId : String(taskId)), 'posting', true);
620
584
  }
621
585
  else {
622
586
  if (op.settler === 'gate_left') {
@@ -635,7 +599,7 @@ async function decidePlanReviewFor(taskId, decision, permissionModeAfter, opts,
635
599
  const settle = (notApplied) => {
636
600
  if (notApplied)
637
601
  mine.notApplied = true;
638
- settlePlanReviewDecisionOp(mine, 'package');
602
+ settleDecisionOp(mine, 'package');
639
603
  };
640
604
  const dispatchNo = ++decideDispatchSeq;
641
605
  hostLog('debug', `planReviewWire: decidePlanReview dispatch #${dispatchNo} task=${taskId} decision=${decision} mode=${permissionModeAfter ?? '-'}`);
@@ -644,7 +608,7 @@ async function decidePlanReviewFor(taskId, decision, permissionModeAfter, opts,
644
608
  }
645
609
  finally {
646
610
  releaseLatch();
647
- settlePlanReviewDecisionOp(mine, 'package');
611
+ settleDecisionOp(mine, 'package');
648
612
  mine.ownCallOpen = false;
649
613
  }
650
614
  }
@@ -912,10 +876,10 @@ function joinReopenFlight(flight, taskId, receiptMs) {
912
876
  abortableSleep(Math.max(0, receiptMs), ac.signal).then(() => false),
913
877
  ]).then((presented) => {
914
878
  ac.abort();
915
- return presented ? { reopened: true, firstSight: false } : { reopened: false };
879
+ return presented ? { reopened: true, firstSight: false } : refusedReopen('not_presented');
916
880
  }, () => {
917
881
  ac.abort();
918
- return { reopened: false };
882
+ return refusedReopen('not_presented');
919
883
  });
920
884
  }
921
885
  function mintPlanReviewReopen(taskId, opts, sessionKey, receiptMs) {
@@ -955,10 +919,10 @@ function mintPlanReviewReopenCard(taskId, opts, sessionKey, receiptMs) {
955
919
  const markBefore = dismissalEntryFor(sessionKey, taskId);
956
920
  const settleOnReceipt = (receipt, firstSight) => receipt.then((presented) => {
957
921
  if (!presented)
958
- return { reopened: false };
922
+ return refusedReopen('not_presented');
959
923
  revokePlanReviewUserDismissal(sessionKey, taskId, markBefore);
960
924
  return { reopened: true, firstSight };
961
- }, () => ({ reopened: false }));
925
+ }, () => refusedReopen('not_presented'));
962
926
  const canonicalId = planReviewQuestionId(taskId);
963
927
  const armedKey = planReviewArmedKeyFor(sessionKey, taskId);
964
928
  const firstSight = !wasGateArmedFor(sessionKey, armedKey);
@@ -1017,6 +981,9 @@ function mintPlanReviewReopenCard(taskId, opts, sessionKey, receiptMs) {
1017
981
  publishQuestionFrameFor(sessionKey, planReviewQuestionFrame(questionId, REOPEN_QUESTION, false, true));
1018
982
  return settleOnReceipt(receipt, firstSight);
1019
983
  }
984
+ function refusedReopen(cause) {
985
+ return { reopened: false, _sema_reopenRefusal: cause };
986
+ }
1020
987
  function noPresentationSurfaceVerdict(taskId, sessionKey) {
1021
988
  const verdict = { reopened: false, _sema_noPresentationSurface: true };
1022
989
  hostLog('debug', `planReviewWire: reopen for task ${taskId} refused — nothing is subscribed to question frames for session ` +
@@ -1039,7 +1006,7 @@ async function reopenAfterDismissalCheck(taskId, opts, sessionKey, receiptMs, ma
1039
1006
  }
1040
1007
  }
1041
1008
  }
1042
- const ledgerSaysInFlight = planReviewDecisionInFlight(taskId, recheckReadStart);
1009
+ const ledgerSaysInFlight = decisionInFlightOf({ gate: 'plan_review', taskId }, recheckReadStart);
1043
1010
  if (ledgerSaysInFlight) {
1044
1011
  hostLog('debug', `planReviewWire: reopen for task ${taskId} refused after the dismissal check — a decision for this task went out while the check was reading`);
1045
1012
  return { reopened: false, _sema_decisionInFlight: true };
@@ -1088,24 +1055,26 @@ async function staleDismissalVerdict(current, sessionKey, taskId, receiptMs) {
1088
1055
  const windowEnd = abortableSleep(Math.max(0, receiptMs), ac.signal).then(() => false);
1089
1056
  try {
1090
1057
  let entry = current;
1058
+ let lastWaitPresented;
1091
1059
  for (let round = 0; round < 8; round++) {
1092
1060
  if (entry?.kind === 'decided')
1093
1061
  return { reopened: false, _sema_decisionInFlight: true };
1094
1062
  if (entry?.kind === 'dismissed')
1095
1063
  return { reopened: false, dismissedByUser: true };
1096
1064
  if (entry?.kind !== 'reopened' || entry.onScreen === undefined)
1097
- return { reopened: false };
1065
+ return refusedReopen(entry === undefined && lastWaitPresented === false ? 'not_presented' : 'gate_record_gone');
1098
1066
  const onScreen = await Promise.race([
1099
1067
  entry.onScreen.then((v) => v === true, () => false),
1100
1068
  windowEnd,
1101
1069
  ]);
1102
1070
  const now = dismissalEntryFor(sessionKey, taskId);
1103
1071
  if (now === entry) {
1104
- return onScreen ? { reopened: true, firstSight: !wasGateArmedFor(sessionKey, planReviewArmedKeyFor(sessionKey, taskId)) } : { reopened: false };
1072
+ return onScreen ? { reopened: true, firstSight: !wasGateArmedFor(sessionKey, planReviewArmedKeyFor(sessionKey, taskId)) } : refusedReopen('not_presented');
1105
1073
  }
1074
+ lastWaitPresented = onScreen;
1106
1075
  entry = now;
1107
1076
  }
1108
- return { reopened: false };
1077
+ return refusedReopen('gate_record_gone');
1109
1078
  }
1110
1079
  finally {
1111
1080
  ac.abort();
@@ -1115,25 +1084,25 @@ export function reopenPlanReviewCard(taskId, opts) {
1115
1084
  const receiptMs = opts?.presentationReceiptMs;
1116
1085
  if (typeof receiptMs !== 'number' || Number.isNaN(receiptMs)) {
1117
1086
  hostLog('debug', `planReviewWire: reopen for task ${String(taskId)} refused — presentationReceiptMs is required (a number of milliseconds); the synchronous form was retired in 0.98.0`);
1118
- return Promise.resolve({ reopened: false });
1087
+ return Promise.resolve(refusedReopen('invalid_call'));
1119
1088
  }
1120
1089
  try {
1121
1090
  if (typeof taskId !== 'string' || taskId.length === 0) {
1122
- return Promise.resolve({ reopened: false });
1091
+ return Promise.resolve(refusedReopen('invalid_call'));
1123
1092
  }
1124
1093
  const injected = opts;
1125
1094
  if (opts?.mintFreshQuestionId === false && (injected?.deliverDecision !== undefined || injected?.wire !== undefined || injected?.onOutcome !== undefined)) {
1126
1095
  hostLog('error', `planReviewWire: plan_review reopen for task ${taskId} refused — mintFreshQuestionId:false reuses the armed card's responder and its delivery, ` +
1127
1096
  'so deliverDecision / wire / onOutcome cannot be given with it; drop mintFreshQuestionId:false to deliver through the injected path');
1128
- return Promise.resolve({ reopened: false });
1097
+ return Promise.resolve(refusedReopen('invalid_call'));
1129
1098
  }
1130
1099
  const readStart = typeof opts.pendingReadStartedAt === 'number' && Number.isFinite(opts.pendingReadStartedAt) ? opts.pendingReadStartedAt : undefined;
1131
- if (planReviewDecisionInFlight(taskId, readStart)) {
1100
+ if (decisionInFlightOf({ gate: 'plan_review', taskId }, readStart)) {
1132
1101
  hostLog('debug', `planReviewWire: reopen for task ${taskId} refused — a decision for this task is in flight (its answer is still being delivered)`);
1133
1102
  const refused = { reopened: false, _sema_decisionInFlight: true };
1134
1103
  return Promise.resolve(refused);
1135
1104
  }
1136
- const guardStartedAt = planReviewPendingReadMark();
1105
+ const guardStartedAt = decisionReadMark();
1137
1106
  const recheckReadStart = readStart === undefined ? guardStartedAt : Math.min(readStart, guardStartedAt);
1138
1107
  const sessionKey = opts.sessionKey ?? DEFAULT_SESSION_KEY;
1139
1108
  if (!hasQuestionOverlayFor(sessionKey)) {
@@ -1144,7 +1113,7 @@ export function reopenPlanReviewCard(taskId, opts) {
1144
1113
  '而缺省决断投递口(decidePlanReview)今天固定打默认槽的 baseUrl/token/principal。' +
1145
1114
  '整条链转 keyed 之前,非默认槽要重开请自带 deliverDecision(按本槽投递);' +
1146
1115
  '此处拒绝而不是照发 —— 照发会把这条会话的决断发到另一个槽上。');
1147
- return Promise.resolve({ reopened: false });
1116
+ return Promise.resolve(refusedReopen('no_delivery_path'));
1148
1117
  }
1149
1118
  const trigger = opts.trigger === undefined ? undefined : opts.trigger === 'user' ? 'user' : 'automatic';
1150
1119
  if (trigger === 'automatic') {
@@ -1155,6 +1124,6 @@ export function reopenPlanReviewCard(taskId, opts) {
1155
1124
  return mintPlanReviewReopen(taskId, opts, sessionKey, receiptMs);
1156
1125
  }
1157
1126
  catch {
1158
- return Promise.resolve({ reopened: false });
1127
+ return Promise.resolve(refusedReopen('internal_error'));
1159
1128
  }
1160
1129
  }
@@ -4,7 +4,8 @@ import { ruleCompileVerdict } from '../ruleCompileVerdict.js';
4
4
  import { readRuleEntry } from '../coreValuePorts.js';
5
5
  import { readOwnDataValue } from '../ownKey.js';
6
6
  import { ruleToolNameVerdictOf } from '../protocolSegment.js';
7
- import { PREFIXES_IN_PROSE, REFUSED_NAME_CLASSES, REFUSED_NAME_FIX } from './refusedToolNameProse.js';
7
+ import { PREFIXES_IN_PROSE, REFUSED_NAME_FIX } from './refusedToolNameProse.js';
8
+ import { prepareRefusalNoteOf } from '../prepareRefusal.js';
8
9
  import { CORE_PROTOCOL_PREFIXES } from '../generated/toolNameTables.js';
9
10
  const COVERING_NAMESPACE_PREFIXES = CORE_PROTOCOL_PREFIXES;
10
11
  const WITHHELD_NOTICE = {
@@ -170,10 +171,6 @@ export function sessionPolicyWithheldNotice(why) {
170
171
  ? WITHHELD_NOTICE[why]
171
172
  : 'Not written to this session’s rule record.';
172
173
  }
173
- const LEGACY_TOOL_NAME_FAILURE_NOTE = `This run did not start: a tool rule applied to it names a tool the engine refuses — ${REFUSED_NAME_CLASSES} (the engine's own error text names the entry). ` +
174
- 'Every later run fails the same way until that entry is removed from wherever it is set: this session’s rule record, the settings sent with the run, a parent session’s rule record, or the deployment’s own tool rules.';
175
174
  export function legacyToolNameFailureNoteOf(code) {
176
- if (code === CONFIG_LEGACY_TOOL_NAME)
177
- return LEGACY_TOOL_NAME_FAILURE_NOTE;
178
- return undefined;
175
+ return code === CONFIG_LEGACY_TOOL_NAME ? prepareRefusalNoteOf(code) : undefined;
179
176
  }
@@ -17,11 +17,11 @@ import { INTERRUPT_DENY_REASON, observeCancelByDeny, surfaceApprovalParking, sur
17
17
  import { approvalCallKey, liveFrameCallKey } from './gateIdentity.js';
18
18
  import { displayUntrusted } from '../displayUntrusted.js';
19
19
  import { frameBindingOf } from '../frameBinding.js';
20
- import { approvalDecisionHolds, approvalHoldFor, awaitApprovalHolder, claimApprovalCardFor, holdLiveCard, joinLiveCard, liveCardHoldOf, clearSettledApprovals, noteHolderSettledApproval, settledApprovalOf, settledForDurableLane, settledLiveCardOutcome } from './approvalHolds.js';
20
+ import { carriesAttributionKey, deliverWithAttributionLadder } from './attributionLadder.js';
21
+ import { approvalDecisionHolds, approvalHoldFor, awaitApprovalHolder, claimApprovalCardFor, enterLiveRespondPhase, holdLiveCard, joinLiveCard, liveCardHoldOf, clearSettledApprovals, noteHolderSettledApproval, settledApprovalOf, settledForDurableLane, settledLiveCardOutcome } from './approvalHolds.js';
21
22
  import { joinedResolution, resolutionOfDecisionFailure } from './approvalResolution.js';
22
23
  import { parkRowDeadlineState } from './parkExpiryJudgements.js';
23
24
  import { isApprovalMandateWord } from '../gateVocabulary.js';
24
- import { denyAttributionRefusalFromError } from '../wireRefusalCopy.js';
25
25
  import { approvalDecidedByAdmitted } from '../approvalDecidedByCapability.js';
26
26
  import { decideFailureNote } from '../decideFailureNote.js';
27
27
  import { wireFailureTextsOf } from '../wireFailureShape.js';
@@ -462,49 +462,30 @@ async function presentFsApprovalAndDecide(deps, taskId, argsByCall, signal, foun
462
462
  try {
463
463
  const denyPayload = { decision: 'deny', reason: answerPayloadFor({ kind: 'deny', ...(denyReasonSnapshot !== undefined ? { reason: denyReasonSnapshot } : {}) }, 'decide').reason };
464
464
  const denyBody = { ...denyPayload, ...attributionKeys };
465
- let attributionDropped = false;
466
- let attributionRenamed = false;
465
+ const ladder = { lastCarried: carriesAttributionKey(attributionKeys), dropped: false, renamed: false };
467
466
  let raw;
468
- lastSendCarriedAttribution = carriesAttributionKey(attributionKeys);
467
+ lastSendCarriedAttribution = ladder.lastCarried;
469
468
  emitAnswerCommitted(callKey, 'decide', card, denyPayload);
470
469
  try {
471
- raw = await bridge.decideTool(denyBody, gatedCallId, decideOpts, pending);
470
+ raw = await deliverWithAttributionLadder(denyBody, (b) => bridge.decideTool(b, gatedCallId, decideOpts, pending), signal, ladder, (step) => {
471
+ hostLog('debug', step === 'renamed'
472
+ ? `liveToolApprovalWire: decide(deny) for task ${taskId} was refused because the settlement note was sent under a name ` +
473
+ 'this engine has retired — re-sending the SAME decision exactly once with that one key renamed to the name the refusal points to ' +
474
+ '(the refusal happened before the approval was judged, so nothing was consumed and this is a re-delivery, not a second act)'
475
+ : step === 'dropped'
476
+ ? `liveToolApprovalWire: decide(deny) for task ${taskId} was refused because the settlement note is not part of ` +
477
+ 'what this deployment signs — re-sending the SAME decision exactly once with that one key removed ' +
478
+ '(the refusal happened before the approval was judged, so nothing was consumed and this is a re-delivery, not a second act)'
479
+ : `liveToolApprovalWire: decide(deny) for task ${taskId} was refused again because the settlement note is not part of ` +
480
+ 'what this deployment signs — re-sending the SAME decision exactly once more with that key removed ' +
481
+ '(still before the approval was judged)');
482
+ });
472
483
  }
473
- catch (first) {
474
- if (shouldResendWithoutAttribution(first, lastSendCarriedAttribution, signal)) {
475
- const withoutAttribution = withoutAttributionKey(denyBody);
476
- lastSendCarriedAttribution = false;
477
- hostLog('debug', `liveToolApprovalWire: decide(deny) for task ${taskId} was refused because the settlement note is not part of ` +
478
- 'what this deployment signs — re-sending the SAME decision exactly once with that one key removed ' +
479
- '(the refusal happened before the approval was judged, so nothing was consumed and this is a re-delivery, not a second act)');
480
- raw = await bridge.decideTool(withoutAttribution, gatedCallId, decideOpts, pending);
481
- attributionDropped = true;
482
- }
483
- else if (shouldResendUnderSuccessorKey(first, Object.hasOwn(denyBody, 'settledBy'), signal)) {
484
- const renamed = withAttributionKeyRenamed(denyBody);
485
- hostLog('debug', `liveToolApprovalWire: decide(deny) for task ${taskId} was refused because the settlement note was sent under a name ` +
486
- 'this engine has retired — re-sending the SAME decision exactly once with that one key renamed to the name the refusal points to ' +
487
- '(the refusal happened before the approval was judged, so nothing was consumed and this is a re-delivery, not a second act)');
488
- try {
489
- raw = await bridge.decideTool(renamed, gatedCallId, decideOpts, pending);
490
- attributionRenamed = true;
491
- }
492
- catch (second) {
493
- if (!shouldResendWithoutAttribution(second, true, signal))
494
- throw second;
495
- const renamedWithoutAttribution = withoutAttributionKey(renamed);
496
- lastSendCarriedAttribution = false;
497
- hostLog('debug', `liveToolApprovalWire: decide(deny) for task ${taskId} was refused again because the settlement note is not part of ` +
498
- 'what this deployment signs — re-sending the SAME decision exactly once more with that key removed ' +
499
- '(still before the approval was judged)');
500
- raw = await bridge.decideTool(renamedWithoutAttribution, gatedCallId, decideOpts, pending);
501
- attributionDropped = true;
502
- }
503
- }
504
- else {
505
- throw first;
506
- }
484
+ finally {
485
+ lastSendCarriedAttribution = ladder.lastCarried;
507
486
  }
487
+ const attributionDropped = ladder.dropped;
488
+ const attributionRenamed = ladder.renamed;
508
489
  const receipt = readDecideReceipt(raw);
509
490
  const deny = denyFactsOf(denySettledByForWire, denyReasonSnapshot, attributionDropped, attributionRenamed);
510
491
  return {
@@ -872,39 +853,11 @@ function readPersistedRuleAnchors(v) {
872
853
  function isNonNegativeSafeInt(v) {
873
854
  return typeof v === 'number' && Number.isSafeInteger(v) && v >= 0;
874
855
  }
875
- function shouldResendWithoutAttribution(e, sentAttributionKey, signal) {
876
- if (!sentAttributionKey)
877
- return false;
878
- if (signal?.aborted === true)
879
- return false;
880
- return denyAttributionRefusalFromError(e, true)?.kind === 'not_in_proof';
881
- }
882
- function shouldResendUnderSuccessorKey(e, lastSendCarriedRetiredKey, signal) {
883
- if (!lastSendCarriedRetiredKey)
884
- return false;
885
- if (signal?.aborted === true)
886
- return false;
887
- return denyAttributionRefusalFromError(e, true)?.kind === 'retired_key';
888
- }
889
856
  export function decisionAttributionKeyOf(reading, denySettledBy) {
890
857
  if (denySettledBy !== 'policy')
891
858
  return {};
892
859
  return approvalDecidedByAdmitted(reading) ? { decidedBy: 'policy' } : { settledBy: 'policy' };
893
860
  }
894
- function carriesAttributionKey(body) {
895
- return Object.hasOwn(body, 'settledBy') || Object.hasOwn(body, 'decidedBy');
896
- }
897
- function withoutAttributionKey(body) {
898
- const { settledBy: _droppedSettledBy, decidedBy: _droppedDecidedBy, ...rest } = body;
899
- void _droppedSettledBy;
900
- void _droppedDecidedBy;
901
- return rest;
902
- }
903
- function withAttributionKeyRenamed(body) {
904
- const { settledBy, decidedBy: _replaced, ...rest } = body;
905
- void _replaced;
906
- return settledBy === undefined ? rest : { ...rest, decidedBy: settledBy };
907
- }
908
861
  function readDecidedByReadingOf(holder) {
909
862
  try {
910
863
  return readOwnDataValue(holder, 'approvalDecidedBy');
@@ -986,7 +939,7 @@ function probeCauseSentence(cause, withProse, lang) {
986
939
  const key = withProse
987
940
  ? withCode ? 'approval.probe.withProseCode' : 'approval.probe.withProse'
988
941
  : withCode ? 'approval.probe.noProseCode' : 'approval.probe.noProse';
989
- return renderMessage(withCode ? msg(key, { code }) : msg(key), lang);
942
+ return renderMessage(withCode ? msg(key, { code: displayUntrusted(code) }) : msg(key), lang);
990
943
  }
991
944
  catch {
992
945
  return undefined;
@@ -1190,7 +1143,7 @@ export function classifierNoRulingDetail(word, lang) {
1190
1143
  return renderMessage(msg(CLASSIFIER_NO_RULING_REASONS[word]), lang);
1191
1144
  }
1192
1145
  if (typeof word === 'string' && CAUSE_WORD.test(word))
1193
- return renderMessage(msg('approval.classifier.noRulingOther', { reason: word }), lang);
1146
+ return renderMessage(msg('approval.classifier.noRulingOther', { reason: displayUntrusted(word) }), lang);
1194
1147
  return renderMessage(msg('approval.classifier.noRulingBare'), lang);
1195
1148
  }
1196
1149
  export function approvalBoundGrantsDetail(grants, lang) {
@@ -1863,7 +1816,7 @@ async function presentToolApprovalFrameAndRespond(frame, approvalId, respond, st
1863
1816
  return { kind: 'not_sent', lane: 'respond', cause: 'retracted' };
1864
1817
  }
1865
1818
  if (card.kind === 'aborted') {
1866
- hold.phase = 'respond';
1819
+ enterLiveRespondPhase(hold);
1867
1820
  const interruptOpts = lane?.approvalDecisionNoteCapable === true ? { note: INTERRUPT_DENY_REASON } : {};
1868
1821
  let interruptDeny;
1869
1822
  try {
@@ -1877,7 +1830,7 @@ async function presentToolApprovalFrameAndRespond(frame, approvalId, respond, st
1877
1830
  hostLog('debug', `liveToolApprovalWire: ${approvalId} card aborted — one tool-level deny issued to settle the pending ask`);
1878
1831
  return { kind: 'unsettled', lane: 'respond', cause: 'interrupted' };
1879
1832
  }
1880
- hold.phase = 'respond';
1833
+ enterLiveRespondPhase(hold);
1881
1834
  const noteCapable = lane?.approvalDecisionNoteCapable === true;
1882
1835
  const denyReasonRead = card.kind === 'deny' ? ((r) => (typeof r === 'string' ? r : undefined))(card.reason) : undefined;
1883
1836
  const answerSnapshot = card.kind === 'deny'
@@ -1982,49 +1935,30 @@ async function presentToolApprovalFrameAndRespond(frame, approvalId, respond, st
1982
1935
  ...(note !== undefined ? { note } : {}),
1983
1936
  ...attributionKeys,
1984
1937
  };
1985
- let attributionDropped = false;
1986
- let attributionRenamed = false;
1938
+ const ladder = { lastCarried: lastSendCarriedAttribution, dropped: false, renamed: false };
1987
1939
  let raw;
1988
1940
  if (basePayload !== undefined)
1989
1941
  emitAnswerCommitted(liveFrameCallKey(approvalId), 'respond', answerSnapshot, basePayload);
1990
1942
  try {
1991
- raw = await respond(approvalId, decision, respondOpts);
1943
+ raw = await deliverWithAttributionLadder(respondOpts, (o) => respond(approvalId, decision, o), signal, ladder, (step) => {
1944
+ hostLog('debug', step === 'renamed'
1945
+ ? `liveToolApprovalWire: respond(deny) for ${approvalId} was refused because the settlement note was sent under a name ` +
1946
+ 'this engine has retired — re-sending the SAME decision exactly once with that one key renamed to the name the refusal points to ' +
1947
+ '(the refusal happened before the approval was judged, so nothing was consumed and this is a re-delivery, not a second act)'
1948
+ : step === 'dropped'
1949
+ ? `liveToolApprovalWire: respond(deny) for ${approvalId} was refused because the settlement note is not part of ` +
1950
+ 'what this deployment signs — re-sending the SAME decision exactly once with that one key removed ' +
1951
+ '(the refusal happened before the approval was judged, so nothing was consumed and this is a re-delivery, not a second act)'
1952
+ : `liveToolApprovalWire: respond(deny) for ${approvalId} was refused again because the settlement note is not part of ` +
1953
+ 'what this deployment signs — re-sending the SAME decision exactly once more with that key removed ' +
1954
+ '(still before the approval was judged)');
1955
+ });
1992
1956
  }
1993
- catch (first) {
1994
- if (shouldResendWithoutAttribution(first, lastSendCarriedAttribution, signal)) {
1995
- const withoutAttribution = withoutAttributionKey(respondOpts);
1996
- lastSendCarriedAttribution = false;
1997
- hostLog('debug', `liveToolApprovalWire: respond(deny) for ${approvalId} was refused because the settlement note is not part of ` +
1998
- 'what this deployment signs — re-sending the SAME decision exactly once with that one key removed ' +
1999
- '(the refusal happened before the approval was judged, so nothing was consumed and this is a re-delivery, not a second act)');
2000
- raw = await respond(approvalId, decision, withoutAttribution);
2001
- attributionDropped = true;
2002
- }
2003
- else if (shouldResendUnderSuccessorKey(first, Object.hasOwn(respondOpts, 'settledBy'), signal)) {
2004
- const renamed = withAttributionKeyRenamed(respondOpts);
2005
- hostLog('debug', `liveToolApprovalWire: respond(deny) for ${approvalId} was refused because the settlement note was sent under a name ` +
2006
- 'this engine has retired — re-sending the SAME decision exactly once with that one key renamed to the name the refusal points to ' +
2007
- '(the refusal happened before the approval was judged, so nothing was consumed and this is a re-delivery, not a second act)');
2008
- try {
2009
- raw = await respond(approvalId, decision, renamed);
2010
- attributionRenamed = true;
2011
- }
2012
- catch (second) {
2013
- if (!shouldResendWithoutAttribution(second, true, signal))
2014
- throw second;
2015
- const renamedWithoutAttribution = withoutAttributionKey(renamed);
2016
- lastSendCarriedAttribution = false;
2017
- hostLog('debug', `liveToolApprovalWire: respond(deny) for ${approvalId} was refused again because the settlement note is not part of ` +
2018
- 'what this deployment signs — re-sending the SAME decision exactly once more with that key removed ' +
2019
- '(still before the approval was judged)');
2020
- raw = await respond(approvalId, decision, renamedWithoutAttribution);
2021
- attributionDropped = true;
2022
- }
2023
- }
2024
- else {
2025
- throw first;
2026
- }
1957
+ finally {
1958
+ lastSendCarriedAttribution = ladder.lastCarried;
2027
1959
  }
1960
+ const attributionDropped = ladder.dropped;
1961
+ const attributionRenamed = ladder.renamed;
2028
1962
  const parkingBody = readToolApprovalRespondParking(raw);
2029
1963
  if (parkingBody !== undefined) {
2030
1964
  const parking = parkingBody.kind === 'parking' && parkingBody.view.approvalId === approvalId ? parkingBody.view : undefined;
@@ -1,14 +1,19 @@
1
+ import type { TaskRequest } from '@sema-agent/sdk';
1
2
  import type { WireHooksConfig } from './finalVerifyWire.js';
3
+ import type { memoryOffDeclared as MemoryOffDeclared } from './request/taskRequest.js';
4
+ import type { EnvLike } from './hostEnv.js';
2
5
  import type { SettingsDocument } from './host.js';
3
6
  import { type HookSettingsSource, type HooksWirePlan } from './pluginHooksWire.js';
4
- export declare const HOST_SUPPLIED_KEYS: readonly ["settings.hooks", "settings.resolved", "settings.webSearch", "settings.outputStyle"];
7
+ import { type WebSearchApiKeyFor } from './webSearchWireCaps.js';
8
+ import { type FileHistoryCaptureReading } from './fileHistoryCaptureCapability.js';
9
+ export declare const HOST_SUPPLIED_KEYS: readonly ["settings.hooks", "settings.resolved", "settings.webSearch", "settings.outputStyle", "memory", "fileHistory"];
5
10
  export type HostSuppliedKey = (typeof HOST_SUPPLIED_KEYS)[number];
6
- export declare const HOST_SETTING_CAUSES: readonly ["carried", "entries_dropped", "source_rejected", "projection_failed", "source_unreadable", "empty", "no_source", "host_port_missing"];
11
+ export declare const HOST_SETTING_CAUSES: readonly ["carried", "entries_dropped", "source_rejected", "projection_failed", "source_unreadable", "empty", "no_source", "host_port_missing", "value_malformed"];
7
12
  export type HostSettingCause = (typeof HOST_SETTING_CAUSES)[number];
8
13
  export declare const HOST_SETTING_DISPOSITIONS: readonly ["carry", "carry_partial", "withhold_notice", "refuse_turn", "unwired", "nothing_to_carry"];
9
14
  export type HostSettingDisposition = (typeof HOST_SETTING_DISPOSITIONS)[number];
10
15
  export type HostSettingPlane = 'turn' | 'session' | 'diagnostic';
11
- export type HostSettingNoticeId = 'HS-UNWIRED' | 'HS-MANAGED-REJECTED' | 'HS-PROJECTION' | 'HS-SOURCE-UNREADABLE';
16
+ export type HostSettingNoticeId = 'HS-UNWIRED' | 'HS-MANAGED-REJECTED' | 'HS-PROJECTION' | 'HS-SOURCE-UNREADABLE' | 'HS-WEBSEARCH-MALFORMED' | 'HS-SWITCH-MALFORMED' | 'HS-FILEHISTORY-UNJUDGED';
12
17
  export interface HostSettingRow {
13
18
  readonly key: HostSuppliedKey;
14
19
  readonly cause: HostSettingCause;
@@ -33,12 +38,24 @@ export interface HostTurnSettingsSources {
33
38
  readonly resolved: {
34
39
  readonly snapshot: SettingsDocument;
35
40
  } | 'none';
36
- readonly webSearch: {
37
- readonly settings: SettingsDocument;
38
- } | 'none';
41
+ readonly webSearch: HostWebSearchSource | 'none';
39
42
  readonly outputStyle: {
40
43
  readonly name: string;
41
44
  } | 'none';
45
+ readonly memory: HostMemorySource | 'none';
46
+ readonly fileHistory: {
47
+ readonly reading: FileHistoryCaptureReading;
48
+ readonly captureOff: boolean;
49
+ } | 'none';
50
+ }
51
+ export interface HostWebSearchSource {
52
+ readonly section?: SettingsDocument;
53
+ readonly env: EnvLike;
54
+ readonly apiKeyFor?: WebSearchApiKeyFor;
55
+ }
56
+ export interface HostMemorySource {
57
+ readonly flag?: string;
58
+ readonly settingsMemory?: SettingsDocument;
42
59
  }
43
60
  export interface HostTurnSettingsInput {
44
61
  readonly sources: HostTurnSettingsSources;
@@ -48,6 +65,8 @@ export interface HostSettingsCarried {
48
65
  readonly resolved?: SettingsDocument;
49
66
  readonly webSearch?: SettingsDocument;
50
67
  readonly outputStyle?: string;
68
+ readonly memory?: TaskRequest['memory'];
69
+ readonly fileHistory?: TaskRequest['fileHistory'];
51
70
  }
52
71
  declare const hostTurnSettingsBrand: unique symbol;
53
72
  export interface HostTurnSettings {
@@ -58,14 +77,34 @@ export interface HostTurnSettings {
58
77
  readonly hooks: HooksWirePlan | undefined;
59
78
  readonly carried: HostSettingsCarried;
60
79
  }
80
+ export interface HostTurnSettingsJudges {
81
+ readonly materialize: HostResolvedMaterializer;
82
+ readonly memoryOffDeclared: typeof MemoryOffDeclared;
83
+ }
61
84
  export declare function rethrowHostResolvedDeferred(product: HostTurnSettings): void;
62
85
  export type HostResolvedMaterializer = (snapshot: SettingsDocument) => SettingsDocument;
63
- export declare function buildHostTurnSettings(input: HostTurnSettingsInput, materialize: HostResolvedMaterializer): HostTurnSettings;
86
+ export declare function buildHostTurnSettings(input: HostTurnSettingsInput, judges: HostTurnSettingsJudges): HostTurnSettings;
64
87
  export declare function hostSettingsSelfCheck(product: HostTurnSettings): readonly HostSuppliedKey[];
88
+ export declare const hostProjectionNotice: () => HostSettingNotice;
65
89
  export declare class HostSettingsRefused extends Error {
66
90
  readonly notice: HostSettingNotice;
67
91
  constructor(n: HostSettingNotice);
68
92
  }
69
93
  export declare function hostTurnSettingsOf(v: unknown, depth?: 'shape' | 'full'): HostTurnSettings | undefined;
94
+ export interface HostHooksIntersection {
95
+ readonly hooks: WireHooksConfig | undefined;
96
+ readonly dropped: number;
97
+ readonly judged: boolean;
98
+ }
99
+ export declare function intersectHostHooks(sent: WireHooksConfig, now: WireHooksConfig | undefined): HostHooksIntersection;
100
+ export interface HostIntakeSnapshot {
101
+ readonly carried: HostSettingsCarried;
102
+ readonly refuses: boolean;
103
+ readonly dispositions: Readonly<Record<HostSuppliedKey, HostSettingDisposition>>;
104
+ readonly refusingKeys: readonly HostSuppliedKey[];
105
+ readonly turnNotices: readonly HostSettingNotice[] | undefined;
106
+ readonly notice: HostSettingNotice | undefined;
107
+ }
108
+ export declare function hostIntakeSnapshotOf(product: HostTurnSettings, onResolved?: (resolved: HostSettingsCarried['resolved']) => void): HostIntakeSnapshot | undefined;
70
109
  export declare const UNWIRED_HOST_TURN_SETTINGS: HostTurnSettings;
71
110
  export {};