bazilion 0.16.0 → 0.18.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/dist/cli.js +672 -87
  2. package/dist/cli.js.map +1 -1
  3. package/dist/daemon.js +3759 -432
  4. package/dist/daemon.js.map +1 -1
  5. package/dist/migrations/0001_init.sql +169 -0
  6. package/dist/web/client/assets/ChatPane-CAYS_fIQ.js +76 -0
  7. package/dist/web/client/assets/ConfirmDialog-BzIiABOP.js +1 -0
  8. package/dist/web/client/assets/{FieldRow-DJ2Gx4Du.js → FieldRow-W_54rw5c.js} +1 -1
  9. package/dist/web/client/assets/ProductionTeamPolicyEditor-DNXVX8Lz.js +7 -0
  10. package/dist/web/client/assets/ProfileCommunicationEditor-DN0fOzqn.js +1 -0
  11. package/dist/web/client/assets/{ResultSourceConversation-CtzJ8QA-.js → ResultSourceConversation-DoU4tOWc.js} +1 -1
  12. package/dist/web/client/assets/TeamTabs-BmTZRI4T.js +1 -0
  13. package/dist/web/client/assets/TemplatesTabs-Bs_OXKwx.js +1 -0
  14. package/dist/web/client/assets/{UnsavedChangesGuard-BCsLw-mU.js → UnsavedChangesGuard-CPRtFReU.js} +1 -1
  15. package/dist/web/client/assets/{_id-DxopIW-y.js → _id-CxAB4TDr.js} +1 -1
  16. package/dist/web/client/assets/_id-DL4tJFQB.js +1 -0
  17. package/dist/web/client/assets/{_id-BEDmIXVf.js → _id-DR9eFC17.js} +1 -1
  18. package/dist/web/client/assets/{_id-BFM_tn_s.js → _id-Dbmei5tg.js} +1 -1
  19. package/dist/web/client/assets/{_id-B5Ov7cdO.js → _id-ybF-pqmr.js} +1 -1
  20. package/dist/web/client/assets/activity-oUyy77jD.js +1 -0
  21. package/dist/web/client/assets/{agents-CMPOFcs-.js → agents-D_TrEqAg.js} +1 -1
  22. package/dist/web/client/assets/{agents-O4soKZND.js → agents-DkjJp7JP.js} +1 -1
  23. package/dist/web/client/assets/{approvals-CwDu_lrA.js → approvals-DhOerWdt.js} +1 -1
  24. package/dist/web/client/assets/{attention-BY8MMuM_.js → attention-DGwiF-Jy.js} +1 -1
  25. package/dist/web/client/assets/chevron-right-DSa4xPTs.js +1 -0
  26. package/dist/web/client/assets/config-BJ2ZzHPR.js +3 -0
  27. package/dist/web/client/assets/createServerFn-Dzfjt7mA.js +3 -0
  28. package/dist/web/client/assets/git-review-presentation-CzHQulDk.js +1 -0
  29. package/dist/web/client/assets/{inbox-CWXql0K3.js → inbox-BUElnGep.js} +1 -1
  30. package/dist/web/client/assets/index-Bi-HxcPG.js +50 -0
  31. package/dist/web/client/assets/{learning-DAm4dyyc.js → learning-BiTHNwB3.js} +1 -1
  32. package/dist/web/client/assets/login-BmcZvAH2.js +1 -0
  33. package/dist/web/client/assets/{mcp-loLB0wuh.js → mcp-Cwk9V82W.js} +1 -1
  34. package/dist/web/client/assets/{members-BJ0ikkTl.js → members-CHDNabFh.js} +1 -1
  35. package/dist/web/client/assets/{memory-Drn9Gv53.js → memory-Cx_Fpd4e.js} +1 -1
  36. package/dist/web/client/assets/policy-C0nMdwcG.js +1 -0
  37. package/dist/web/client/assets/{results-9exU6f7m.js → results-Bz3jASs-.js} +1 -1
  38. package/dist/web/client/assets/review-AK9WGmpv.js +1 -0
  39. package/dist/web/client/assets/routes-DsMY_6oy.js +1 -0
  40. package/dist/web/client/assets/{services-BLso1BhA.js → services-DItA6fJ7.js} +1 -1
  41. package/dist/web/client/assets/{skills-BodqX3OI.js → skills-DbNV2vgL.js} +1 -1
  42. package/dist/web/client/assets/{styles-d1yjBpud.css → styles-C6br2xxl.css} +1 -1
  43. package/dist/web/client/assets/{teams-ByQedXZi.js → teams-D83scDxw.js} +1 -1
  44. package/dist/web/client/assets/{teams-SYsF1bOR.js → teams-DAny1ypN.js} +1 -1
  45. package/dist/web/client/assets/{telegram-DC9PLFbB.js → telegram-BOmf9vUh.js} +1 -1
  46. package/dist/web/client/assets/{tokens-DGy8Ijpo.js → tokens-DBGH6Bw5.js} +1 -1
  47. package/dist/web/client/assets/{triggers-BXpVmHDG.js → triggers-D1_pseI3.js} +1 -1
  48. package/dist/web/client/assets/verifications-CBTo-FyV.js +2 -0
  49. package/dist/web/client/assets/welcome-DAfPOm15.js +1 -0
  50. package/dist/web/client/assets/x-CWY-gUaM.js +1 -0
  51. package/dist/web/server/assets/{ChatPane-CS5oI7ef.js → ChatPane-DybH39WK.js} +301 -14
  52. package/dist/web/server/assets/{ResultSourceConversation-BpVWBRYq.js → ResultSourceConversation-BmXTcEOA.js} +1 -1
  53. package/dist/web/server/assets/{TeamTabs-TCKjCvMA.js → TeamTabs-Dg4v6x0-.js} +8 -0
  54. package/dist/web/server/assets/{_id-DtIYuJJX.js → _id--onriuvj.js} +1 -1
  55. package/dist/web/server/assets/{_id-DOnInzLb.js → _id--zoh1vv7.js} +1 -1
  56. package/dist/web/server/assets/{_id-CeyHEsCZ.js → _id-6p-mDmI8.js} +1 -1
  57. package/dist/web/server/assets/{_id-5pgKoid8.js → _id-BN1BPEDI.js} +1 -1
  58. package/dist/web/server/assets/{_id-DFHB9JFQ.js → _id-BYKpT2Tu.js} +1 -1
  59. package/dist/web/server/assets/{_id-B_-CDHOi2.js → _id-BqWTB8Wl.js} +1 -1
  60. package/dist/web/server/assets/{_id-BnqodC1c2.js → _id-C_2er0_G.js} +3 -3
  61. package/dist/web/server/assets/{_id-BG2nkGxa.js → _id-DptBl3X8.js} +1 -1
  62. package/dist/web/server/assets/{_id-DwZXhLlL.js → _id-EAjRXNbD.js} +2 -2
  63. package/dist/web/server/assets/{_id-DrB9uR1b.js → _id-dUnXL-My2.js} +1 -1
  64. package/dist/web/server/assets/{_tanstack-start-manifest_v-D7gKv6m6.js → _tanstack-start-manifest_v-B3M-dfRO.js} +108 -84
  65. package/dist/web/server/assets/{activity-0VUkStOu.js → activity-C5jpoEQI.js} +1 -1
  66. package/dist/web/server/assets/{activity-C88qrNqv.js → activity-Cu7zKPGD.js} +1 -1
  67. package/dist/web/server/assets/{activity-5fWKPDxj.js → activity-Dn50vkQP.js} +2 -2
  68. package/dist/web/server/assets/{agents-CSXLaM2W.js → agents-RE6aYOb-.js} +1 -1
  69. package/dist/web/server/assets/{agents-C86K6HvS.js → agents-nAOx_H7s.js} +1 -1
  70. package/dist/web/server/assets/{approvals-C3MysI6l.js → approvals-DhHxIDrL.js} +1 -1
  71. package/dist/web/server/assets/{attention-DLeLCKah.js → attention-CBWzWRni.js} +1 -1
  72. package/dist/web/server/assets/{auth-CDZp9aEk.js → auth-tB3i6cFd.js} +1 -1
  73. package/dist/web/server/assets/{config-BVTHvljR.js → config-D1k_tTAw.js} +1 -1
  74. package/dist/web/server/assets/{daemon-client-xWyYKAcx.js → daemon-client-C7qjQ2iO.js} +45 -0
  75. package/dist/web/server/assets/git-review-BB3M9nYg.js +26 -0
  76. package/dist/web/server/assets/git-review-Bf5ABFJg.js +179 -0
  77. package/dist/web/server/assets/git-review-presentation-TJiHJhen.js +81 -0
  78. package/dist/web/server/assets/{inbox-PQTrjtOw.js → inbox-Dw4pTevh.js} +1 -1
  79. package/dist/web/server/assets/{learning-K0cmDsZR.js → learning-CF8ZzFVD.js} +1 -1
  80. package/dist/web/server/assets/{mcp-Rtraochg.js → mcp-D5dmBT82.js} +1 -1
  81. package/dist/web/server/assets/{members-CD3GiTfF.js → members-Bd0OtiTr.js} +1 -1
  82. package/dist/web/server/assets/{members-grAKFWgv.js → members-CvwEN9pm.js} +1 -1
  83. package/dist/web/server/assets/{members-cc5SeEaW.js → members-xSXoYUOd.js} +2 -2
  84. package/dist/web/server/assets/{memory-egFpBD1g.js → memory-CcPK7um7.js} +1 -1
  85. package/dist/web/server/assets/{memory-C5i_GxlY.js → memory-UP6AsRkO.js} +2 -2
  86. package/dist/web/server/assets/{memory-CVqnyUaM.js → memory-lo2vHRNw.js} +1 -1
  87. package/dist/web/server/assets/{policy-bLKwvnja.js → policy-B62WXIFo.js} +1 -1
  88. package/dist/web/server/assets/{policy-Dgjb0_gK.js → policy-Bze9Krhg.js} +2 -2
  89. package/dist/web/server/assets/{policy-ooSBgiDS.js → policy-Dh6wd2wN.js} +1 -1
  90. package/dist/web/server/assets/{results-N-kP4iFT.js → results-BFqs2iOu.js} +1 -1
  91. package/dist/web/server/assets/{results-DXdYtHaq.js → results-BWnu3gXP.js} +1 -1
  92. package/dist/web/server/assets/{results-CfNsFncJ.js → results-CzZk50Fu.js} +3 -3
  93. package/dist/web/server/assets/review-DUe3vHPU.js +393 -0
  94. package/dist/web/server/assets/review-c_-cFi7H.js +14 -0
  95. package/dist/web/server/assets/{router-B6g_s7W3.js → router-Deq94UJQ.js} +41 -27
  96. package/dist/web/server/assets/{routes-pcRy_Sf8.js → routes-B6x3pEW8.js} +1 -1
  97. package/dist/web/server/assets/{routes-BqSaZvlu.js → routes-CVKkvFVv.js} +1 -1
  98. package/dist/web/server/assets/{routes-Dsh8F_7i.js → routes-DsUzzxk4.js} +2 -2
  99. package/dist/web/server/assets/{services-DlZA8fRL.js → services-CEr61xb5.js} +1 -1
  100. package/dist/web/server/assets/{skills-i2duvgW-.js → skills-BImC3LTO.js} +1 -1
  101. package/dist/web/server/assets/{teams-6RYIj1Xm.js → teams-8zEIo08E.js} +1 -1
  102. package/dist/web/server/assets/{teams-B1AI3NfN.js → teams-D-yaAWLV.js} +1 -1
  103. package/dist/web/server/assets/{telegram-C4q0YTVn.js → telegram-CGl_LFtJ.js} +1 -1
  104. package/dist/web/server/assets/{tokens-RFquA2Bx.js → tokens-cB-uf7qm.js} +1 -1
  105. package/dist/web/server/assets/{triggers-DVD-iE-N.js → triggers-CtSj79L0.js} +1 -1
  106. package/dist/web/server/assets/verification-B5QjcpIo.js +97 -0
  107. package/dist/web/server/assets/verifications-BfQsfwSE.js +268 -0
  108. package/dist/web/server/assets/verifications-CUq_6ZqL.js +26 -0
  109. package/dist/web/server/server.js +72 -28
  110. package/dist/worker.js +470 -79
  111. package/dist/worker.js.map +1 -1
  112. package/package.json +3 -3
  113. package/dist/web/client/assets/ChatPane-CQZzxOir.js +0 -76
  114. package/dist/web/client/assets/ConfirmDialog-MicTTwdy.js +0 -1
  115. package/dist/web/client/assets/ProductionTeamPolicyEditor-DqUnN_ce.js +0 -7
  116. package/dist/web/client/assets/ProfileCommunicationEditor-DArXub0b.js +0 -1
  117. package/dist/web/client/assets/TeamTabs-DbIk5vvT.js +0 -1
  118. package/dist/web/client/assets/TemplatesTabs-CatJIjGi.js +0 -1
  119. package/dist/web/client/assets/_id-CrnEVcw8.js +0 -1
  120. package/dist/web/client/assets/activity-CrG8Bg60.js +0 -1
  121. package/dist/web/client/assets/chevron-right-Cf6vKeLq.js +0 -1
  122. package/dist/web/client/assets/config-Cn4iBJFz.js +0 -3
  123. package/dist/web/client/assets/index-Bq2zrG2_.js +0 -52
  124. package/dist/web/client/assets/login-BsABI8Ux.js +0 -1
  125. package/dist/web/client/assets/policy-pQadZyk0.js +0 -1
  126. package/dist/web/client/assets/routes-jw1PuqiR.js +0 -1
  127. package/dist/web/client/assets/welcome-BKsnsCxJ.js +0 -1
  128. package/dist/web/client/assets/x-BK4xNCzS.js +0 -1
