@junghanacs/entwurf 0.23.0 → 0.24.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 (102) hide show
  1. package/AGENTS.md +3 -1
  2. package/BASELINE.md +2 -0
  3. package/CHANGELOG.md +307 -0
  4. package/FAQ.md +47 -0
  5. package/README.md +5 -3
  6. package/VERIFY.md +43 -2
  7. package/demo/README.md +1 -1
  8. package/docs/acp-backend-rail.md +97 -18
  9. package/docs/setup-clean-host.md +8 -7
  10. package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +33 -1
  11. package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/backend-adapter.js +2 -2
  12. package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/context.js +19 -5
  13. package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/tool-surface.js +2 -1
  14. package/mcp/entwurf-bridge/dist/pi-extensions/lib/callback-env.js +68 -0
  15. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-contract.js +2 -2
  16. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-lock.js +1 -1
  17. package/mcp/entwurf-bridge/dist/pi-extensions/lib/fresh-call-composition.js +54 -22
  18. package/mcp/entwurf-bridge/dist/pi-extensions/lib/herdr-fresh-call.js +7 -3
  19. package/mcp/entwurf-bridge/dist/pi-extensions/lib/herdr-placement.js +13 -4
  20. package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-fresh-call.js +19 -10
  21. package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-omp.js +35 -42
  22. package/mcp/entwurf-bridge/dist/scripts/probe-bridge-command.js +1 -0
  23. package/mcp/entwurf-bridge/src/index.ts +41 -1
  24. package/mcp/entwurf-bridge/test.sh +2 -2
  25. package/package.json +15 -13
  26. package/pi-extensions/entwurf-control.ts +56 -0
  27. package/pi-extensions/lib/acp/acp-client.ts +3 -3
  28. package/pi-extensions/lib/acp/backend-adapter.ts +3 -3
  29. package/pi-extensions/lib/acp/backend.ts +20 -10
  30. package/pi-extensions/lib/acp/context.ts +30 -10
  31. package/pi-extensions/lib/acp/event-mapper.ts +5 -5
  32. package/pi-extensions/lib/acp/session-store.ts +2 -2
  33. package/pi-extensions/lib/acp/tool-surface.ts +2 -1
  34. package/pi-extensions/lib/callback-env.ts +78 -0
  35. package/pi-extensions/lib/compaction-send-guard.ts +4 -1
  36. package/pi-extensions/lib/entwurf-v2-contract.ts +2 -2
  37. package/pi-extensions/lib/entwurf-v2-lock.ts +1 -1
  38. package/pi-extensions/lib/entwurf-v2-runner.ts +1 -1
  39. package/pi-extensions/lib/fresh-call-composition.ts +56 -22
  40. package/pi-extensions/lib/herdr-fresh-call.ts +12 -4
  41. package/pi-extensions/lib/herdr-placement.ts +13 -4
  42. package/pi-extensions/lib/mux-fresh-call.ts +23 -8
  43. package/pi-extensions/meta-bridge-omp.ts +35 -48
  44. package/run.sh +327 -246
  45. package/scripts/check-acp-backend-preflight.ts +117 -9
  46. package/scripts/check-acp-carrier-augment.ts +6 -4
  47. package/scripts/check-acp-event-mapper.ts +17 -6
  48. package/scripts/check-acp-prompt-builder.ts +17 -9
  49. package/scripts/check-acp-prompt-lifecycle.ts +23 -6
  50. package/scripts/check-acp-session-reuse.ts +64 -51
  51. package/scripts/check-acp-session-store.ts +31 -8
  52. package/scripts/check-acp-stop-reason.ts +20 -2
  53. package/scripts/check-acp-stream-hooks.ts +22 -5
  54. package/scripts/check-acp-usage-accounting.ts +42 -18
  55. package/scripts/check-entwurf-bridge-boot.ts +16 -1
  56. package/scripts/check-fresh-call-dispatch.ts +4 -5
  57. package/scripts/check-gate-qualification.ts +45 -5
  58. package/scripts/check-herdr-activation.ts +73 -0
  59. package/scripts/check-herdr-fresh-call.ts +22 -6
  60. package/scripts/check-herdr-sandbox.ts +14 -2
  61. package/scripts/check-install-container.sh +1 -1
  62. package/scripts/check-pi-launch.ts +361 -0
  63. package/scripts/check-release-gate-outcomes.ts +7 -0
  64. package/scripts/inventory-verification-surface.ts +86 -10
  65. package/scripts/lib/mutation-qualify.ts +1 -1
  66. package/scripts/mutants/acp-backend-preflight.json +20 -0
  67. package/scripts/mutants/bridge-boot-resume.json +26 -0
  68. package/scripts/mutants/herdr-activation.json +16 -0
  69. package/scripts/mutants/herdr-fresh-call.json +11 -0
  70. package/scripts/mutants/herdr-plugin-build.json +1 -1
  71. package/scripts/mutants/mux-fresh-call.json +21 -8
  72. package/scripts/mutants/omp-fresh.json +5 -9
  73. package/scripts/mutants/pack-install.json +3 -3
  74. package/scripts/mutants/pi-launch.json +113 -0
  75. package/scripts/mutants/resume-args.json +6 -6
  76. package/scripts/mutants/v2-surface.json +2 -2
  77. package/scripts/mutants/v2-visible-resume.json +17 -17
  78. package/scripts/probe-bridge-command.ts +1 -0
  79. package/scripts/smoke-acp-raw-turn-live.ts +1 -1
  80. package/scripts/smoke-acp-session-reuse-live.ts +23 -5
  81. package/scripts/smoke-agy-install-state.sh +2 -2
  82. package/scripts/smoke-copilot-mcp-state.sh +1 -1
  83. package/scripts/smoke-entwurf-v2-matrix-live.ts +1 -1
  84. package/scripts/smoke-herdr-fresh-call-live.ts +56 -28
  85. package/scripts/smoke-herdr-raw-install-live.sh +877 -0
  86. package/scripts/smoke-omp-fresh-live.ts +4 -2
  87. package/scripts/smoke-omp-mcp-state.sh +1 -1
  88. package/scripts/smoke-pi-provider-state.sh +2 -2
  89. package/scripts/tsconfig.json +5 -0
  90. package/scripts/check-entwurf-facts.ts +0 -391
  91. package/scripts/check-entwurf-resume-args.ts +0 -122
  92. package/scripts/check-entwurf-v2-decider.ts +0 -657
  93. package/scripts/check-entwurf-v2-lock.ts +0 -371
  94. package/scripts/check-entwurf-v2-mailbox.ts +0 -261
  95. package/scripts/check-entwurf-v2-matrix.ts +0 -401
  96. package/scripts/check-entwurf-v2-native-push.ts +0 -221
  97. package/scripts/check-entwurf-v2-release.ts +0 -151
  98. package/scripts/check-entwurf-v2-runner.ts +0 -448
  99. package/scripts/check-entwurf-v2-send-fallback.ts +0 -350
  100. package/scripts/check-entwurf-v2-send.ts +0 -458
  101. package/scripts/check-entwurf-v2-visible-resume.ts +0 -445
  102. package/scripts/check-socket-discovery.ts +0 -401
