@akagilnc/pi-workflow-roles 0.1.3673 → 0.1.3685

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 (42) hide show
  1. package/dist/acp-host/production-host.js +297 -166
  2. package/dist/audit-escalation.js +4 -3
  3. package/dist/diarist-contracts.js +4 -4
  4. package/dist/diarist-role.js +10 -4
  5. package/dist/diarist.js +121 -17
  6. package/dist/doctor-role.js +2 -1
  7. package/dist/gatekeeper-role.js +3 -2
  8. package/dist/judge-role.js +2 -1
  9. package/dist/package-contracts/terminating-tools.js +1 -1
  10. package/dist/public-cli/inspector-run.js +3 -13
  11. package/dist/public-cli/instruction-seat-run.js +6 -31
  12. package/dist/public-cli/invocation.js +32 -0
  13. package/dist/public-cli/judge-run.js +1 -7
  14. package/dist/public-cli/main.js +714 -728
  15. package/dist/public-cli/run-lifecycle.js +0 -28
  16. package/dist/public-cli/seat-ticket-binding.js +15 -104
  17. package/dist/readable-gate-item.js +16 -0
  18. package/dist/role-runtime.js +89 -10
  19. package/dist/submission-errors.js +4 -1
  20. package/package.json +1 -1
  21. package/resources/diarist-collect.md +10 -0
  22. package/src/audit-escalation.ts +4 -3
  23. package/src/diarist-contracts.ts +21 -9
  24. package/src/diarist-role.ts +15 -4
  25. package/src/diarist.ts +192 -22
  26. package/src/doctor-role.ts +2 -1
  27. package/src/gatekeeper-role.ts +3 -2
  28. package/src/judge-role.ts +2 -1
  29. package/src/package-contracts/terminating-tools.ts +1 -1
  30. package/src/public-cli/coder-run.ts +1 -7
  31. package/src/public-cli/countersign-run.ts +238 -86
  32. package/src/public-cli/diarist-run.ts +83 -28
  33. package/src/public-cli/fixer-run.ts +1 -7
  34. package/src/public-cli/inspector-run.ts +3 -17
  35. package/src/public-cli/instruction-seat-run.ts +6 -36
  36. package/src/public-cli/invocation.ts +52 -0
  37. package/src/public-cli/judge-run.ts +1 -7
  38. package/src/public-cli/run-lifecycle.ts +0 -31
  39. package/src/public-cli/seat-ticket-binding.ts +14 -138
  40. package/src/readable-gate-item.ts +20 -0
  41. package/src/role-runtime.ts +107 -9
  42. package/src/submission-errors.ts +4 -1
@@ -2228,6 +2228,19 @@ var init_reviewer_output = __esm({
2228
2228
  }
2229
2229
  });
2230
2230
 
2231
+ // src/readable-gate-item.ts
2232
+ function readableGateItem(value) {
2233
+ return typeof value === "string" ? value : JSON.stringify(value);
2234
+ }
2235
+ function joinReadableGateItems(items, separator = "; ") {
2236
+ return items.map(readableGateItem).join(separator);
2237
+ }
2238
+ var init_readable_gate_item = __esm({
2239
+ "src/readable-gate-item.ts"() {
2240
+ "use strict";
2241
+ }
2242
+ });
2243
+
2231
2244
  // src/audit-escalation.ts