package/dist/worker.js CHANGED
@@ -1108,6 +1108,41 @@ function qmdBackend(root, options = {}) {
1108
1108
  };
1109
1109
  }
1110
1110
 
1111
+ // ../daemon/src/lib/coding-environment/receipt-reference.ts
1112
+ function codingLogReference(content) {
1113
+ const parsed = objectFrom(textContent(content));
1114
+ if (!parsed) return null;
1115
+ return referenceFrom(parsed) ?? referenceFrom(objectFrom(parsed.receipt));
1116
+ }
1117
+ function referenceFrom(value) {
1118
+ if (!value) return null;
1119
+ const commandId = value.id;
1120
+ const teamId = value.teamId;
1121
+ if (typeof commandId !== "string" || commandId.length === 0) return null;
1122
+ if (typeof teamId !== "string" || teamId.length === 0) return null;
1123
+ return { commandId, teamId };
1124
+ }
1125
+ function textContent(content) {
1126
+ if (typeof content === "string") return content;
1127
+ if (!Array.isArray(content)) return "";
1128
+ let out = "";
1129
+ for (const block of content) {
1130
+ if (block && block.type === "text" && typeof block.text === "string") out += block.text;
1131
+ }
1132
+ return out;
1133
+ }
1134
+ function objectFrom(value) {
1135
+ if (typeof value === "string") {
1136
+ try {
1137
+ return objectFrom(JSON.parse(value));
1138
+ } catch {
1139
+ return null;
1140
+ }
1141
+ }
1142
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return null;
1143
+ return value;
1144
+ }
1145
+
1111
1146
  // ../daemon/src/runtime/pi/events.ts