@@ -86,6 +86,7 @@
86
86
  * there is no "session created" field because nothing here creates one.
87
87
  */
88
88
 
89
+ import { callbackEnvAssignments } from "./callback-env.ts";
89
90
  import { classifyTmuxCwd, type TmuxCwdRejectReason } from "./classify-tmux-cwd.ts";
90
91
  import {
91
92
  CODEX_CALLER_SEAT_HINT,
@@ -111,6 +112,7 @@ import {
111
112
  composeFreshCallPrompt,
112
113
  FRESH_CALL_BACKENDS,
113
114
  FRESH_CALL_CALLBACK_TOOL,
115
+ FRESH_CALL_DELIVERY_TOOL,
114
116
  type FreshCallBackend,
115
117
  type FreshCallComposition,
116
118
  type FreshCallInputRejectReason,
@@ -158,6 +160,7 @@ export {
158
160
  buildOmpBootstrapPayload,
159
161
  FRESH_CALL_BACKENDS,
160
162
  FRESH_CALL_CALLBACK_TOOL,
163
+ FRESH_CALL_DELIVERY_TOOL,
161
164
  type FreshCallBackend,
162
165
  type FreshCallComposition,
163
166
  isSafeFreshCallModel,
@@ -351,9 +354,11 @@ export type FreshCallResult = { ok: true; receipt: FreshCallReceipt } | { ok: fa
351
354
  * scrub only on the backend whose measurement surfaced it would encode the claim that the other
352
355
  * four are immune, which is false. It costs the legitimate case nothing: a carrier is only ever
353
356
  * authoritative when the process that owns it exported it ITSELF, and a fresh `pi` sibling does
354
- * exactly that after this argv has run. This is a fixed two-variable seam and deliberately NOT a
355
- * general env carrier — an arbitrary `-e` passthrough would hand callers the environment-shaping
356
- * power this rail exists to refuse.
357
+ * exactly that after this argv has run. This is a fixed seam and deliberately NOT a general env
358
+ * carrier — an arbitrary `-e` passthrough would hand callers the environment-shaping power this
359
+ * rail exists to refuse. Two more `-e` assignments ride beside the scrub: the callback pair
360
+ * (`callback-env.ts`), launcher-computed, so the sibling's first action does not retype an
361
+ * address out of prose.
357
362
  */
358
363
  const SCRUBBED_INHERITED_ENV = ["PI_SESSION_ID=", "PI_AGENT_ID="] as const;
359
364
 
@@ -371,7 +376,8 @@ export function buildFreshCallArgs(
371
376
  targetSessionId: string,
372
377
  runtimePath: string,
373
378
  backendArgs: readonly string[],
374
- cwd?: string,
379
+ cwd: string | undefined,
380
+ callback: { target: string; nonce: string },
375
381
  ): string[] {
376
382
  assertSelector("session", targetSessionId);
377
383
  assertLaunchTarget(runtimePath);
@@ -384,6 +390,7 @@ export function buildFreshCallArgs(
384
390
  "-d",
385
391
  "-a",
386
392
  ...SCRUBBED_INHERITED_ENV.flatMap((assignment) => ["-e", assignment]),
393
+ ...callbackEnvAssignments(callback).flatMap((assignment) => ["-e", assignment]),
387
394
  "-t",
388
395
  `${targetSessionId}:{end}`,
389
396
  ...(cwd === undefined ? [] : ["-c", cwd]),
@@ -569,7 +576,13 @@ export function freshCall(
569
576
  );
570
577
  }
571
578
  }
572
- const run = runTmux(buildFreshCallArgs(targetSessionId, runtimePath, backendArgs, cwd), env);
579
+ const run = runTmux(
580
+ buildFreshCallArgs(targetSessionId, runtimePath, backendArgs, cwd, {
581
+ target: callerGardenId,
582
+ nonce,
583
+ }),
584
+ env,
585
+ );
573
586
  assertTmuxOk("new-window", run);
574
587
 
575
588
  let fields: ReturnType<typeof parseWindowFields>;
@@ -683,9 +696,11 @@ export function renderFreshCall(result: FreshCallResult): { text: string; isErro
683
696
  `\n` +
684
697
  `This is a LAUNCH receipt: tmux created that window and was asked to start the runtime with the model above. It does ` +
685
698
  `NOT mean the sibling is running, that its first turn ran, or that the task was delivered.\n` +
686
- `The sibling's garden id arrives separately — it calls entwurf_v2 back with the nonce above as its ` +
687
- `first action, and the sender envelope of THAT message is the address. Nothing is polling for it; ` +
688
- `if it never comes, the window is visible and can be read directly.`,
699
+ `The sibling's garden id arrives separately — its first action is the zero-argument callback verb ` +
700
+ `(codex is the one arm that still sends the nonce as arguments), and the sender envelope of THAT ` +
701
+ `message is the address. The nonce above is the correlation tag it carries; the sibling reads it ` +
702
+ `from its own launch env, never from this receipt. Nothing is polling for it; if it never comes, ` +
703
+ `the window is visible and can be read directly.`,
689
704
  isError: false,
690
705
  };
691
706
  }
@@ -83,7 +83,6 @@ import {
83
83
  type MetaRootBundle,
84
84
  ompMetaRootBase,
85
85
  ompMetaRoots,
86
- requireGardenId,
87
86
  upsertMetaSession,
88
87
  writeMetaSenderMarker,
89
88
  } from "./lib/meta-session.ts";
@@ -162,7 +161,7 @@ export const OMP_BOOTSTRAP_FLAG = "entwurf-bootstrap";
162
161
  /** Payload grammar version. A payload that does not say exactly this is refused rather than
163
162
  * best-guessed: the launcher and this unit ship in the same package, so a mismatch means a
164
163
  * STALE installed unit — the one condition `doctor-omp-bridge` exists to name out loud. */
165
- export const OMP_BOOTSTRAP_VERSION = 1;
164
+ export const OMP_BOOTSTRAP_VERSION = 2;
166
165
 
167
166
  /**
168
167
  * The model-facing callback tool, spelled for omp. `[측정]` the vendor's minter sanitises to
@@ -177,7 +176,7 @@ export const OMP_BOOTSTRAP_VERSION = 1;
177
176
  * spellings are held equal by `test/omp-fresh-bootstrap.contract.test.ts`, the same shape
178
177
  * `check-omp-fresh-preflight` already uses for the preflight's reproduced oracles.
179
178
  */
180
- export const OMP_BOOTSTRAP_CALLBACK_TOOL = "mcp__entwurf_bridge_entwurf_v";
179
+ export const OMP_BOOTSTRAP_CALLBACK_TOOL = "mcp__entwurf_bridge_entwurf_callback";
181
180
 
182
181
  /** Task ceiling, held equal to the launcher's `TASK_MAX_CHARS` by the same contract test. */
183
182
  export const OMP_BOOTSTRAP_TASK_MAX_CHARS = 16000;
@@ -195,15 +194,9 @@ export const OMP_BOOTSTRAP_READY_TIMEOUT_MS = 60_000;
195
194
  * primitive; a FIXED DELAY is forbidden because the gap is a race, not a constant. */
196
195
  export const OMP_BOOTSTRAP_POLL_MS = 100;
197
196
 
198
- /** The nonce the launcher mints (`mintNonce`: `mux-fresh-call-` + 12 random bytes as hex). */
199
- const BOOTSTRAP_NONCE_RE = /^mux-fresh-call-[0-9a-f]{24}$/;
200
-
201
- /** What the launcher put on the flag. Exactly three fields — a target to call back to, the
202
- * correlation nonce, and the operator's task. Nothing here is a command, a path or an env
203
- * name, and the decoder refuses anything wider. */
197
+ /** What the launcher put on the flag. Address rides process env; this payload is the task
198
+ * released after the no-arg callback succeeds. The decoder refuses anything wider. */
204
199
  export interface OmpBootstrapPayload {
205
- target: string;
206
- nonce: string;
207
200
  task: string;
208
201
  }
209
202
 
@@ -216,8 +209,6 @@ export type OmpBootstrapRejectReason =
216
209
  | "payload-not-object"
217
210
  | "version-unsupported"
218
211
  | "payload-unknown-key"
219
- | "target-invalid"
220
- | "nonce-invalid"
221
212
  | "task-empty"
222
213
  | "task-too-long";
223
214
 
@@ -228,7 +219,7 @@ export type OmpBootstrapDecode =
228
219
  /** The wire keys, closed. An unknown key is a REFUSAL rather than an ignored extra: this
229
220
  * flag is the one thing a caller can put arbitrary bytes into, so the decoder's job is to
230
221
  * make "what the launcher meant" and "what this unit will act on" the same set. */
231
- const BOOTSTRAP_KEYS = new Set(["v", "target", "nonce", "task"]);
222
+ const BOOTSTRAP_KEYS = new Set(["v", "task"]);
232
223
 
233
224
  /**
234
225
  * Read the flag value into a payload, or name why not.
@@ -256,18 +247,10 @@ export function decodeOmpBootstrapPayload(raw: unknown): OmpBootstrapDecode {
256
247
  for (const key of Object.keys(obj)) {
257
248
  if (!BOOTSTRAP_KEYS.has(key)) return { ok: false, reason: "payload-unknown-key" };
258
249
  }
259
- let target: string;
260
- try {
261
- target = requireGardenId(obj.target);
262
- } catch {
263
- return { ok: false, reason: "target-invalid" };
264
- }
265
- const nonce = obj.nonce;
266
- if (typeof nonce !== "string" || !BOOTSTRAP_NONCE_RE.test(nonce)) return { ok: false, reason: "nonce-invalid" };
267
250
  const task = obj.task;
268
251
  if (typeof task !== "string" || task.trim().length === 0) return { ok: false, reason: "task-empty" };
269
252
  if (task.length > OMP_BOOTSTRAP_TASK_MAX_CHARS) return { ok: false, reason: "task-too-long" };
270
- return { ok: true, value: { target, nonce, task } };
253
+ return { ok: true, value: { task } };
271
254
  }
272
255
 
273
256
  /**
@@ -279,18 +262,13 @@ export function decodeOmpBootstrapPayload(raw: unknown): OmpBootstrapDecode {
279
262
  * no competing goal at all. Stage two exists so this message never has to compete with the
280
263
  * work; adding "then do X" back into it would rebuild exactly the prompt that failed.
281
264
  */
282
- export function buildOmpCallbackOnlyPrompt(params: { target: string; nonce: string }): string {
265
+ export function buildOmpCallbackOnlyPrompt(): string {
283
266
  return [
284
267
  "You are a fresh visible citizen that entwurf opened in the operator's tmux session.",
285
268
  "",
286
- `FIRST AND ONLY ACTION RIGHT NOW: call ${OMP_BOOTSTRAP_CALLBACK_TOOL} with ` +
287
- `target=${params.target}, intent=fire-and-forget, wants_reply=false, and ` +
288
- `message set to exactly ${params.nonce} — that string alone, nothing added.`,
269
+ `FIRST AND ONLY ACTION RIGHT NOW: call ${OMP_BOOTSTRAP_CALLBACK_TOOL} with no arguments.`,
289
270
  "That call is how the agent that opened you learns your address. Make the call before",
290
- "reading files, before planning, and before answering in prose. Do not reword the message.",
291
- "",
292
- "Do not inspect environment variables, do not call entwurf_self, and do not start an MCP",
293
- "server yourself. Your own report of your identity is not the address anyone needs.",
271
+ "reading files, before planning, and before answering in prose. There are no parameters.",
294
272
  "",
295
273
  "Your actual task arrives as the NEXT user message, immediately after that call succeeds.",
296
274
  "Do not ask for it and do not guess at it.",
@@ -756,20 +734,29 @@ export function ompCallbackToolReady(pi: OmpExtensionApi): boolean {
756
734
  }
757
735
 
758
736
  /**
759
- * Does this tool event name OUR callback, with OUR target and OUR nonce?
737
+ * Does this tool event name OUR callback?
760
738
  *
761
739
  * The event carries no server name, no session id and no original MCP tool name
762
- * (`extensions/types.ts:916-1017`), so the match is built from what IS there: the canonical
763
- * minted tool name plus the two argument values this rail already owns as contract. Exact
764
- * string equality on both — a prefix or `includes` here would let a sibling's nonce release
765
- * this session's task.
740
+ * (`extensions/types.ts:916-1017`), so the match is built from what IS there: exact string
741
+ * equality on the canonical minted tool name a prefix or `includes` here would let a
742
+ * neighbouring tool release this session's task.
743
+ *
744
+ * The target/nonce half of this predicate is GONE, and that is the point of the out-of-band
745
+ * callback: the address rides the sibling's process env, so the verb takes no arguments and
746
+ * there are no argument values left to compare. What replaces the comparison is the ABSENCE
747
+ * of arguments — a call carrying a target or a message is a model supplying an address, which
748
+ * is the second address axis Hard Rule 2 refuses, and it must not release the task. Correlation
749
+ * to THIS bootstrap is not weakened by the removal: it is carried by the stored `toolCallId`
750
+ * (one session, one live tool call) plus the fact that only this session's env named the caller.
766
751
  */
767
- function matchesCallback(event: OmpToolCallEvent, payload: OmpBootstrapPayload): boolean {
752
+ function matchesCallback(event: OmpToolCallEvent, _payload: OmpBootstrapPayload): boolean {
768
753
  if (event?.toolName !== OMP_BOOTSTRAP_CALLBACK_TOOL) return false;
769
754
  const input = event?.input;
770
- if (typeof input !== "object" || input === null || Array.isArray(input)) return false;
755
+ if (input === undefined || input === null) return true;
756
+ if (typeof input !== "object" || Array.isArray(input)) return false;
771
757
  const args = input as Record<string, unknown>;
772
- return args.target === payload.target && args.message === payload.nonce;
758
+ // No-arg verb: a supplied target/message is a second address axis — not our callback.
759
+ return args.target === undefined && args.message === undefined;
773
760
  }
774
761
 
775
762
  /**
@@ -822,7 +809,7 @@ export function createOmpBootstrap(opts: {
822
809
  stopTimer();
823
810
  if (isFinal()) return;
824
811
  phase = "failed";
825
- log("WARN", `bootstrap-failed nonce=${payload.nonce}: ${why}; the task was NOT sent`);
812
+ log("WARN", `bootstrap-failed: ${why}; the task was NOT sent`);
826
813
  }
827
814
 
828
815
  /**
@@ -858,8 +845,8 @@ export function createOmpBootstrap(opts: {
858
845
  // two callback prompts for one bootstrap.
859
846
  phase = "callback-sent";
860
847
  stopTimer();
861
- log("INFO", `bootstrap-ready nonce=${payload.nonce}: callback tool live, sending callback-only prompt`);
862
- send(buildOmpCallbackOnlyPrompt({ target: payload.target, nonce: payload.nonce }));
848
+ log("INFO", "bootstrap-ready: callback tool live, sending callback-only prompt");
849
+ send(buildOmpCallbackOnlyPrompt());
863
850
  return;
864
851
  }
865
852
  if (timers.now() >= deadline) {
@@ -895,14 +882,14 @@ export function createOmpBootstrap(opts: {
895
882
  const id = event?.toolCallId;
896
883
  if (typeof id !== "string" || id.length === 0) return;
897
884
  callId = id;
898
- log("INFO", `bootstrap-callback-observed nonce=${payload.nonce} toolCallId=${id}`);
885
+ log("INFO", `bootstrap-callback-observed toolCallId=${id}`);
899
886
  },
900
887
  onToolResult(event: OmpToolResultEvent): void {
901
888
  if (phase !== "callback-sent" || callId === null) return;
902
889
  if (event?.toolCallId !== callId) return;
903
890
  if (!matchesCallback(event, payload)) return;
904
891
  if (event?.isError !== false) {
905
- log("WARN", `bootstrap-callback-errored nonce=${payload.nonce} toolCallId=${callId}; the task was NOT sent`);
892
+ log("WARN", `bootstrap-callback-errored toolCallId=${callId}; the task was NOT sent`);
906
893
  return;
907
894
  }
908
895
  // RELEASED, AND THE TASK IS NOT SENT HERE. This handler runs inside the callback
@@ -911,7 +898,7 @@ export function createOmpBootstrap(opts: {
911
898
  // record that the callback provably succeeded; `onTurnEnd` owns the send.
912
899
  phase = "released";
913
900
  stopTimer();
914
- log("INFO", `bootstrap-released nonce=${payload.nonce} toolCallId=${callId}: task armed for the next turn_end`);
901
+ log("INFO", `bootstrap-released toolCallId=${callId}: task armed for the next turn_end`);
915
902
  },
916
903
  /**
917
904
  * The stage-two boundary: the callback turn is over, so the session is at the edge
@@ -932,7 +919,7 @@ export function createOmpBootstrap(opts: {
932
919
  onTurnEnd(): void {
933
920
  if (phase !== "released") return;
934
921
  phase = "task-sent";
935
- log("INFO", `bootstrap-task-sent nonce=${payload.nonce}: delivering the task at the turn_end boundary`);
922
+ log("INFO", "bootstrap-task-sent: delivering the task at the turn_end boundary");
936
923
  send(payload.task);
937
924
  },
938
925
  invalidate(why: string): void {
@@ -942,7 +929,7 @@ export function createOmpBootstrap(opts: {
942
929
  // caller's task must die with the session it was addressed to.
943
930
  if (isFinal()) return;
944
931
  phase = "failed";
945
- log("INFO", `bootstrap-invalidated nonce=${payload.nonce}: ${why}; the task was NOT sent`);
932
+ log("INFO", `bootstrap-invalidated: ${why}; the task was NOT sent`);
946
933
  },
947
934
  };
948
935
  }
@@ -1118,7 +1105,7 @@ export function startOmpBootstrap(opts: {
1118
1105
  const handle = createOmpBootstrap({ payload: decoded.value, pi, timers, log });
1119
1106
  activeBootstrap = { sessionId: envelope.nativeSessionId, handle };
1120
1107
  bootstrapConsumed = true;
1121
- log("INFO", `bootstrap-armed nonce=${decoded.value.nonce} target=${decoded.value.target}`);
1108
+ log("INFO", "bootstrap-armed: payload admitted, waiting for callback tool");
1122
1109
  handle.start();
1123
1110
  }
1124
1111