2232
2245
  function buildAuditEscalationResult(decision, deliveredOutput) {
2233
2246
  const auditOwned = {
@@ -2276,17 +2289,17 @@ function humanDecisionText(decision, result) {
2276
2289
  lines.push(`Reason: ${result.reason}`);
2277
2290
  }
2278
2291
  if (Array.isArray(result.conflicts)) {
2279
- lines.push("Conflicts:", ...result.conflicts.map((conflict) => `- ${conflict}`));
2292
+ lines.push("Conflicts:", ...result.conflicts.map((conflict) => `- ${readableGateItem(conflict)}`));
2280
2293
  }
2281
2294
  if (officer !== void 0 && Array.isArray(result.findings) && result.findings.length > 0) {
2282
- lines.push("Findings:", ...result.findings.map((finding2) => `- ${finding2}`));
2295
+ lines.push("Findings:", ...result.findings.map((finding2) => `- ${readableGateItem(finding2)}`));
2283
2296
  }
2284
2297
  const gate = result.auditDecisionGate;
2285
2298
  if (gate !== null && typeof gate === "object" && !Array.isArray(gate)) {
2286
2299
  const record4 = gate;
2287
2300
  if (typeof record4.question === "string") lines.push(`Question: ${record4.question}`);
2288
2301
  if (Array.isArray(record4.options)) {
2289
- lines.push("Options:", ...record4.options.map((option) => `- ${option}`));
2302
+ lines.push("Options:", ...record4.options.map((option) => `- ${readableGateItem(option)}`));
2290
2303
  }
2291
2304
  }
2292
2305
  return lines.join("\n");
@@ -2338,6 +2351,7 @@ var AUDIT_ESCALATION_KIND, AUDIT_ESCALATION_LIVE_REGISTRY;
2338
2351
  var init_audit_escalation = __esm({
2339
2352
  "src/audit-escalation.ts"() {
2340
2353
  "use strict";
2354
+ init_readable_gate_item();
2341
2355
  AUDIT_ESCALATION_KIND = "audit_escalation";
2342
2356
  AUDIT_ESCALATION_LIVE_REGISTRY = /* @__PURE__ */ new WeakSet();
2343
2357
  }
@@ -2346,7 +2360,7 @@ var init_audit_escalation = __esm({
2346
2360
  // src/submission-errors.ts
2347
2361
  function gatekeeperNonPassMessage(result) {
2348
2362
  if (result.status === "bounce") {
2349
- const findings = result.findings.length === 0 ? "\uFF08\u65E0 findings\uFF09" : result.findings.join("; ");
2363
+ const findings = result.findings.length === 0 ? "\uFF08\u65E0 findings\uFF09" : joinReadableGateItems(result.findings);
2350
2364
  return `\u95E8\u4E0B\u7701\u6253\u56DE\u91CD\u5199\uFF0Cfindings\uFF1A${findings}`;
2351
2365
  }
2352
2366
  if (result.status === "unreadable") {
@@ -2358,6 +2372,7 @@ var GatekeeperDecisionError, WorkerCommitReminderError, WorkerPrefixReminderErro
2358
2372
  var init_submission_errors = __esm({
2359
2373
  "src/submission-errors.ts"() {
2360
2374
  "use strict";
2375
+ init_readable_gate_item();
2361
2376
  GatekeeperDecisionError = class extends Error {
2362
2377
  result;
2363
2378
  constructor(result) {
@@ -3242,7 +3257,7 @@ function validateRecordedDiaristOutput(value) {
3242
3257
  } catch {
3243
3258
  throw new Error("Diarist output has no execution discriminator");
3244
3259
  }
3245
- if (status === "completed") {
3260
+ if (status === "completed" || status === "escalate") {
3246
3261
  return value;
3247
3262
  }
3248
3263
  throw new Error("Diarist output has no execution discriminator");
@@ -3274,7 +3289,7 @@ var init_diarist_contracts = __esm({
3274
3289
  DIARIST_SOURCES_FLAG = {
3275
3290
  name: "ak-diarist-sources",
3276
3291
  definition: {
3277
- description: "Frozen per-ticket source catalog the diarist selects from",
3292
+ description: "Frozen source catalog the diarist selects from (may be unbound until LLM asserts ticketNumber)",
3278
3293
  type: "string"
3279
3294
  }
3280
3295
  };
@@ -3496,7 +3511,7 @@ function validateAcceptedDetails(toolName, details) {
3496
3511
  [GATEKEEPER_OUTPUT_TOOL_NAME]: ["dispatch", "pass"],
3497
3512
  [NAVIGATOR_OUTPUT_TOOL_NAME]: ["advice"],
3498
3513
  [AUDITOR_OUTPUT_TOOL_NAME]: ["pass", "bounce", "escalate"],
3499
- [DIARIST_OUTPUT_TOOL_NAME]: ["completed"]
3514
+ [DIARIST_OUTPUT_TOOL_NAME]: ["completed", "escalate"]
3500
3515
  };
3501
3516
  const collectorDiscriminator = toolName === COLLECTOR_OUTPUT_TOOL && Array.isArray(candidate?.groups);
3502
3517
  const baseDiscriminator = discriminator;
@@ -4643,27 +4658,6 @@ async function findLatestRunIdForSeatTicket(input) {
4643
4658
  }
4644
4659
  return best;
4645
4660
  }
4646
- async function collectBookRunTicketNumbers(input) {
4647
- const ledgerHome = resolveActivationLedgerHome(input.home);
4648
- const runsDir = join11(
4649
- activationBookDirectory(ledgerHome, input.bookKey),
4650
- "runs"
4651
- );
4652
- let entries;
4653
- try {
4654
- entries = await readdir2(runsDir);
4655
- } catch (error) {
4656
- if (errorCodeOf2(error) === "ENOENT") return /* @__PURE__ */ new Set();
4657
- throw error;
4658
- }
4659
- const known = /* @__PURE__ */ new Set();
4660
- for (const entry of entries) {
4661
- if (!entry.includes("@")) continue;
4662
- const ticketNumber = await readRunTicketNumber(join11(runsDir, entry));
4663
- if (ticketNumber !== void 0) known.add(ticketNumber);
4664
- }
4665
- return known;
4666
- }
4667
4661
  function parsePersistedTicketIdentity(record4) {
4668
4662
  const correlationId = typeof record4.correlationId === "string" && record4.correlationId.trim() !== "" ? record4.correlationId : void 0;
4669
4663
  const ticketNumber = typeof record4.ticketNumber === "number" && Number.isSafeInteger(record4.ticketNumber) && record4.ticketNumber >= 1 ? record4.ticketNumber : void 0;
@@ -6158,6 +6152,7 @@ __export(invocation_exports, {
6158
6152
  admitNotaryInvocation: () => admitNotaryInvocation,
6159
6153
  admitReviewerInvocation: () => admitReviewerInvocation,
6160
6154
  bindAdmittedTicketNumber: () => bindAdmittedTicketNumber,
6155
+ bindTicketNumberOnRunDirectory: () => bindTicketNumberOnRunDirectory,
6161
6156
  buildCoderTransportPrompt: () => buildCoderTransportPrompt,
6162
6157
  buildCollectorTransportPrompt: () => buildCollectorTransportPrompt,
6163
6158
  buildCountersignTransportPrompt: () => buildCountersignTransportPrompt,
@@ -6206,6 +6201,7 @@ __export(invocation_exports, {
6206
6201
  resolveGitHubRemoteRepository: () => resolveGitHubRemoteRepository
6207
6202
  });
6208
6203
  import { execFileSync as execFileSync2 } from "node:child_process";
6204
+ import { existsSync as existsSync4 } from "node:fs";
6209
6205
  import {
6210
6206
  lstat as lstat3,
6211
6207
  mkdir,
@@ -6352,6 +6348,40 @@ async function bindAdmittedTicketNumber(admitted, ticketNumber) {
6352
6348
  "utf8"
6353
6349
  );
6354
6350
  }
6351
+ async function bindTicketNumberOnRunDirectory(runDirectory, ticketNumber) {
6352
+ if (!Number.isSafeInteger(ticketNumber) || ticketNumber < 1) {
6353
+ throw new Error(
6354
+ `bindTicketNumberOnRunDirectory requires a safe positive integer, got ${String(ticketNumber)}`
6355
+ );
6356
+ }
6357
+ const admittedPath = join13(runDirectory, "admitted-request.json");
6358
+ const invocationPath = join13(runDirectory, "invocation.json");
6359
+ const admitted = JSON.parse(await readFile9(admittedPath, "utf8"));
6360
+ const existing = admitted.ticketNumber;
6361
+ if (typeof existing === "number") {
6362
+ if (existing === ticketNumber) return;
6363
+ throw new Error(
6364
+ `bindTicketNumberOnRunDirectory refuses to replace existing ticket #${existing} with #${ticketNumber}`
6365
+ );
6366
+ }
6367
+ if (existsSync4(invocationPath)) {
6368
+ const invocation = JSON.parse(
6369
+ await readFile9(invocationPath, "utf8")
6370
+ );
6371
+ if (typeof invocation.ticketNumber === "number" && invocation.ticketNumber !== ticketNumber) {
6372
+ throw new Error(
6373
+ `bindTicketNumberOnRunDirectory refuses to replace invocation ticket #${invocation.ticketNumber} with #${ticketNumber}`
6374
+ );
6375
+ }
6376
+ }
6377
+ await writeFile4(
6378
+ admittedPath,
6379
+ `${JSON.stringify({ ...admitted, ticketNumber }, null, 2)}
6380
+ `,
6381
+ "utf8"
6382
+ );
6383
+ await mergeInvocationIdentityPage(runDirectory, { ticketNumber });
6384
+ }
6355
6385
  async function recordLaunchedPiIdentity(runDirectory, identity) {
6356
6386
  await mergeInvocationIdentityPage(runDirectory, {
6357
6387
  piExecutable: identity.executable,
@@ -8388,7 +8418,7 @@ var load_production_acp_host_exports = {};
8388
8418
  __export(load_production_acp_host_exports, {
8389
8419
  loadProductionAcpHostFactory: () => loadProductionAcpHostFactory
8390
8420
  });
8391
- import { existsSync as existsSync4 } from "node:fs";
8421
+ import { existsSync as existsSync5 } from "node:fs";
8392
8422
  import { join as join14 } from "node:path";
8393
8423
  import { pathToFileURL } from "node:url";
8394
8424
  async function loadProductionAcpHostFactory(packageRoot, host) {
@@ -8398,7 +8428,7 @@ async function loadProductionAcpHostFactory(packageRoot, host) {
8398
8428
  }
8399
8429
  const built = join14(packageRoot, "dist/acp-host/production-host.js");
8400
8430
  const source = join14(packageRoot, "src/acp-host/production-host.ts");
8401
- const target = existsSync4(built) ? built : source;
8431
+ const target = existsSync5(built) ? built : source;
8402
8432
  const href = pathToFileURL(target).href;
8403
8433
  const mod = await import(href);
8404
8434
  const create = mod.createProductionAcpRoleTurnHost;
@@ -9263,6 +9293,30 @@ var init_config = __esm({
9263
9293
  }
9264
9294
  });
9265
9295
 
9296
+ // src/public-cli/seat-ticket-binding.ts
9297
+ async function tryResumeSameTicketSeatRun(input) {
9298
+ if (input.freshSummons === true) return void 0;
9299
+ if (input.parentRunPath === void 0 && input.ticketNumber === void 0) {
9300
+ return void 0;
9301
+ }
9302
+ const previousRunId = await findLatestRunIdForSeatTicket({
9303
+ home: input.home,
9304
+ bookKey: resolveBookKeyFromGit(input.projectRoot),
9305
+ role: input.role,
9306
+ ...input.parentRunPath === void 0 ? {} : { parentRunPath: input.parentRunPath },
9307
+ ...input.ticketNumber === void 0 ? {} : { ticketNumber: input.ticketNumber }
9308
+ });
9309
+ if (previousRunId === void 0) return void 0;
9310
+ return await input.resume(previousRunId, input.summons);
9311
+ }
9312
+ var init_seat_ticket_binding = __esm({
9313
+ "src/public-cli/seat-ticket-binding.ts"() {
9314
+ "use strict";
9315
+ init_activation_ledger_git();
9316
+ init_run_lifecycle();
9317
+ }
9318
+ });
9319
+
9266
9320
  // src/ticket-provenance-contracts.ts
9267
9321
  function isRecord11(value) {
9268
9322
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -9356,7 +9410,7 @@ var init_ticket_provenance_contracts = __esm({
9356
9410
 
9357
9411
  // src/ticket-provenance.ts
9358
9412
  import { createHash as createHash5 } from "node:crypto";
9359
- import { appendFileSync as appendFileSync2, existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "node:fs";
9413
+ import { appendFileSync as appendFileSync2, existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "node:fs";
9360
9414
  import { join as join16 } from "node:path";
9361
9415
  function ticketProvenanceSubject(ticketNumber) {
9362
9416
  if (!Number.isSafeInteger(ticketNumber) || ticketNumber < 1) {
@@ -9421,7 +9475,7 @@ function resolveTicketProvenanceVolume(ticketNumber, cwd, home) {
9421
9475
  }
9422
9476
  function readOfferedIdentities(ticketNumber, cwd, home) {
9423
9477
  const { offeredWatermarkFile } = resolveTicketProvenanceVolume(ticketNumber, cwd, home);
9424
- if (!existsSync5(offeredWatermarkFile)) return /* @__PURE__ */ new Set();
9478
+ if (!existsSync6(offeredWatermarkFile)) return /* @__PURE__ */ new Set();
9425
9479
  let text;
9426
9480
  try {
9427
9481
  text = readFileSync2(offeredWatermarkFile, "utf8");
@@ -9632,84 +9686,6 @@ var init_ticket_provenance = __esm({
9632
9686
  }
9633
9687
  });
9634
9688
 
9635
- // src/public-cli/seat-ticket-binding.ts
9636
- import { existsSync as existsSync6 } from "node:fs";
9637
- function instructionTicketTokens(instruction) {
9638
- const tokens = [];
9639
- const seen = /* @__PURE__ */ new Set();
9640
- for (const match of instruction.matchAll(/#([1-9]\d*)/g)) {
9641
- const parsed = Number(match[1]);
9642
- if (!Number.isSafeInteger(parsed)) continue;
9643
- if (seen.has(parsed)) continue;
9644
- seen.add(parsed);
9645
- tokens.push(parsed);
9646
- }
9647
- return tokens;
9648
- }
9649
- async function resolveKnownTicketNumber(input) {
9650
- const tokens = instructionTicketTokens(input.instruction);
9651
- if (tokens.length === 0) return void 0;
9652
- const target = tokens[0];
9653
- const volume = resolveTicketProvenanceVolume(
9654
- target,
9655
- input.projectRoot,
9656
- input.home
9657
- );
9658
- if (existsSync6(volume.volumeDir)) return target;
9659
- const runTickets = await readBookRunTickets(input);
9660
- return runTickets.has(target) ? target : void 0;
9661
- }
9662
- async function readBookRunTickets(input) {
9663
- let bookKey;
9664
- try {
9665
- bookKey = input.bookKey ?? resolveBookKeyFromGit(input.projectRoot);
9666
- } catch (error) {
9667
- if (error instanceof ActivationGitRepositoryRequiredError) return /* @__PURE__ */ new Set();
9668
- throw error;
9669
- }
9670
- return await collectBookRunTicketNumbers({ home: input.home, bookKey });
9671
- }
9672
- async function bindReusedTicketNumber(admitted, ticketNumber) {
9673
- if (ticketNumber === void 0) return;
9674
- if (admitted.ticketNumber !== void 0) return;
9675
- await bindAdmittedTicketNumber(admitted, ticketNumber);
9676
- }
9677
- async function resolveSeatTicketBinding(admitted, env) {
9678
- if (admitted.ticketNumber !== void 0) return admitted.ticketNumber;
9679
- const ticketNumber = await resolveKnownTicketNumber({
9680
- instruction: admitted.instruction,
9681
- projectRoot: admitted.projectRoot,
9682
- home: env.home,
9683
- bookKey: admitted.bookKey
9684
- });
9685
- await bindReusedTicketNumber(admitted, ticketNumber);
9686
- return ticketNumber;
9687
- }
9688
- async function tryResumeSameTicketSeatRun(input) {
9689
- if (input.freshSummons === true) return void 0;
9690
- if (input.parentRunPath === void 0 && input.ticketNumber === void 0) {
9691
- return void 0;
9692
- }
9693
- const previousRunId = await findLatestRunIdForSeatTicket({
9694
- home: input.home,
9695
- bookKey: resolveBookKeyFromGit(input.projectRoot),
9696
- role: input.role,
9697
- ...input.parentRunPath === void 0 ? {} : { parentRunPath: input.parentRunPath },
9698
- ...input.ticketNumber === void 0 ? {} : { ticketNumber: input.ticketNumber }
9699
- });
9700
- if (previousRunId === void 0) return void 0;
9701
- return await input.resume(previousRunId, input.summons);
9702
- }
9703
- var init_seat_ticket_binding = __esm({
9704
- "src/public-cli/seat-ticket-binding.ts"() {
9705
- "use strict";
9706
- init_activation_ledger_git();
9707
- init_ticket_provenance();
9708
- init_invocation();
9709
- init_run_lifecycle();
9710
- }
9711
- });
9712
-
9713
9689
  // src/public-cli/case-dossier-delivery.ts
9714
9690
  import { stat as stat2 } from "node:fs/promises";
9715
9691
  async function describeDossierFile(path) {
@@ -9873,7 +9849,7 @@ function failureReason(error) {
9873
9849
  }
9874
9850
  function asStringArray3(value) {
9875
9851
  if (!Array.isArray(value)) return [];
9876
- return value.map((item) => typeof item === "string" ? item : JSON.stringify(item));
9852
+ return value.map(readableGateItem);
9877
9853
  }
9878
9854
  function isRecord13(value) {
9879
9855
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -10012,6 +9988,7 @@ var init_gatekeeper_role = __esm({
10012
9988
  "use strict";
10013
9989
  init_auditor_dossier_tool();
10014
9990
  init_submission_errors();
9991
+ init_readable_gate_item();
10015
9992
  init_inspector_contracts();
10016
9993
  init_gatekeeper_output();
10017
9994
  init_shape_unreadable_failure();
@@ -16482,11 +16459,6 @@ async function runPublicInspector(argv, env, io, parseInspectorArgv2) {
16482
16459
  throw error;
16483
16460
  }
16484
16461
  const projectRoot = parsed.project ?? env.cwd;
16485
- const reusedTicketNumber = await resolveKnownTicketNumber({
16486
- instruction: parsed.instruction,
16487
- projectRoot,
16488
- home: env.home
16489
- });
16490
16462
  const parentRunPath = parentRunPathFromGatePointerInstruction(parsed.instruction);
16491
16463
  if (parentRunPath !== void 0) {
16492
16464
  const summons = {
@@ -16552,11 +16524,7 @@ async function runPublicInspector(argv, env, io, parseInspectorArgv2) {
16552
16524
  env,
16553
16525
  io,
16554
16526
  request: turnRequest,
16555
- adapters: inspectorAdapters({
16556
- beforeDispatch: async (admittedSeat) => {
16557
- await bindReusedTicketNumber(admittedSeat, reusedTicketNumber);
16558
- }
16559
- }),
16527
+ adapters: inspectorAdapters(),
16560
16528
  ...env.engine === void 0 ? {} : { effectiveEngine: env.engine }
16561
16529
  });
16562
16530
  }
@@ -16737,7 +16705,6 @@ async function runPublicInstructionSeat(argv, env, io, role, parseArgv) {
16737
16705
  let auditorSubject;
16738
16706
  let auditorSourceRun;
16739
16707
  let auditorSourceTicket;
16740
- let reusedTicketNumber;
16741
16708
  const projectRoot = parsed.project ?? env.cwd;
16742
16709
  if (role === "auditor") {
16743
16710
  if (parsed.subject !== "judge" && parsed.subject !== "doctor") {
@@ -16772,12 +16739,6 @@ async function runPublicInstructionSeat(argv, env, io, role, parseArgv) {
16772
16739
  );
16773
16740
  return { exitCode: 2 };
16774
16741
  }
16775
- } else {
16776
- reusedTicketNumber = await resolveKnownTicketNumber({
16777
- instruction: parsed.instruction,
16778
- projectRoot,
16779
- home: env.home
16780
- });
16781
16742
  }
16782
16743
  const summons = {
16783
16744
  instruction: parsed.instruction,
@@ -16803,21 +16764,6 @@ async function runPublicInstructionSeat(argv, env, io, role, parseArgv) {
16803
16764
  })
16804
16765
  });
16805
16766
  if (resumed !== void 0) return resumed;
16806
- } else if (reusedTicketNumber !== void 0) {
16807
- const resumed = await tryResumeSameTicketSeatRun({
16808
- home: env.home,
16809
- projectRoot,
16810
- role,
16811
- ticketNumber: reusedTicketNumber,
16812
- freshSummons: env.freshSummons,
16813
- summons,
16814
- resume: (runId, materials) => runPublicInstructionSeatResume(
16815
- { runId, ...materials === void 0 ? {} : { summons: materials } },
16816
- env,
16817
- io
16818
- )
16819
- });
16820
- if (resumed !== void 0) return resumed;
16821
16767
  }
16822
16768
  let admitted;
16823
16769
  try {
@@ -16875,8 +16821,6 @@ async function runPublicInstructionSeat(argv, env, io, role, parseArgv) {
16875
16821
  beforeDispatch: async (admittedSeat) => {
16876
16822
  if (auditorSourceTicket !== void 0) {
16877
16823
  await bindAdmittedTicketNumber(admittedSeat, auditorSourceTicket);
16878
- } else {
16879
- await bindReusedTicketNumber(admittedSeat, reusedTicketNumber);
16880
16824
  }
16881
16825
  }
16882
16826
  }),
@@ -16984,12 +16928,7 @@ async function runPublicJudge(argv, env, io, parseJudgeArgv2) {
16984
16928
  })
16985
16929
  }
16986
16930
  }),
16987
- adapters: {
16988
- ...judgeAdapters(),
16989
- beforeDispatch: async (admittedSeat) => {
16990
- await resolveSeatTicketBinding(admittedSeat, env);
16991
- }
16992
- },
16931
+ adapters: judgeAdapters(),
16993
16932
  ...env.engine === void 0 ? {} : { effectiveEngine: env.engine }
16994
16933
  });
16995
16934
  }
@@ -17013,7 +16952,6 @@ var init_judge_run = __esm({
17013
16952
  init_engine_material();
17014
16953
  init_cli_errors();
17015
16954
  init_invocation();
17016
- init_seat_ticket_binding();
17017
16955
  init_run_lifecycle();
17018
16956
  init_settlement();
17019
16957
  init_turn_request();
@@ -20149,7 +20087,7 @@ function createDoctorRoleRuntime(pi, dependencies, host) {
20149
20087
  const details = testimony.status === "completed" ? { ...testimony, cost: activation.patient.cost } : testimony;
20150
20088
  const acceptedDetails = details;
20151
20089
  return disposeComplianceDecision(audit, { pass: (usage) => ({ content: [{ type: "text", text: DOCTOR_ACCEPTED_TEXT }], details: acceptedDetails, terminate: true, ...usage === void 0 ? {} : { usage } }), noReceipt: (auditNoReceipt, usageProjection) => ({ content: [{ type: "text", text: DOCTOR_ACCEPTED_AUDIT_NO_RECEIPT_TEXT }], details: { ...acceptedDetails, auditNoReceipt }, terminate: true, ...usageProjection }), received: (auditReceived, usageProjection) => ({ content: [{ type: "text", text: DOCTOR_ACCEPTED_TEXT }], details: { ...acceptedDetails, audit: auditReceived.reply }, terminate: true, ...usageProjection }), bounce: (violations) => {
20152
- throw new Error(`\u592A\u533B\u7F72\u56DE\u6267\u8FDD soul\uFF1A${violations.join("; ")}`);
20090
+ throw new Error(`\u592A\u533B\u7F72\u56DE\u6267\u8FDD soul\uFF1A${joinReadableGateItems(violations)}`);
20153
20091
  }, escalate: (result) => result }, acceptedDetails);
20154
20092
  } });
20155
20093
  pi.on("before_agent_start", (event) => {
@@ -20180,6 +20118,7 @@ var init_doctor_role = __esm({
20180
20118
  "use strict";
20181
20119
  init_audit_escalation();
20182
20120
  init_compliance_transport();
20121
+ init_readable_gate_item();
20183
20122
  init_dossier_resolution();
20184
20123
  init_doctor_contracts();
20185
20124
  init_sitian_facade();
@@ -20439,8 +20378,18 @@ var init_diarist_role = __esm({
20439
20378
  openToolObject(
20440
20379
  Type23.Object({
20441
20380
  status: Type23.Unknown({
20442
- description: "completed \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8"
20381
+ description: "completed | escalate \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8"
20443
20382
  }),
20383
+ ticketNumber: Type23.Optional(
20384
+ Type23.Unknown({
20385
+ description: "\u672C\u5EAD\u5BF9\u8C61\u7968\u53F7\uFF08\u6B63\u6574\u6570\uFF09\u6216 null/\u7701\u7565\uFF1D\u771F\u65E0\u7968\uFF1B\u673A\u68B0\u9A8C\u771F\u540E\u4E0B\u6E38\u8D70 typed \u952E\uFF1B\u8BA4\u4E0D\u51FA\u7528 status=escalate\uFF0C\u4E0D\u6D17\u6210\u65E0\u5F55"
20386
+ })
20387
+ ),
20388
+ reason: Type23.Optional(
20389
+ Type23.String({
20390
+ description: "status \u4E3A escalate \u65F6\uFF1A\u8BA4\u4E0D\u51FA\u672C\u5EAD\u5BF9\u8C61\u7684\u539F\u56E0"
20391
+ })
20392
+ ),
20444
20393
  selections: Type23.Array(
20445
20394
  Type23.Object(
20446
20395
  {
@@ -20454,7 +20403,7 @@ var init_diarist_role = __esm({
20454
20403
  },
20455
20404
  { additionalProperties: true, description: "\u4E00\u6761\u5165\u5F55\u9009\u62E9" }
20456
20405
  ),
20457
- { description: "\u5165\u5F55\u9009\u62E9\uFF1B\u7A7A\u5217\u8868\u5408\u6CD5\u5B8C\u5C40" }
20406
+ { description: "\u5165\u5F55\u9009\u62E9\uFF1B\u7A7A\u5217\u8868\u5408\u6CD5\u5B8C\u5C40\uFF1Bescalate \u65F6\u53EF\u4E0D\u4EA4" }
20458
20407
  )
20459
20408
  })
20460
20409
  )
@@ -20462,8 +20411,8 @@ var init_diarist_role = __esm({
20462
20411
  DIARIST_TOOL_SPEC = {
20463
20412
  name: DIARIST_OUTPUT_TOOL_NAME,
20464
20413
  label: "\u8D77\u5C45\u90CE\u8F93\u51FA",
20465
- description: "\u8D77\u5C45\u90CE\u5165\u5F55\u9009\u62E9\u3002",
20466
- promptSnippet: "\u8D77\u5C45\u90CE\u5165\u5F55\u9009\u62E9",
20414
+ description: "\u8D77\u5C45\u90CE\u5165\u5F55\u9009\u62E9\u4E0E\u672C\u7968\u8EAB\u4EFD\u65AD\u8A00\uFF1B\u8BA4\u4E0D\u51FA\u672C\u5EAD\u5BF9\u8C61\u5219 escalate\u3002",
20415
+ promptSnippet: "\u8D77\u5C45\u90CE\u5165\u5F55\u9009\u62E9\u4E0E\u672C\u7968\u8EAB\u4EFD",
20467
20416
  parameters: diaristOutputSchema
20468
20417
  };
20469
20418
  }
@@ -20547,6 +20496,83 @@ var init_diarist_mechanical = __esm({
20547
20496
 
20548
20497
  // src/diarist.ts
20549
20498
  import { readFileSync as readFileSync4 } from "node:fs";
20499
+ import { execFileSync as execFileSync3 } from "node:child_process";
20500
+ function instructionContainsTicketNumber(instruction, ticketNumber) {
20501
+ if (!Number.isSafeInteger(ticketNumber) || ticketNumber < 1) return false;
20502
+ return new RegExp("(?<!\\d)" + String(ticketNumber) + "(?!\\d)").test(
20503
+ instruction
20504
+ );
20505
+ }
20506
+ function createGhTicketExistenceChecker(options) {
20507
+ const runner = options?.runner ?? createGhApiRunner();
20508
+ return async (input) => {
20509
+ const projected = await projectGhIssueBody(runner, {
20510
+ owner: input.owner,
20511
+ repo: input.repo,
20512
+ ticketNumber: input.ticketNumber,
20513
+ ...input.signal === void 0 ? {} : { signal: input.signal }
20514
+ });
20515
+ return projected.status === "available";
20516
+ };
20517
+ }
20518
+ async function verifyAssertedTicketNumber(input) {
20519
+ const n = input.ticketNumber;
20520
+ if (!Number.isSafeInteger(n) || n < 1) {
20521
+ throw new DiaristTicketVerificationError(
20522
+ "assertion-uninterpretable",
20523
+ `diarist ticket assertion must be a safe integer >= 1, got ${String(n)}`
20524
+ );
20525
+ }
20526
+ if (!instructionContainsTicketNumber(input.instruction, n)) {
20527
+ throw new DiaristTicketVerificationError(
20528
+ "number-not-in-instruction",
20529
+ `diarist ticket assertion #${n} complete decimal number does not appear in accepted instruction`
20530
+ );
20531
+ }
20532
+ const origin = resolveDiaristGithubOrigin(input.projectRoot);
20533
+ if (origin === void 0) {
20534
+ throw new DiaristTicketVerificationError(
20535
+ "origin-unresolved",
20536
+ `diarist ticket assertion #${n} requires a resolvable github.com origin remote for live verification`
20537
+ );
20538
+ }
20539
+ const checkExistence = input.checkExistence ?? createGhTicketExistenceChecker();
20540
+ let exists;
20541
+ try {
20542
+ exists = await checkExistence({
20543
+ owner: origin.owner,
20544
+ repo: origin.repo,
20545
+ ticketNumber: n,
20546
+ ...input.signal === void 0 ? {} : { signal: input.signal }
20547
+ });
20548
+ } catch (error) {
20549
+ throw new DiaristTicketVerificationError(
20550
+ "ticket-missing",
20551
+ `diarist ticket assertion #${n} live verification failed`,
20552
+ { cause: error }
20553
+ );
20554
+ }
20555
+ if (!exists) {
20556
+ throw new DiaristTicketVerificationError(
20557
+ "ticket-missing",
20558
+ `diarist ticket assertion #${n} does not exist as a live issue on ${origin.owner}/${origin.repo}`
20559
+ );
20560
+ }
20561
+ }
20562
+ function resolveDiaristGithubOrigin(projectRoot) {
20563
+ let remoteUrl;
20564
+ try {
20565
+ remoteUrl = execFileSync3("git", ["remote", "get-url", "origin"], {
20566
+ cwd: projectRoot,
20567
+ encoding: "utf8",
20568
+ stdio: ["ignore", "pipe", "pipe"]
20569
+ }).trim();
20570
+ } catch {
20571
+ return void 0;
20572
+ }
20573
+ if (remoteUrl.length === 0) return void 0;
20574
+ return parseGitHubOriginRemote(remoteUrl);
20575
+ }
20550
20576
  function blockEntryIdentity(ticketNumber, block) {
20551
20577
  return ticketProvenanceEntryIdentity({
20552
20578
  ticketNumber,
@@ -20561,8 +20587,20 @@ function loadDiaristSourceCatalog(path) {
20561
20587
  throw new Error(`diarist source catalog is not an object (${path})`);
20562
20588
  }
20563
20589
  const record4 = parsed;
20564
- if (typeof record4.ticketNumber !== "number" || typeof record4.cwd !== "string") {
20565
- throw new Error(`diarist source catalog is missing ticket coordinates (${path})`);
20590
+ if (typeof record4.cwd !== "string") {
20591
+ throw new Error(`diarist source catalog is missing cwd (${path})`);
20592
+ }
20593
+ if (typeof record4.instruction !== "string") {
20594
+ throw new Error(`diarist source catalog is missing instruction (${path})`);
20595
+ }
20596
+ if (typeof record4.runDirectory !== "string") {
20597
+ throw new Error(`diarist source catalog is missing runDirectory (${path})`);
20598
+ }
20599
+ if (typeof record4.projectRoot !== "string") {
20600
+ throw new Error(`diarist source catalog is missing projectRoot (${path})`);
20601
+ }
20602
+ if (record4.ticketNumber !== void 0 && (typeof record4.ticketNumber !== "number" || !Number.isSafeInteger(record4.ticketNumber) || record4.ticketNumber < 1)) {
20603
+ throw new Error(`diarist source catalog ticketNumber is not a safe ticket (${path})`);
20566
20604
  }
20567
20605
  if (!Array.isArray(record4.candidates)) {
20568
20606
  throw new Error(`diarist source catalog is missing candidates (${path})`);
@@ -20570,7 +20608,13 @@ function loadDiaristSourceCatalog(path) {
20570
20608
  return parsed;
20571
20609
  }
20572
20610
  async function commitDiaristSelections(input) {
20573
- const { ticketNumber, cwd } = input.catalog;
20611
+ const ticketNumber = input.catalog.ticketNumber;
20612
+ if (ticketNumber === void 0) {
20613
+ throw new Error(
20614
+ "commitDiaristSelections requires a bound ticketNumber on the catalog"
20615
+ );
20616
+ }
20617
+ const { cwd } = input.catalog;
20574
20618
  const homeOpt = input.catalog.home === void 0 ? {} : { home: input.catalog.home };
20575
20619
  const volumePaths = ensureTicketProvenanceVolume(ticketNumber, cwd, input.catalog.home);
20576
20620
  const anchors = buildDiaristAnchors({ ticketNumber });
@@ -20636,6 +20680,7 @@ async function commitDiaristSelections(input) {
20636
20680
  ]
20637
20681
  };
20638
20682
  }
20683
+ var DiaristTicketVerificationError;
20639
20684
  var init_diarist = __esm({
20640
20685
  "src/diarist.ts"() {
20641
20686
  "use strict";
@@ -20645,6 +20690,15 @@ var init_diarist = __esm({
20645
20690
  init_reviewer_pinned_git();
20646
20691
  init_ticket_provenance();
20647
20692
  init_sitian_facade();
20693
+ DiaristTicketVerificationError = class extends Error {
20694
+ code = "diarist-ticket-verification";
20695
+ reason;
20696
+ constructor(reason, message, options) {
20697
+ super(message, options);
20698
+ this.name = "DiaristTicketVerificationError";
20699
+ this.reason = reason;
20700
+ }
20701
+ };
20648
20702
  }
20649
20703
  });
20650
20704
 
@@ -20743,7 +20797,7 @@ function createJudgeRoleRuntime(pi, dependencies, hostActions) {
20743
20797
  }),
20744
20798
  bounce: (violations) => {
20745
20799
  throw new Error(
20746
- `\u5927\u7406\u5BFA\u56DE\u6267\u8FDD soul\uFF1A${violations.join("; ")}`
20800
+ `\u5927\u7406\u5BFA\u56DE\u6267\u8FDD soul\uFF1A${joinReadableGateItems(violations)}`
20747
20801
  );
20748
20802
  },
20749
20803
  escalate: (result) => result
@@ -20773,6 +20827,7 @@ var init_judge_role = __esm({
20773
20827
  "use strict";
20774
20828
  init_host_contracts();
20775
20829
  init_audit_escalation();
20830
+ init_readable_gate_item();
20776
20831
  init_terminating_infrastructure();
20777
20832
  init_judge_output();
20778
20833
  judgeVerdictSchema = withInfrastructureFailureDeclaration(
@@ -21182,11 +21237,11 @@ var init_reviewer_role = __esm({
21182
21237
  });
21183
21238
 
21184
21239
  // src/worker-submission-gates.ts
21185
- import { execFileSync as execFileSync3 } from "node:child_process";
21240
+ import { execFileSync as execFileSync4 } from "node:child_process";
21186
21241
  import { existsSync as existsSync12, lstatSync as lstatSync3, readdirSync as readdirSync2, readFileSync as readFileSync5, rmdirSync, rmSync } from "node:fs";
21187
21242
  import { resolve as resolve18 } from "node:path";
21188
21243
  function git2(cwd, args) {
21189
- return execFileSync3("git", args, {
21244
+ return execFileSync4("git", args, {
21190
21245
  cwd,
21191
21246
  encoding: "utf8",
21192
21247
  stdio: ["ignore", "pipe", "pipe"],
@@ -21194,7 +21249,7 @@ function git2(cwd, args) {
21194
21249
  }).trim();
21195
21250
  }
21196
21251
  function gitFile(file, args) {
21197
- return execFileSync3("git", ["config", "--file", file, ...args], {
21252
+ return execFileSync4("git", ["config", "--file", file, ...args], {
21198
21253
  encoding: "utf8",
21199
21254
  stdio: ["ignore", "pipe", "pipe"],
21200
21255
  env: { ...process.env, GIT_DIR: void 0, GIT_WORK_TREE: void 0, GIT_COMMON_DIR: void 0 }
@@ -22281,6 +22336,26 @@ function createAuditorRoleRuntime(roleHost, dependencies) {
22281
22336
  }
22282
22337
  };
22283
22338
  }
22339
+ function readDiaristTicketAssertion(submitted) {
22340
+ if (submitted === void 0 || !("ticketNumber" in submitted)) {
22341
+ return { kind: "true-unbound" };
22342
+ }
22343
+ const raw = submitted.ticketNumber;
22344
+ if (raw === null) return { kind: "true-unbound" };
22345
+ if (typeof raw === "number" && Number.isSafeInteger(raw) && raw >= 1) {
22346
+ return { kind: "ticket", ticketNumber: raw };
22347
+ }
22348
+ if (typeof raw === "string" && /^[1-9]\d*$/.test(raw)) {
22349
+ const n = Number(raw);
22350
+ if (Number.isSafeInteger(n) && n >= 1) {
22351
+ return { kind: "ticket", ticketNumber: n };
22352
+ }
22353
+ }
22354
+ throw new DiaristTicketVerificationError(
22355
+ "assertion-uninterpretable",
22356
+ "diarist ticketNumber must be a safe integer >= 1, null, or absent"
22357
+ );
22358
+ }
22284
22359
  function createDiaristRoleRuntime(roleHost, dependencies, getSourcesFlag) {
22285
22360
  let catalog;
22286
22361
  const runtime = createFiledOfficerRuntime(
@@ -22292,17 +22367,72 @@ function createDiaristRoleRuntime(roleHost, dependencies, getSourcesFlag) {
22292
22367
  soulTag: "diarist",
22293
22368
  beforeAccept: async ({ parameters }) => {
22294
22369
  const submitted = parameters !== null && typeof parameters === "object" && !Array.isArray(parameters) ? parameters : void 0;
22370
+ if (submitted?.status === "escalate") {
22371
+ if (!("sitian" in submitted) && !("ticketNumber" in submitted)) {
22372
+ return submitted;
22373
+ }
22374
+ const stripped = { ...submitted };
22375
+ delete stripped.sitian;
22376
+ delete stripped.ticketNumber;
22377
+ return stripped;
22378
+ }
22379
+ const assertion = readDiaristTicketAssertion(submitted);
22295
22380
  if (catalog === void 0) {
22381
+ if (assertion.kind === "ticket") {
22382
+ throw new DiaristTicketVerificationError(
22383
+ "assertion-uninterpretable",
22384
+ `diarist asserted ticket #${assertion.ticketNumber} but no source catalog was frozen for this turn`
22385
+ );
22386
+ }
22296
22387
  if (submitted === void 0 || !("sitian" in submitted)) return void 0;
22297
22388
  const stripped = { ...submitted };
22298
22389
  delete stripped.sitian;
22299
22390
  return stripped;
22300
22391
  }
22392
+ if (catalog.ticketNumber !== void 0) {
22393
+ const facts2 = await commitDiaristSelections({
22394
+ catalog,
22395
+ selections: projectDiaristSelections(parameters)
22396
+ });
22397
+ return {
22398
+ ...submitted ?? { receipt: parameters },
22399
+ ticketNumber: catalog.ticketNumber,
22400
+ sitian: facts2
22401
+ };
22402
+ }
22403
+ if (assertion.kind === "true-unbound") {
22404
+ if (submitted === void 0 || !("sitian" in submitted)) {
22405
+ return { ...submitted ?? { receipt: parameters }, ticketNumber: null };
22406
+ }
22407
+ const stripped = {
22408
+ ...submitted,
22409
+ ticketNumber: null
22410
+ };
22411
+ delete stripped.sitian;
22412
+ return stripped;
22413
+ }
22414
+ await verifyAssertedTicketNumber({
22415
+ ticketNumber: assertion.ticketNumber,
22416
+ instruction: catalog.instruction,
22417
+ projectRoot: catalog.projectRoot
22418
+ });
22419
+ await bindTicketNumberOnRunDirectory(
22420
+ catalog.runDirectory,
22421
+ assertion.ticketNumber
22422
+ );
22423
+ const boundCatalog = {
22424
+ ...catalog,
22425
+ ticketNumber: assertion.ticketNumber
22426
+ };
22301
22427
  const facts = await commitDiaristSelections({
22302
- catalog,
22428
+ catalog: boundCatalog,
22303
22429
  selections: projectDiaristSelections(parameters)
22304
22430
  });
22305
- return { ...submitted ?? { receipt: parameters }, sitian: facts };
22431
+ return {
22432
+ ...submitted ?? { receipt: parameters },
22433
+ ticketNumber: assertion.ticketNumber,
22434
+ sitian: facts
22435
+ };
22306
22436
  }
22307
22437
  },
22308
22438
  dependencies
@@ -23093,6 +23223,7 @@ var init_role_runtime = __esm({
23093
23223
  init_diarist_role();
23094
23224
  init_diarist_contracts();
23095
23225
  init_diarist();
23226
+ init_invocation();
23096
23227
  init_gatekeeper_role();
23097
23228
  init_navigator_role();
23098
23229
  init_auditor_role();