1112
1147
  function translatePiEvent(e) {
1113
1148
  switch (e.type) {
@@ -1147,6 +1182,22 @@ function translatePiEvent(e) {
1147
1182
  }
1148
1183
  return out;
1149
1184
  }
1185
+ case "tool_execution_update": {
1186
+ if (e.toolName !== "coding_command") return [];
1187
+ const progress = e.partialResult?.details?.codingProgress;
1188
+ if (!progress || typeof progress.id !== "string" || typeof progress.commandId !== "string" || typeof progress.output !== "string" || typeof progress.elapsedMs !== "number")
1189
+ return [];
1190
+ return [
1191
+ {
1192
+ type: "coding_progress",
1193
+ id: progress.id,
1194
+ commandId: progress.commandId,
1195
+ output: progress.output,
1196
+ truncated: progress.truncated === true,
1197
+ elapsedMs: Math.max(0, Math.floor(progress.elapsedMs))
1198
+ }
1199
+ ];
1200
+ }
1150
1201
  case "tool_execution_end": {
1151
1202
  if (e.toolName === "ask_user")
1152
1203
  return [
@@ -1254,14 +1305,22 @@ function piMessagesToProviderView(messages, questionResultVisible) {
1254
1305
  }
1255
1306
  case "toolResult": {
1256
1307
  const tr = m;
1257
- if (["repository_context", "coding_environment", "coding_command", "coding_receipt"].includes(
1258
- tr.toolName ?? ""
1259
- )) {
1308
+ if ([
1309
+ "repository_context",
1310
+ "coding_environment",
1311
+ "coding_command",
1312
+ "coding_receipt",
1313
+ "coding_log",
1314
+ // BAZ-042: a snapshot result names withheld paths, so history must not render it.
1315
+ "source_snapshot"
1316
+ ].includes(tr.toolName ?? "")) {
1317
+ const codingLog = codingLogReference(tr.content);
1260
1318
  out.push({
1261
1319
  role: "tool",
1262
1320
  toolCallId: tr.toolCallId,
1263
1321
  toolName: tr.toolName,
1264
- content: "Coding context or command evidence retained privately. Captured transport output follows its communication approval; ask the Agent for the relevant result."
1322
+ content: "Coding context or command evidence retained privately. Captured transport output follows its communication approval; ask the Agent for the relevant result.",
1323
+ ...codingLog ? { codingLog } : {}
1265
1324
  });
1266
1325
  break;
1267
1326
  }
@@ -1298,6 +1357,107 @@ function extractResultReference(value) {
1298
1357
  return typeof id === "string" && /^[a-f0-9-]{36}$/.test(id) ? { resultId: id } : void 0;
1299
1358
  }
1300
1359
 
1360
+ // ../daemon/src/lib/coding-environment/diagnostics.ts
1361
+ var CODING_OUTPUT_BYTES = 64 * 1024;
1362
+ var CODING_RETAINED_BYTES = 2 * 1024 * 1024;
1363
+ var CODING_LIVE_BYTES = 8 * 1024;
1364
+ function diagnosticTail(value, limit) {
1365
+ const bytes = Buffer.from(value);
1366
+ if (bytes.length <= limit) return { text: value, truncated: false };
1367
+ let offset = bytes.length - limit;
1368
+ while (offset < bytes.length && ((bytes[offset] ?? 0) & 192) === 128) offset++;
1369
+ return { text: bytes.subarray(offset).toString("utf8"), truncated: true };
1370
+ }
1371
+ var CodingDiagnostics = class {
1372
+ decoder = new TextDecoder();
1373
+ secrets;
1374
+ lookbehind;
1375
+ retainBytes;
1376
+ pending = "";
1377
+ text = "";
1378
+ truncated = false;
1379
+ observedBytes = 0;
1380
+ redactions = 0;
1381
+ finished = false;
1382
+ constructor(secrets, retainBytes = CODING_OUTPUT_BYTES) {
1383
+ this.secrets = [...new Set(secrets.filter(Boolean))].sort((a, b) => b.length - a.length);
1384
+ this.lookbehind = Math.max(1, ...this.secrets.map((secret) => secret.length)) - 1;
1385
+ this.retainBytes = retainBytes;
1386
+ }
1387
+ append(bytes) {
1388
+ if (this.finished) throw new Error("Coding diagnostics already finalized");
1389
+ this.observedBytes += bytes.length;
1390
+ for (let offset = 0; offset < bytes.length; offset += 8192) {
1391
+ this.pending += this.decoder.decode(bytes.subarray(offset, offset + 8192), { stream: true });
1392
+ this.flush(false);
1393
+ }
1394
+ }
1395
+ /**
1396
+ * Redacted cumulative tail for a live update. Unlike `finish()` this does not seal
1397
+ * the diagnostics: more output may follow. It deliberately excludes the trailing
1398
+ * lookbehind bytes so a credential split across chunks cannot leak before the next
1399
+ * chunk resolves it.
1400
+ */
1401
+ preview(limit = CODING_LIVE_BYTES) {
1402
+ return diagnosticTail(this.text, limit);
1403
+ }
1404
+ finish() {
1405
+ if (!this.finished) {
1406
+ this.pending += this.decoder.decode();
1407
+ this.flush(true);
1408
+ this.finished = true;
1409
+ }
1410
+ return {
1411
+ diagnostic: this.text,
1412
+ truncated: this.truncated,
1413
+ observedBytes: this.observedBytes,
1414
+ redacted: this.redactions > 0
1415
+ };
1416
+ }
1417
+ flush(final) {
1418
+ let end = final ? this.pending.length : Math.max(0, this.pending.length - this.lookbehind);
1419
+ const last = this.pending.charCodeAt(end - 1);
1420
+ if (!final && last >= 55296 && last <= 56319) end--;
1421
+ let offset = 0;
1422
+ let safe = "";
1423
+ while (offset < end) {
1424
+ const secret = this.secrets.find((value) => this.pending.startsWith(value, offset));
1425
+ if (secret) {
1426
+ safe += "[redacted]";
1427
+ this.redactions++;
1428
+ offset += secret.length;
1429
+ } else {
1430
+ const code = this.pending.charCodeAt(offset);
1431
+ const char = this.pending[offset] ?? "";
1432
+ safe += code < 32 && code !== 9 && code !== 10 || code >= 127 && code <= 159 ? `\\u${code.toString(16).padStart(4, "0")}` : char;
1433
+ offset++;
1434
+ }
1435
+ }
1436
+ this.pending = this.pending.slice(offset);
1437
+ const tail = diagnosticTail(this.text + safe, this.retainBytes);
1438
+ this.text = tail.text;
1439
+ this.truncated ||= tail.truncated;
1440
+ }
1441
+ };
1442
+ function codingSecrets(env) {
1443
+ const values = /* @__PURE__ */ new Set();
1444
+ function collect(value, depth = 0) {
1445
+ if (depth > 8) return;
1446
+ if (typeof value === "string" && value.length >= 4) values.add(value);
1447
+ else if (value && typeof value === "object")
1448
+ for (const entry of Object.values(value)) collect(entry, depth + 1);
1449
+ }
1450
+ for (const [key, value] of Object.entries(env)) {
1451
+ if (!value || !/KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL|AUTH/i.test(key)) continue;
1452
+ values.add(value);
1453
+ try {
1454
+ collect(JSON.parse(value));
1455
+ } catch {
1456
+ }
1457
+ }
1458
+ return [...values];
1459
+ }
1460
+
1301
1461
  // ../daemon/src/lib/result-source.ts
1302
1462
  import { closeSync as closeSync2, constants as constants2, fstatSync as fstatSync2, openSync as openSync2, readSync, realpathSync as realpathSync2 } from "fs";
1303
1463
  import { basename as basename2, join as join13 } from "path";
@@ -1387,67 +1547,6 @@ function validateCodingCommand(input) {
1387
1547
  };
1388
1548
  }
1389
1549
 
1390
- // ../daemon/src/lib/coding-environment/diagnostics.ts
1391
- var CODING_OUTPUT_BYTES = 64 * 1024;
1392
- function diagnosticTail(value, limit) {
1393
- const bytes = Buffer.from(value);
1394
- if (bytes.length <= limit) return { text: value, truncated: false };
1395
- let offset = bytes.length - limit;
1396
- while (offset < bytes.length && ((bytes[offset] ?? 0) & 192) === 128) offset++;
1397
- return { text: bytes.subarray(offset).toString("utf8"), truncated: true };
1398
- }
1399
- var CodingDiagnostics = class {
1400
- decoder = new TextDecoder();
1401
- secrets;
1402
- lookbehind;
1403
- pending = "";
1404
- text = "";
1405
- truncated = false;
1406
- finished = false;
1407
- constructor(secrets) {
1408
- this.secrets = [...new Set(secrets.filter(Boolean))].sort((a, b) => b.length - a.length);
1409
- this.lookbehind = Math.max(1, ...this.secrets.map((secret) => secret.length)) - 1;
1410
- }
1411
- append(bytes) {
1412
- if (this.finished) throw new Error("Coding diagnostics already finalized");
1413
- for (let offset = 0; offset < bytes.length; offset += 8192) {
1414
- this.pending += this.decoder.decode(bytes.subarray(offset, offset + 8192), { stream: true });
1415
- this.flush(false);
1416
- }
1417
- }
1418
- finish() {
1419
- if (!this.finished) {
1420
- this.pending += this.decoder.decode();
1421
- this.flush(true);
1422
- this.finished = true;
1423
- }
1424
- return { diagnostic: this.text, truncated: this.truncated };
1425
- }
1426
- flush(final) {
1427
- let end = final ? this.pending.length : Math.max(0, this.pending.length - this.lookbehind);
1428
- const last = this.pending.charCodeAt(end - 1);
1429
- if (!final && last >= 55296 && last <= 56319) end--;
1430
- let offset = 0;
1431
- let safe = "";
1432
- while (offset < end) {
1433
- const secret = this.secrets.find((value) => this.pending.startsWith(value, offset));
1434
- if (secret) {
1435
- safe += "[redacted]";
1436
- offset += secret.length;
1437
- } else {
1438
- const code = this.pending.charCodeAt(offset);
1439
- const char = this.pending[offset] ?? "";
1440
- safe += code < 32 && code !== 9 && code !== 10 || code >= 127 && code <= 159 ? `\\u${code.toString(16).padStart(4, "0")}` : char;
1441
- offset++;
1442
- }
1443
- }
1444
- this.pending = this.pending.slice(offset);
1445
- const tail = diagnosticTail(this.text + safe, CODING_OUTPUT_BYTES);
1446
- this.text = tail.text;
1447
- this.truncated ||= tail.truncated;
1448
- }
1449
- };
1450
-
1451
1550
  // ../daemon/src/runtime/coding-directory.ts
1452
1551
  import { realpathSync as realpathSync4 } from "fs";
1453
1552
  import { join as join15 } from "path";
@@ -2895,6 +2994,7 @@ function runCleanupCommand(dockerPath, args, processEnv) {
2895
2994
 
2896
2995
  // ../daemon/src/runtime/pi/coding.ts
2897
2996
  function codingTools(input) {
2997
+ const readSecrets = () => typeof input.secrets === "function" ? input.secrets() : input.secrets ?? [];
2898
2998
  const hostOperations = input.docker ? null : createLocalBashOperations();
2899
2999
  return [
2900
3000
  {
@@ -2935,7 +3035,7 @@ function codingTools(input) {
2935
3035
  { additionalProperties: false }
2936
3036
  ),
2937
3037
  executionMode: "sequential",
2938
- async execute(toolCallId, params, signal) {
3038
+ async execute(toolCallId, params, signal, onUpdate) {
2939
3039
  const command = validateCodingCommand(params);
2940
3040
  const context = await input.context(command.cwd);
2941
3041
  if (context.instructions.state !== "complete")
@@ -2945,7 +3045,27 @@ function codingTools(input) {
2945
3045
  toolCallId,
2946
3046
  input: command
2947
3047
  });
2948
- const output = new CodingDiagnostics(input.secrets ?? []);
3048
+ const output = new CodingDiagnostics(readSecrets());
3049
+ let lastProgressAt = 0;
3050
+ const emitProgress = (force) => {
3051
+ if (!onUpdate) return;
3052
+ const now = Date.now();
3053
+ if (!force && now - lastProgressAt < 400) return;
3054
+ lastProgressAt = now;
3055
+ const preview = output.preview(CODING_LIVE_BYTES);
3056
+ onUpdate({
3057
+ content: [{ type: "text", text: preview.text }],
3058
+ details: {
3059
+ codingProgress: {
3060
+ id: toolCallId,
3061
+ commandId: started.id,
3062
+ output: preview.text,
3063
+ truncated: preview.truncated,
3064
+ elapsedMs: Math.max(0, now - started.startedAt)
3065
+ }
3066
+ }
3067
+ });
3068
+ };
2949
3069
  let outcome;
2950
3070
  try {
2951
3071
  if (input.approval)
@@ -2966,8 +3086,16 @@ function codingTools(input) {
2966
3086
  const result = await operations.exec(
2967
3087
  command.command,
2968
3088
  input.docker ? input.root : cwd.path,
2969
- { onData: (bytes) => output.append(bytes), signal, timeout: command.timeoutSeconds }
3089
+ {
3090
+ onData: (bytes) => {
3091
+ output.append(bytes);
3092
+ emitProgress(false);
3093
+ },
3094
+ signal,
3095
+ timeout: command.timeoutSeconds
3096
+ }
2970
3097
  );
3098
+ emitProgress(true);
2971
3099
  outcome = {
2972
3100
  state: result.exitCode === 0 ? "succeeded" : result.exitCode === null ? "interrupted" : "failed",
2973
3101
  exitCode: result.exitCode,
@@ -3012,6 +3140,74 @@ function codingTools(input) {
3012
3140
  details: { codingEvidence: value }
3013
3141
  };
3014
3142
  }
3143
+ },
3144
+ {
3145
+ name: "coding_log",
3146
+ label: "Read retained command output",
3147
+ description: "Read a bounded page of retained diagnostic output for a coding receipt, or search it. Producing Agents may read their own logs; a teammate must pass the id of the policy-authorized message that carried coding-receipt:<id>. Output is bounded and may be truncated, expired, deleted or unavailable \u2014 report that state honestly and do not infer completeness from an exit code.",
3148
+ parameters: Type.Object(
3149
+ {
3150
+ id: Type.String({ maxLength: 64 }),
3151
+ messageId: Type.Optional(Type.String({ maxLength: 64 })),
3152
+ search: Type.Optional(Type.String({ minLength: 1, maxLength: 256 })),
3153
+ offset: Type.Optional(Type.Integer({ minimum: 0 })),
3154
+ limit: Type.Optional(Type.Integer({ minimum: 1, maximum: 65536 }))
3155
+ },
3156
+ { additionalProperties: false }
3157
+ ),
3158
+ executionMode: "sequential",
3159
+ async execute(_id, params) {
3160
+ const values = params;
3161
+ if (values.search !== void 0) {
3162
+ const result = await input.host.invoke({
3163
+ action: "log-search",
3164
+ id: values.id,
3165
+ query: values.search,
3166
+ ...values.messageId !== void 0 ? { messageId: values.messageId } : {}
3167
+ });
3168
+ return {
3169
+ content: [{ type: "text", text: JSON.stringify(result) }],
3170
+ details: { codingLogSearch: result }
3171
+ };
3172
+ }
3173
+ const value = await input.host.invoke({
3174
+ action: "log",
3175
+ id: values.id,
3176
+ ...values.messageId !== void 0 ? { messageId: values.messageId } : {},
3177
+ ...values.offset !== void 0 ? { offset: values.offset } : {},
3178
+ ...values.limit !== void 0 ? { limit: values.limit } : {}
3179
+ });
3180
+ return {
3181
+ content: [{ type: "text", text: JSON.stringify(value) }],
3182
+ details: { codingLog: value }
3183
+ };
3184
+ }
3185
+ },
3186
+ {
3187
+ name: "source_snapshot",
3188
+ label: "Capture the current source state",
3189
+ description: "Capture a bounded snapshot of the repository source you are about to work from, and quote its reference in your summary. Call this once before you start editing: the reference is how a later change or verification is tied to the version it actually applies to. It is read-only and never changes the repository. The result may be incomplete \u2014 when it is, say so, because an incomplete snapshot cannot support a claim that code is unchanged. Untracked file content is never included unless you name each path.",
3190
+ parameters: Type.Object(
3191
+ {
3192
+ includeUntracked: Type.Optional(
3193
+ Type.Array(Type.String({ maxLength: 4096 }), { maxItems: 1e3 })
3194
+ )
3195
+ },
3196
+ { additionalProperties: false }
3197
+ ),
3198
+ executionMode: "sequential",
3199
+ async execute(toolCallId, params) {
3200
+ const values = params;
3201
+ const value = await input.host.invoke({
3202
+ action: "snapshot",
3203
+ toolCallId,
3204
+ ...values.includeUntracked ? { includeUntracked: values.includeUntracked } : {}
3205
+ });
3206
+ return {
3207
+ content: [{ type: "text", text: JSON.stringify(value) }],
3208
+ details: { sourceSnapshot: value }
3209
+ };
3210
+ }
3015
3211
  }
3016
3212
  ];
3017
3213
  }
@@ -3349,6 +3545,20 @@ function fallbackApi(providerName) {
3349
3545
  return "openai-completions";
3350
3546
  }
3351
3547
  }
3548
+ var UnknownModelError = class extends Error {
3549
+ providerName;
3550
+ modelId;
3551
+ // Fields are declared explicitly, not as constructor parameter properties:
3552
+ // worker subprocesses run Node's strip-only TypeScript, which rejects them.
3553
+ constructor(providerName, modelId) {
3554
+ super(
3555
+ `Unknown model "${modelId}" for provider "${providerName}": it is not in that provider's catalog, and no endpoint is configured for it. Choose a catalogued model, or configure an endpoint for a custom one.`
3556
+ );
3557
+ this.name = "UnknownModelError";
3558
+ this.providerName = providerName;
3559
+ this.modelId = modelId;
3560
+ }
3561
+ };
3352
3562
  function fallbackPiModel(providerName, modelId, baseUrl) {
3353
3563
  return {
3354
3564
  id: modelId,
@@ -3420,6 +3630,7 @@ async function createProtectedPiRuntime(options) {
3420
3630
  function resolvePiModel(runtime, providerName, modelId, baseUrl) {
3421
3631
  const known = runtime.getModel(piProviderName(providerName), modelId);
3422
3632
  if (known) return baseUrl ? { ...known, baseUrl } : known;
3633
+ if (!baseUrl) throw new UnknownModelError(providerName, modelId);
3423
3634
  return fallbackPiModel(providerName, modelId, baseUrl);
3424
3635
  }
3425
3636
 
@@ -3835,6 +4046,16 @@ var PROTECTED_REQUIRED_KEYS = new Set(
3835
4046
  (key) => key !== "images" && key !== "questionEnabled" && key !== "containerNamespace"
3836
4047
  )
3837
4048
  );
4049
+ var VERIFICATION_KEYS = /* @__PURE__ */ new Set([
4050
+ "kind",
4051
+ "agentId",
4052
+ "message",
4053
+ "turnId",
4054
+ "runtime",
4055
+ "verification",
4056
+ "apiKeyRefreshEnabled",
4057
+ "scratch"
4058
+ ]);
3838
4059
  var REVIEW_KEYS = /* @__PURE__ */ new Set([
3839
4060
  "kind",
3840
4061
  "agentId",
@@ -3958,6 +4179,27 @@ function parseWorkerInput(value) {
3958
4179
  assertMinimalWorkerScratch(input.scratch);
3959
4180
  return value;
3960
4181
  }
4182
+ if (kind === "specialist_verification") {
4183
+ assertExactKeys(input, VERIFICATION_KEYS, "verification worker input", VERIFICATION_KEYS);
4184
+ requireString(input.agentId, "agentId");
4185
+ requireString(input.message, "message");
4186
+ requireString(input.turnId, "turnId");
4187
+ assertProtectedProviderRuntime(input.runtime);
4188
+ if (input.apiKeyRefreshEnabled !== true) {
4189
+ throw new Error("worker: verification input requires bound API key refresh");
4190
+ }
4191
+ assertMinimalWorkerScratch(input.scratch);
4192
+ const verification = objectRecord(input.verification, "verification metadata");
4193
+ assertExactKeys(
4194
+ verification,
4195
+ /* @__PURE__ */ new Set(["requestId", "attemptId"]),
4196
+ "verification metadata",
4197
+ /* @__PURE__ */ new Set(["requestId", "attemptId"])
4198
+ );
4199
+ requireString(verification.requestId, "requestId");
4200
+ requireString(verification.attemptId, "attemptId");
4201
+ return value;
4202
+ }
3961
4203
  if (kind === "restricted_review") {
3962
4204
  assertExactKeys(input, REVIEW_KEYS, "restricted review worker input", REVIEW_KEYS);
3963
4205
  requireString(input.agentId, "agentId");
@@ -6006,6 +6248,7 @@ async function createBazilionSession(opts) {
6006
6248
  if (repository) bazilionTools.push(repository.tool);
6007
6249
  if (repository && opts.codingHost && shellTools && shellTools.config.sandboxMode === "docker" && !opts.preparedDocker)
6008
6250
  throw new Error("Coding commands require the admitted Docker runtime");
6251
+ const redactionSecrets = uniqueSecrets(codingSecrets(env));
6009
6252
  if (repository && opts.codingHost && shellTools)
6010
6253
  bazilionTools.push(
6011
6254
  ...codingTools({
@@ -6016,7 +6259,7 @@ async function createBazilionSession(opts) {
6016
6259
  lifecycle: opts.dockerLifecycle,
6017
6260
  approval: shellTools.config.approvalMode === "dangerous",
6018
6261
  approvalHost: bashApprovalHost,
6019
- secrets: Object.entries(env).filter(([key]) => /KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL|AUTH/i.test(key)).map(([, value]) => value ?? "")
6262
+ secrets: () => redactionSecrets
6020
6263
  })
6021
6264
  );
6022
6265
  const customTools = shellTools?.customBash ? [...bazilionTools, shellTools.customBash] : bazilionTools;
@@ -6038,7 +6281,9 @@ async function createBazilionSession(opts) {
6038
6281
  session.agent.getApiKey = async (requestedProvider) => {
6039
6282
  if (requestedProvider !== piProviderName(providerName)) return void 0;
6040
6283
  try {
6041
- return await refreshApiKey(providerName);
6284
+ const token = await refreshApiKey(providerName);
6285
+ if (token && !redactionSecrets.includes(token)) redactionSecrets.push(token);
6286
+ return token;
6042
6287
  } catch {
6043
6288
  return void 0;
6044
6289
  }
@@ -6123,6 +6368,7 @@ async function createProtectedBazilionSession(opts) {
6123
6368
  sessionId: sessionManager.getSessionId()
6124
6369
  });
6125
6370
  if (repository) bazilionTools.push(repository.tool);
6371
+ const redactionSecrets = uniqueSecrets(protectedRuntimeSecrets(opts.runtime));
6126
6372
  if (repository && opts.codingHost)
6127
6373
  bazilionTools.push(
6128
6374
  ...codingTools({
@@ -6133,7 +6379,7 @@ async function createProtectedBazilionSession(opts) {
6133
6379
  lifecycle: opts.dockerLifecycle,
6134
6380
  approval: true,
6135
6381
  approvalHost: opts.bashApprovalHost,
6136
- secrets: protectedRuntimeSecrets(opts.runtime)
6382
+ secrets: () => redactionSecrets
6137
6383
  })
6138
6384
  );
6139
6385
  if (!shellTools.customBash) throw new Error("protected Docker bash tool is unavailable");
@@ -6157,7 +6403,7 @@ async function createProtectedBazilionSession(opts) {
6157
6403
  installProtectedCredentialBoundary(
6158
6404
  session,
6159
6405
  opts.runtime.providerName,
6160
- protectedRuntimeSecrets(opts.runtime),
6406
+ redactionSecrets,
6161
6407
  opts.refreshApiKey
6162
6408
  );
6163
6409
  return sessionHandle(session);
@@ -6208,11 +6454,14 @@ async function createRestrictedReviewSession(opts) {
6208
6454
  installProtectedCredentialBoundary(
6209
6455
  session,
6210
6456
  opts.runtime.providerName,
6211
- protectedRuntimeSecrets(opts.runtime),
6457
+ uniqueSecrets(protectedRuntimeSecrets(opts.runtime)),
6212
6458
  opts.refreshApiKey
6213
6459
  );
6214
6460
  return sessionHandle(session);
6215
6461
  }
6462
+ function uniqueSecrets(values) {
6463
+ return [...new Set(values.filter(Boolean))];
6464
+ }
6216
6465
  function materializeProtectedCredentialFile(runtime, scratch) {
6217
6466
  const fields = [...runtime.credentialEnv ?? []];
6218
6467
  if (runtime.credentialFile) {
@@ -6237,8 +6486,7 @@ function createInMemorySettingsManager() {
6237
6486
  }
6238
6487
  });
6239
6488
  }
6240
- function installProtectedCredentialBoundary(session, providerName, initialSecrets, refreshApiKey) {
6241
- const activeTokens = [...new Set(initialSecrets.filter(Boolean))];
6489
+ function installProtectedCredentialBoundary(session, providerName, activeTokens, refreshApiKey) {
6242
6490
  session.agent.state.messages = redactJsonValue(session.agent.state.messages, activeTokens);
6243
6491
  const originalStream = session.agent.streamFunction;
6244
6492
  session.agent.streamFunction = async (model, context, options) => {
@@ -6359,6 +6607,111 @@ function explicitConversationFile(directory, target) {
6359
6607
  return file;
6360
6608
  }
6361
6609
 
6610
+ // ../daemon/src/runtime/tools/verification.ts
6611
+ var VerificationCapabilityError = class extends Error {
6612
+ constructor(message) {
6613
+ super(message);
6614
+ this.name = "VerificationCapabilityError";
6615
+ }
6616
+ };
6617
+ function verificationTools(host) {
6618
+ const attempted = /* @__PURE__ */ new Set();
6619
+ const request = {
6620
+ def: {
6621
+ name: "verification_request",
6622
+ description: "Read the captured verification request: the exact change under verification, the environment the checks were admitted into, and every declared check with its timeout and any outcome so far. A check you were not asked to run cannot be added here \u2014 a different or additional command needs a new request.",
6623
+ parameters: { type: "object", properties: {}, additionalProperties: false }
6624
+ },
6625
+ async invoke() {
6626
+ return renderBrief(await host.read());
6627
+ }
6628
+ };
6629
+ const check = {
6630
+ def: {
6631
+ name: "verification_check",
6632
+ description: "Invoke exactly one declared check, identified by its ordinal from verification_request. Each check runs at most once: a check that already reported its outcome cannot be run again, and you cannot change its command, cwd, timeout or environment. Report what actually happened, including failures, skips and blockers. A successful exit is evidence about the commands that ran, never proof about later code.",
6633
+ parameters: {
6634
+ type: "object",
6635
+ properties: {
6636
+ ordinal: {
6637
+ type: "integer",
6638
+ minimum: 0,
6639
+ description: "Ordinal of a declared check, as listed by verification_request."
6640
+ }
6641
+ },
6642
+ required: ["ordinal"],
6643
+ additionalProperties: false
6644
+ }
6645
+ },
6646
+ async invoke(args, context) {
6647
+ const ordinal = readOrdinal(args);
6648
+ const brief = await host.read();
6649
+ const declared = brief.checks.find((entry) => entry.ordinal === ordinal);
6650
+ if (!declared) {
6651
+ throw new VerificationCapabilityError(
6652
+ `check ${ordinal} was not captured with this request; only ${brief.checks.map((entry) => entry.ordinal).join(", ")} exist`
6653
+ );
6654
+ }
6655
+ if (declared.state !== "not_executed") {
6656
+ throw new VerificationCapabilityError(
6657
+ `check ${ordinal} already reported '${declared.state}' and cannot be run again`
6658
+ );
6659
+ }
6660
+ if (attempted.has(ordinal)) {
6661
+ throw new VerificationCapabilityError(`check ${ordinal} is already running`);
6662
+ }
6663
+ attempted.add(ordinal);
6664
+ try {
6665
+ const run = await host.invoke(ordinal, { toolCallId: context?.toolCallId ?? "" });
6666
+ return renderRun(run);
6667
+ } catch (error) {
6668
+ attempted.delete(ordinal);
6669
+ throw error;
6670
+ }
6671
+ }
6672
+ };
6673
+ return [request, check];
6674
+ }
6675
+ function readOrdinal(args) {
6676
+ const keys2 = Object.keys(args).sort();
6677
+ if (keys2.length !== 1 || keys2[0] !== "ordinal") {
6678
+ throw new VerificationCapabilityError("verification_check takes only a declared ordinal");
6679
+ }
6680
+ const ordinal = args.ordinal;
6681
+ if (!Number.isInteger(ordinal) || ordinal < 0) {
6682
+ throw new VerificationCapabilityError("ordinal must be a non-negative integer");
6683
+ }
6684
+ return ordinal;
6685
+ }
6686
+ function renderBrief(brief) {
6687
+ const lines = [
6688
+ `Verification request ${brief.requestId}`,
6689
+ `Change: snapshot ${brief.snapshot.id} (base ${brief.snapshot.baseOid.slice(0, 12)}${brief.snapshot.complete ? "" : ", INCOMPLETE COVERAGE"})`,
6690
+ `Environment: image ${brief.environment.image}, shell ${brief.environment.sandbox}${brief.environment.cwd ? `, cwd ${brief.environment.cwd}` : ""}`,
6691
+ `Applicability: ${brief.applicability === "identical" ? "unchanged since capture" : brief.applicability}`
6692
+ ];
6693
+ if (brief.summary) lines.push(`Requested by the requester: ${brief.summary}`);
6694
+ if (brief.writablePaths.length > 0) {
6695
+ lines.push(
6696
+ `Declared generated-output paths (where a check is expected to write; this does not confine writes): ${brief.writablePaths.join(", ")}`
6697
+ );
6698
+ }
6699
+ lines.push("", "Captured checks:");
6700
+ for (const entry of brief.checks) {
6701
+ const outcome = entry.state === "not_executed" ? "not run yet" : `${entry.state}${entry.exitCode === null ? "" : ` (exit ${entry.exitCode})`}${entry.commandId ? ` receipt ${entry.commandId}` : ""}`;
6702
+ lines.push(
6703
+ ` [${entry.ordinal}] ${entry.command} (cwd ${entry.cwd}, ${entry.timeoutMs} ms, ${entry.purpose}) \u2014 ${outcome}`
6704
+ );
6705
+ }
6706
+ lines.push("", "Run each captured check with verification_check. Report failures as failures.");
6707
+ return lines.join("\n");
6708
+ }
6709
+ function renderRun(run) {
6710
+ const head = `Check ${run.ordinal}: ${run.state}${run.exitCode === null ? "" : ` (exit ${run.exitCode})`}${run.commandId ? ` \u2014 receipt ${run.commandId}` : ""}${run.truncated ? " [output truncated]" : ""}`;
6711
+ return run.output.trim() ? `${head}
6712
+ ${run.output}` : head;
6713
+ }
6714
+
6362
6715
  // ../daemon/src/runtime/worker/api-key-refresh.ts
6363
6716
  function createIpcApiKeyRefresher(call, context) {
6364
6717
  return async (providerName) => {
@@ -6582,8 +6935,16 @@ function createReviewState(evidenceItems) {
6582
6935
  tools
6583
6936
  };
6584
6937
  }
6938
+ function createIpcVerificationHost(ipcCall, identity2) {
6939
+ return {
6940
+ // The request identity is bound here from the worker's own input, so a tool call cannot address
6941
+ // another request's attempt: only an ordinal travels.
6942
+ read: () => ipcCall("verificationRead", identity2),
6943
+ invoke: (ordinal) => ipcCall("verificationRun", { ...identity2, ordinal })
6944
+ };
6945
+ }
6585
6946
  async function createSessionForInput(input, ipcCall) {
6586
- if (input.kind !== "restricted_review" && !input.repositoryContext)
6947
+ if (input.kind !== "restricted_review" && input.kind !== "specialist_verification" && !input.repositoryContext)
6587
6948
  throw new Error("Coding turn requires daemon-prepared repository context");
6588
6949
  if (input.kind === "configured_operator_http") {
6589
6950
  const paths = resolvePaths();
@@ -6641,6 +7002,18 @@ async function createSessionForInput(input, ipcCall) {
6641
7002
  agentId: input.kind === "protected" ? input.agent.agent.id : input.agentId,
6642
7003
  turnId: input.turnId
6643
7004
  });
7005
+ if (input.kind === "specialist_verification") {
7006
+ const handle2 = await createRestrictedReviewSession({
7007
+ runtime: input.runtime,
7008
+ scratch: input.scratch,
7009
+ systemPrompt: VERIFICATION_SYSTEM_PROMPT,
7010
+ tools: verificationTools(createIpcVerificationHost(ipcCall, input.verification)).map(
7011
+ ourToolToPiTool
7012
+ ),
7013
+ refreshApiKey
7014
+ });
7015
+ return { handle: handle2 };
7016
+ }
6644
7017
  if (input.kind === "restricted_review") {
6645
7018
  const reviewState = createReviewState(input.review.evidence);
6646
7019
  const handle2 = await createRestrictedReviewSession({
@@ -6717,7 +7090,7 @@ async function main() {
6717
7090
  session = handle.session;
6718
7091
  const consumptionAcks = /* @__PURE__ */ new Set();
6719
7092
  const unsubscribe = session.subscribe((piEvent) => {
6720
- if (input.kind !== "restricted_review" && input.questionEnabled && piEvent.type === "message_end" && piEvent.message.role === "toolResult" && piEvent.message.toolName === "ask_user" && !piEvent.message.isError) {
7093
+ if (input.kind !== "restricted_review" && input.kind !== "specialist_verification" && input.questionEnabled && piEvent.type === "message_end" && piEvent.message.role === "toolResult" && piEvent.message.toolName === "ask_user" && !piEvent.message.isError) {
6721
7094
  const message = piEvent.message;
6722
7095
  const content = message.content[0];
6723
7096
  if (content?.type === "text") {
@@ -6747,8 +7120,8 @@ async function main() {
6747
7120
  });
6748
7121
  try {
6749
7122
  const promptMessage = redactJsonValue(input.message, activeAccessTokens);
6750
- const sanitizedImages = input.kind === "restricted_review" ? [] : redactJsonValue(input.images ?? [], activeAccessTokens);
6751
- const promptImages = input.kind === "restricted_review" ? [] : sanitizedImages.map((image) => ({
7123
+ const sanitizedImages = input.kind === "restricted_review" || input.kind === "specialist_verification" ? [] : redactJsonValue(input.images ?? [], activeAccessTokens);
7124
+ const promptImages = input.kind === "restricted_review" || input.kind === "specialist_verification" ? [] : sanitizedImages.map((image) => ({
6752
7125
  type: "image",
6753
7126
  data: image.data,
6754
7127
  mimeType: image.mimeType
@@ -6791,6 +7164,24 @@ main().catch((error) => {
6791
7164
  }
6792
7165
  process.exit(1);
6793
7166
  });
7167
+ var VERIFICATION_SYSTEM_PROMPT = `You are a restricted verification specialist. You verify one
7168
+ captured change against the checks your requester selected. Call verification_request to read the
7169
+ request, then verification_check once per declared check, in order.
7170
+
7171
+ Boundaries you cannot cross, and must not try to:
7172
+ - Only the declared ordinal of a captured check can run, once. You cannot change its command, cwd,
7173
+ timeout or environment, add a check, or retry a check that already reported.
7174
+ - You have no shell, no editor, no browser, no network tool and no deployment credential. A missing
7175
+ toolchain, service or approval is an explicit blocker to report, never something to work around.
7176
+ - Generated output may only be written to the declared writable paths.
7177
+
7178
+ Report what actually happened. A non-zero exit is a failure of that check; say so plainly. An exit
7179
+ code is evidence about the commands that ran, never proof about later code, and never a statement
7180
+ that the change is ready to merge. Distinguish a failure from a check you did not run, and never
7181
+ describe an unrun check as passing.
7182
+
7183
+ Finish with a short summary: the snapshot you verified, each check with its outcome and receipt, and
7184
+ any blocker or limitation that stopped a check. Do not recommend deployment.`;
6794
7185
  var REVIEW_SYSTEM_PROMPT = `You are a restricted learning reviewer. Analyze only the supplied
6795
7186
  transcript digest and approved-lesson index. You cannot act on the world. Call propose_lesson once
6796
7187
  with zero to five proposals, then stop.