@akagilnc/pi-workflow-roles 0.1.3673 → 0.1.3682

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.
@@ -3242,7 +3242,7 @@ function validateRecordedDiaristOutput(value) {
3242
3242
  } catch {
3243
3243
  throw new Error("Diarist output has no execution discriminator");
3244
3244
  }
3245
- if (status === "completed") {
3245
+ if (status === "completed" || status === "escalate") {
3246
3246
  return value;
3247
3247
  }
3248
3248
  throw new Error("Diarist output has no execution discriminator");
@@ -3274,7 +3274,7 @@ var init_diarist_contracts = __esm({
3274
3274
  DIARIST_SOURCES_FLAG = {
3275
3275
  name: "ak-diarist-sources",
3276
3276
  definition: {
3277
- description: "Frozen per-ticket source catalog the diarist selects from",
3277
+ description: "Frozen source catalog the diarist selects from (may be unbound until LLM asserts ticketNumber)",
3278
3278
  type: "string"
3279
3279
  }
3280
3280
  };
@@ -3496,7 +3496,7 @@ function validateAcceptedDetails(toolName, details) {
3496
3496
  [GATEKEEPER_OUTPUT_TOOL_NAME]: ["dispatch", "pass"],
3497
3497
  [NAVIGATOR_OUTPUT_TOOL_NAME]: ["advice"],
3498
3498
  [AUDITOR_OUTPUT_TOOL_NAME]: ["pass", "bounce", "escalate"],
3499
- [DIARIST_OUTPUT_TOOL_NAME]: ["completed"]
3499
+ [DIARIST_OUTPUT_TOOL_NAME]: ["completed", "escalate"]
3500
3500
  };
3501
3501
  const collectorDiscriminator = toolName === COLLECTOR_OUTPUT_TOOL && Array.isArray(candidate?.groups);
3502
3502
  const baseDiscriminator = discriminator;
@@ -4643,27 +4643,6 @@ async function findLatestRunIdForSeatTicket(input) {
4643
4643
  }
4644
4644
  return best;
4645
4645
  }
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
4646
  function parsePersistedTicketIdentity(record4) {
4668
4647
  const correlationId = typeof record4.correlationId === "string" && record4.correlationId.trim() !== "" ? record4.correlationId : void 0;
4669
4648
  const ticketNumber = typeof record4.ticketNumber === "number" && Number.isSafeInteger(record4.ticketNumber) && record4.ticketNumber >= 1 ? record4.ticketNumber : void 0;
@@ -6158,6 +6137,7 @@ __export(invocation_exports, {
6158
6137
  admitNotaryInvocation: () => admitNotaryInvocation,
6159
6138
  admitReviewerInvocation: () => admitReviewerInvocation,
6160
6139
  bindAdmittedTicketNumber: () => bindAdmittedTicketNumber,
6140
+ bindTicketNumberOnRunDirectory: () => bindTicketNumberOnRunDirectory,
6161
6141
  buildCoderTransportPrompt: () => buildCoderTransportPrompt,
6162
6142
  buildCollectorTransportPrompt: () => buildCollectorTransportPrompt,
6163
6143
  buildCountersignTransportPrompt: () => buildCountersignTransportPrompt,
@@ -6206,6 +6186,7 @@ __export(invocation_exports, {
6206
6186
  resolveGitHubRemoteRepository: () => resolveGitHubRemoteRepository
6207
6187
  });
6208
6188
  import { execFileSync as execFileSync2 } from "node:child_process";
6189
+ import { existsSync as existsSync4 } from "node:fs";
6209
6190
  import {
6210
6191
  lstat as lstat3,
6211
6192
  mkdir,
@@ -6352,6 +6333,40 @@ async function bindAdmittedTicketNumber(admitted, ticketNumber) {
6352
6333
  "utf8"
6353
6334
  );
6354
6335
  }
6336
+ async function bindTicketNumberOnRunDirectory(runDirectory, ticketNumber) {
6337
+ if (!Number.isSafeInteger(ticketNumber) || ticketNumber < 1) {
6338
+ throw new Error(
6339
+ `bindTicketNumberOnRunDirectory requires a safe positive integer, got ${String(ticketNumber)}`
6340
+ );
6341
+ }
6342
+ const admittedPath = join13(runDirectory, "admitted-request.json");
6343
+ const invocationPath = join13(runDirectory, "invocation.json");
6344
+ const admitted = JSON.parse(await readFile9(admittedPath, "utf8"));
6345
+ const existing = admitted.ticketNumber;
6346
+ if (typeof existing === "number") {
6347
+ if (existing === ticketNumber) return;
6348
+ throw new Error(
6349
+ `bindTicketNumberOnRunDirectory refuses to replace existing ticket #${existing} with #${ticketNumber}`
6350
+ );
6351
+ }
6352
+ if (existsSync4(invocationPath)) {
6353
+ const invocation = JSON.parse(
6354
+ await readFile9(invocationPath, "utf8")
6355
+ );
6356
+ if (typeof invocation.ticketNumber === "number" && invocation.ticketNumber !== ticketNumber) {
6357
+ throw new Error(
6358
+ `bindTicketNumberOnRunDirectory refuses to replace invocation ticket #${invocation.ticketNumber} with #${ticketNumber}`
6359
+ );
6360
+ }
6361
+ }
6362
+ await writeFile4(
6363
+ admittedPath,
6364
+ `${JSON.stringify({ ...admitted, ticketNumber }, null, 2)}
6365
+ `,
6366
+ "utf8"
6367
+ );
6368
+ await mergeInvocationIdentityPage(runDirectory, { ticketNumber });
6369
+ }
6355
6370
  async function recordLaunchedPiIdentity(runDirectory, identity) {
6356
6371
  await mergeInvocationIdentityPage(runDirectory, {
6357
6372
  piExecutable: identity.executable,
@@ -8388,7 +8403,7 @@ var load_production_acp_host_exports = {};
8388
8403
  __export(load_production_acp_host_exports, {
8389
8404
  loadProductionAcpHostFactory: () => loadProductionAcpHostFactory
8390
8405
  });
8391
- import { existsSync as existsSync4 } from "node:fs";
8406
+ import { existsSync as existsSync5 } from "node:fs";
8392
8407
  import { join as join14 } from "node:path";
8393
8408
  import { pathToFileURL } from "node:url";
8394
8409
  async function loadProductionAcpHostFactory(packageRoot, host) {
@@ -8398,7 +8413,7 @@ async function loadProductionAcpHostFactory(packageRoot, host) {
8398
8413
  }
8399
8414
  const built = join14(packageRoot, "dist/acp-host/production-host.js");
8400
8415
  const source = join14(packageRoot, "src/acp-host/production-host.ts");
8401
- const target = existsSync4(built) ? built : source;
8416
+ const target = existsSync5(built) ? built : source;
8402
8417
  const href = pathToFileURL(target).href;
8403
8418
  const mod = await import(href);
8404
8419
  const create = mod.createProductionAcpRoleTurnHost;
@@ -9263,6 +9278,30 @@ var init_config = __esm({
9263
9278
  }
9264
9279
  });
9265
9280
 
9281
+ // src/public-cli/seat-ticket-binding.ts
9282
+ async function tryResumeSameTicketSeatRun(input) {
9283
+ if (input.freshSummons === true) return void 0;
9284
+ if (input.parentRunPath === void 0 && input.ticketNumber === void 0) {
9285
+ return void 0;
9286
+ }
9287
+ const previousRunId = await findLatestRunIdForSeatTicket({
9288
+ home: input.home,
9289
+ bookKey: resolveBookKeyFromGit(input.projectRoot),
9290
+ role: input.role,
9291
+ ...input.parentRunPath === void 0 ? {} : { parentRunPath: input.parentRunPath },
9292
+ ...input.ticketNumber === void 0 ? {} : { ticketNumber: input.ticketNumber }
9293
+ });
9294
+ if (previousRunId === void 0) return void 0;
9295
+ return await input.resume(previousRunId, input.summons);
9296
+ }
9297
+ var init_seat_ticket_binding = __esm({
9298
+ "src/public-cli/seat-ticket-binding.ts"() {
9299
+ "use strict";
9300
+ init_activation_ledger_git();
9301
+ init_run_lifecycle();
9302
+ }
9303
+ });
9304
+
9266
9305
  // src/ticket-provenance-contracts.ts
9267
9306
  function isRecord11(value) {
9268
9307
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -9356,7 +9395,7 @@ var init_ticket_provenance_contracts = __esm({
9356
9395
 
9357
9396
  // src/ticket-provenance.ts
9358
9397
  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";
9398
+ import { appendFileSync as appendFileSync2, existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "node:fs";
9360
9399
  import { join as join16 } from "node:path";
9361
9400
  function ticketProvenanceSubject(ticketNumber) {
9362
9401
  if (!Number.isSafeInteger(ticketNumber) || ticketNumber < 1) {
@@ -9421,7 +9460,7 @@ function resolveTicketProvenanceVolume(ticketNumber, cwd, home) {
9421
9460
  }
9422
9461
  function readOfferedIdentities(ticketNumber, cwd, home) {
9423
9462
  const { offeredWatermarkFile } = resolveTicketProvenanceVolume(ticketNumber, cwd, home);
9424
- if (!existsSync5(offeredWatermarkFile)) return /* @__PURE__ */ new Set();
9463
+ if (!existsSync6(offeredWatermarkFile)) return /* @__PURE__ */ new Set();
9425
9464
  let text;
9426
9465
  try {
9427
9466
  text = readFileSync2(offeredWatermarkFile, "utf8");
@@ -9632,84 +9671,6 @@ var init_ticket_provenance = __esm({
9632
9671
  }
9633
9672
  });
9634
9673
 
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
9674
  // src/public-cli/case-dossier-delivery.ts
9714
9675
  import { stat as stat2 } from "node:fs/promises";
9715
9676
  async function describeDossierFile(path) {
@@ -16482,11 +16443,6 @@ async function runPublicInspector(argv, env, io, parseInspectorArgv2) {
16482
16443
  throw error;
16483
16444
  }
16484
16445
  const projectRoot = parsed.project ?? env.cwd;
16485
- const reusedTicketNumber = await resolveKnownTicketNumber({
16486
- instruction: parsed.instruction,
16487
- projectRoot,
16488
- home: env.home
16489
- });
16490
16446
  const parentRunPath = parentRunPathFromGatePointerInstruction(parsed.instruction);
16491
16447
  if (parentRunPath !== void 0) {
16492
16448
  const summons = {
@@ -16552,11 +16508,7 @@ async function runPublicInspector(argv, env, io, parseInspectorArgv2) {
16552
16508
  env,
16553
16509
  io,
16554
16510
  request: turnRequest,
16555
- adapters: inspectorAdapters({
16556
- beforeDispatch: async (admittedSeat) => {
16557
- await bindReusedTicketNumber(admittedSeat, reusedTicketNumber);
16558
- }
16559
- }),
16511
+ adapters: inspectorAdapters(),
16560
16512
  ...env.engine === void 0 ? {} : { effectiveEngine: env.engine }
16561
16513
  });
16562
16514
  }
@@ -16737,7 +16689,6 @@ async function runPublicInstructionSeat(argv, env, io, role, parseArgv) {
16737
16689
  let auditorSubject;
16738
16690
  let auditorSourceRun;
16739
16691
  let auditorSourceTicket;
16740
- let reusedTicketNumber;
16741
16692
  const projectRoot = parsed.project ?? env.cwd;
16742
16693
  if (role === "auditor") {
16743
16694
  if (parsed.subject !== "judge" && parsed.subject !== "doctor") {
@@ -16772,12 +16723,6 @@ async function runPublicInstructionSeat(argv, env, io, role, parseArgv) {
16772
16723
  );
16773
16724
  return { exitCode: 2 };
16774
16725
  }
16775
- } else {
16776
- reusedTicketNumber = await resolveKnownTicketNumber({
16777
- instruction: parsed.instruction,
16778
- projectRoot,
16779
- home: env.home
16780
- });
16781
16726
  }
16782
16727
  const summons = {
16783
16728
  instruction: parsed.instruction,
@@ -16803,21 +16748,6 @@ async function runPublicInstructionSeat(argv, env, io, role, parseArgv) {
16803
16748
  })
16804
16749
  });
16805
16750
  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
16751
  }
16822
16752
  let admitted;
16823
16753
  try {
@@ -16875,8 +16805,6 @@ async function runPublicInstructionSeat(argv, env, io, role, parseArgv) {
16875
16805
  beforeDispatch: async (admittedSeat) => {
16876
16806
  if (auditorSourceTicket !== void 0) {
16877
16807
  await bindAdmittedTicketNumber(admittedSeat, auditorSourceTicket);
16878
- } else {
16879
- await bindReusedTicketNumber(admittedSeat, reusedTicketNumber);
16880
16808
  }
16881
16809
  }
16882
16810
  }),
@@ -16984,12 +16912,7 @@ async function runPublicJudge(argv, env, io, parseJudgeArgv2) {
16984
16912
  })
16985
16913
  }
16986
16914
  }),
16987
- adapters: {
16988
- ...judgeAdapters(),
16989
- beforeDispatch: async (admittedSeat) => {
16990
- await resolveSeatTicketBinding(admittedSeat, env);
16991
- }
16992
- },
16915
+ adapters: judgeAdapters(),
16993
16916
  ...env.engine === void 0 ? {} : { effectiveEngine: env.engine }
16994
16917
  });
16995
16918
  }
@@ -17013,7 +16936,6 @@ var init_judge_run = __esm({
17013
16936
  init_engine_material();
17014
16937
  init_cli_errors();
17015
16938
  init_invocation();
17016
- init_seat_ticket_binding();
17017
16939
  init_run_lifecycle();
17018
16940
  init_settlement();
17019
16941
  init_turn_request();
@@ -20439,8 +20361,18 @@ var init_diarist_role = __esm({
20439
20361
  openToolObject(
20440
20362
  Type23.Object({
20441
20363
  status: Type23.Unknown({
20442
- description: "completed \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8"
20364
+ description: "completed | escalate \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8"
20443
20365
  }),
20366
+ ticketNumber: Type23.Optional(
20367
+ Type23.Unknown({
20368
+ 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"
20369
+ })
20370
+ ),
20371
+ reason: Type23.Optional(
20372
+ Type23.String({
20373
+ description: "status \u4E3A escalate \u65F6\uFF1A\u8BA4\u4E0D\u51FA\u672C\u5EAD\u5BF9\u8C61\u7684\u539F\u56E0"
20374
+ })
20375
+ ),
20444
20376
  selections: Type23.Array(
20445
20377
  Type23.Object(
20446
20378
  {
@@ -20454,7 +20386,7 @@ var init_diarist_role = __esm({
20454
20386
  },
20455
20387
  { additionalProperties: true, description: "\u4E00\u6761\u5165\u5F55\u9009\u62E9" }
20456
20388
  ),
20457
- { description: "\u5165\u5F55\u9009\u62E9\uFF1B\u7A7A\u5217\u8868\u5408\u6CD5\u5B8C\u5C40" }
20389
+ { description: "\u5165\u5F55\u9009\u62E9\uFF1B\u7A7A\u5217\u8868\u5408\u6CD5\u5B8C\u5C40\uFF1Bescalate \u65F6\u53EF\u4E0D\u4EA4" }
20458
20390
  )
20459
20391
  })
20460
20392
  )
@@ -20462,8 +20394,8 @@ var init_diarist_role = __esm({
20462
20394
  DIARIST_TOOL_SPEC = {
20463
20395
  name: DIARIST_OUTPUT_TOOL_NAME,
20464
20396
  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",
20397
+ 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",
20398
+ promptSnippet: "\u8D77\u5C45\u90CE\u5165\u5F55\u9009\u62E9\u4E0E\u672C\u7968\u8EAB\u4EFD",
20467
20399
  parameters: diaristOutputSchema
20468
20400
  };
20469
20401
  }
@@ -20547,6 +20479,83 @@ var init_diarist_mechanical = __esm({
20547
20479
 
20548
20480
  // src/diarist.ts
20549
20481
  import { readFileSync as readFileSync4 } from "node:fs";
20482
+ import { execFileSync as execFileSync3 } from "node:child_process";
20483
+ function instructionContainsTicketNumber(instruction, ticketNumber) {
20484
+ if (!Number.isSafeInteger(ticketNumber) || ticketNumber < 1) return false;
20485
+ return new RegExp("(?<!\\d)" + String(ticketNumber) + "(?!\\d)").test(
20486
+ instruction
20487
+ );
20488
+ }
20489
+ function createGhTicketExistenceChecker(options) {
20490
+ const runner = options?.runner ?? createGhApiRunner();
20491
+ return async (input) => {
20492
+ const projected = await projectGhIssueBody(runner, {
20493
+ owner: input.owner,
20494
+ repo: input.repo,
20495
+ ticketNumber: input.ticketNumber,
20496
+ ...input.signal === void 0 ? {} : { signal: input.signal }
20497
+ });
20498
+ return projected.status === "available";
20499
+ };
20500
+ }
20501
+ async function verifyAssertedTicketNumber(input) {
20502
+ const n = input.ticketNumber;
20503
+ if (!Number.isSafeInteger(n) || n < 1) {
20504
+ throw new DiaristTicketVerificationError(
20505
+ "assertion-uninterpretable",
20506
+ `diarist ticket assertion must be a safe integer >= 1, got ${String(n)}`
20507
+ );
20508
+ }
20509
+ if (!instructionContainsTicketNumber(input.instruction, n)) {
20510
+ throw new DiaristTicketVerificationError(
20511
+ "number-not-in-instruction",
20512
+ `diarist ticket assertion #${n} complete decimal number does not appear in accepted instruction`
20513
+ );
20514
+ }
20515
+ const origin = resolveDiaristGithubOrigin(input.projectRoot);
20516
+ if (origin === void 0) {
20517
+ throw new DiaristTicketVerificationError(
20518
+ "origin-unresolved",
20519
+ `diarist ticket assertion #${n} requires a resolvable github.com origin remote for live verification`
20520
+ );
20521
+ }
20522
+ const checkExistence = input.checkExistence ?? createGhTicketExistenceChecker();
20523
+ let exists;
20524
+ try {
20525
+ exists = await checkExistence({
20526
+ owner: origin.owner,
20527
+ repo: origin.repo,
20528
+ ticketNumber: n,
20529
+ ...input.signal === void 0 ? {} : { signal: input.signal }
20530
+ });
20531
+ } catch (error) {
20532
+ throw new DiaristTicketVerificationError(
20533
+ "ticket-missing",
20534
+ `diarist ticket assertion #${n} live verification failed`,
20535
+ { cause: error }
20536
+ );
20537
+ }
20538
+ if (!exists) {
20539
+ throw new DiaristTicketVerificationError(
20540
+ "ticket-missing",
20541
+ `diarist ticket assertion #${n} does not exist as a live issue on ${origin.owner}/${origin.repo}`
20542
+ );
20543
+ }
20544
+ }
20545
+ function resolveDiaristGithubOrigin(projectRoot) {
20546
+ let remoteUrl;
20547
+ try {
20548
+ remoteUrl = execFileSync3("git", ["remote", "get-url", "origin"], {
20549
+ cwd: projectRoot,
20550
+ encoding: "utf8",
20551
+ stdio: ["ignore", "pipe", "pipe"]
20552
+ }).trim();
20553
+ } catch {
20554
+ return void 0;
20555
+ }
20556
+ if (remoteUrl.length === 0) return void 0;
20557
+ return parseGitHubOriginRemote(remoteUrl);
20558
+ }
20550
20559
  function blockEntryIdentity(ticketNumber, block) {
20551
20560
  return ticketProvenanceEntryIdentity({
20552
20561
  ticketNumber,
@@ -20561,8 +20570,20 @@ function loadDiaristSourceCatalog(path) {
20561
20570
  throw new Error(`diarist source catalog is not an object (${path})`);
20562
20571
  }
20563
20572
  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})`);
20573
+ if (typeof record4.cwd !== "string") {
20574
+ throw new Error(`diarist source catalog is missing cwd (${path})`);
20575
+ }
20576
+ if (typeof record4.instruction !== "string") {
20577
+ throw new Error(`diarist source catalog is missing instruction (${path})`);
20578
+ }
20579
+ if (typeof record4.runDirectory !== "string") {
20580
+ throw new Error(`diarist source catalog is missing runDirectory (${path})`);
20581
+ }
20582
+ if (typeof record4.projectRoot !== "string") {
20583
+ throw new Error(`diarist source catalog is missing projectRoot (${path})`);
20584
+ }
20585
+ if (record4.ticketNumber !== void 0 && (typeof record4.ticketNumber !== "number" || !Number.isSafeInteger(record4.ticketNumber) || record4.ticketNumber < 1)) {
20586
+ throw new Error(`diarist source catalog ticketNumber is not a safe ticket (${path})`);
20566
20587
  }
20567
20588
  if (!Array.isArray(record4.candidates)) {
20568
20589
  throw new Error(`diarist source catalog is missing candidates (${path})`);
@@ -20570,7 +20591,13 @@ function loadDiaristSourceCatalog(path) {
20570
20591
  return parsed;
20571
20592
  }
20572
20593
  async function commitDiaristSelections(input) {
20573
- const { ticketNumber, cwd } = input.catalog;
20594
+ const ticketNumber = input.catalog.ticketNumber;
20595
+ if (ticketNumber === void 0) {
20596
+ throw new Error(
20597
+ "commitDiaristSelections requires a bound ticketNumber on the catalog"
20598
+ );
20599
+ }
20600
+ const { cwd } = input.catalog;
20574
20601
  const homeOpt = input.catalog.home === void 0 ? {} : { home: input.catalog.home };
20575
20602
  const volumePaths = ensureTicketProvenanceVolume(ticketNumber, cwd, input.catalog.home);
20576
20603
  const anchors = buildDiaristAnchors({ ticketNumber });
@@ -20636,6 +20663,7 @@ async function commitDiaristSelections(input) {
20636
20663
  ]
20637
20664
  };
20638
20665
  }
20666
+ var DiaristTicketVerificationError;
20639
20667
  var init_diarist = __esm({
20640
20668
  "src/diarist.ts"() {
20641
20669
  "use strict";
@@ -20645,6 +20673,15 @@ var init_diarist = __esm({
20645
20673
  init_reviewer_pinned_git();
20646
20674
  init_ticket_provenance();
20647
20675
  init_sitian_facade();
20676
+ DiaristTicketVerificationError = class extends Error {
20677
+ code = "diarist-ticket-verification";
20678
+ reason;
20679
+ constructor(reason, message, options) {
20680
+ super(message, options);
20681
+ this.name = "DiaristTicketVerificationError";
20682
+ this.reason = reason;
20683
+ }
20684
+ };
20648
20685
  }
20649
20686
  });
20650
20687
 
@@ -21182,11 +21219,11 @@ var init_reviewer_role = __esm({
21182
21219
  });
21183
21220
 
21184
21221
  // src/worker-submission-gates.ts
21185
- import { execFileSync as execFileSync3 } from "node:child_process";
21222
+ import { execFileSync as execFileSync4 } from "node:child_process";
21186
21223
  import { existsSync as existsSync12, lstatSync as lstatSync3, readdirSync as readdirSync2, readFileSync as readFileSync5, rmdirSync, rmSync } from "node:fs";
21187
21224
  import { resolve as resolve18 } from "node:path";
21188
21225
  function git2(cwd, args) {
21189
- return execFileSync3("git", args, {
21226
+ return execFileSync4("git", args, {
21190
21227
  cwd,
21191
21228
  encoding: "utf8",
21192
21229
  stdio: ["ignore", "pipe", "pipe"],
@@ -21194,7 +21231,7 @@ function git2(cwd, args) {
21194
21231
  }).trim();
21195
21232
  }
21196
21233
  function gitFile(file, args) {
21197
- return execFileSync3("git", ["config", "--file", file, ...args], {
21234
+ return execFileSync4("git", ["config", "--file", file, ...args], {
21198
21235
  encoding: "utf8",
21199
21236
  stdio: ["ignore", "pipe", "pipe"],
21200
21237
  env: { ...process.env, GIT_DIR: void 0, GIT_WORK_TREE: void 0, GIT_COMMON_DIR: void 0 }
@@ -22281,6 +22318,26 @@ function createAuditorRoleRuntime(roleHost, dependencies) {
22281
22318
  }
22282
22319
  };
22283
22320
  }
22321
+ function readDiaristTicketAssertion(submitted) {
22322
+ if (submitted === void 0 || !("ticketNumber" in submitted)) {
22323
+ return { kind: "true-unbound" };
22324
+ }
22325
+ const raw = submitted.ticketNumber;
22326
+ if (raw === null) return { kind: "true-unbound" };
22327
+ if (typeof raw === "number" && Number.isSafeInteger(raw) && raw >= 1) {
22328
+ return { kind: "ticket", ticketNumber: raw };
22329
+ }
22330
+ if (typeof raw === "string" && /^[1-9]\d*$/.test(raw)) {
22331
+ const n = Number(raw);
22332
+ if (Number.isSafeInteger(n) && n >= 1) {
22333
+ return { kind: "ticket", ticketNumber: n };
22334
+ }
22335
+ }
22336
+ throw new DiaristTicketVerificationError(
22337
+ "assertion-uninterpretable",
22338
+ "diarist ticketNumber must be a safe integer >= 1, null, or absent"
22339
+ );
22340
+ }
22284
22341
  function createDiaristRoleRuntime(roleHost, dependencies, getSourcesFlag) {
22285
22342
  let catalog;
22286
22343
  const runtime = createFiledOfficerRuntime(
@@ -22292,17 +22349,72 @@ function createDiaristRoleRuntime(roleHost, dependencies, getSourcesFlag) {
22292
22349
  soulTag: "diarist",
22293
22350
  beforeAccept: async ({ parameters }) => {
22294
22351
  const submitted = parameters !== null && typeof parameters === "object" && !Array.isArray(parameters) ? parameters : void 0;
22352
+ if (submitted?.status === "escalate") {
22353
+ if (!("sitian" in submitted) && !("ticketNumber" in submitted)) {
22354
+ return submitted;
22355
+ }
22356
+ const stripped = { ...submitted };
22357
+ delete stripped.sitian;
22358
+ delete stripped.ticketNumber;
22359
+ return stripped;
22360
+ }
22361
+ const assertion = readDiaristTicketAssertion(submitted);
22295
22362
  if (catalog === void 0) {
22363
+ if (assertion.kind === "ticket") {
22364
+ throw new DiaristTicketVerificationError(
22365
+ "assertion-uninterpretable",
22366
+ `diarist asserted ticket #${assertion.ticketNumber} but no source catalog was frozen for this turn`
22367
+ );
22368
+ }
22296
22369
  if (submitted === void 0 || !("sitian" in submitted)) return void 0;
22297
22370
  const stripped = { ...submitted };
22298
22371
  delete stripped.sitian;
22299
22372
  return stripped;
22300
22373
  }
22374
+ if (catalog.ticketNumber !== void 0) {
22375
+ const facts2 = await commitDiaristSelections({
22376
+ catalog,
22377
+ selections: projectDiaristSelections(parameters)
22378
+ });
22379
+ return {
22380
+ ...submitted ?? { receipt: parameters },
22381
+ ticketNumber: catalog.ticketNumber,
22382
+ sitian: facts2
22383
+ };
22384
+ }
22385
+ if (assertion.kind === "true-unbound") {
22386
+ if (submitted === void 0 || !("sitian" in submitted)) {
22387
+ return { ...submitted ?? { receipt: parameters }, ticketNumber: null };
22388
+ }
22389
+ const stripped = {
22390
+ ...submitted,
22391
+ ticketNumber: null
22392
+ };
22393
+ delete stripped.sitian;
22394
+ return stripped;
22395
+ }
22396
+ await verifyAssertedTicketNumber({
22397
+ ticketNumber: assertion.ticketNumber,
22398
+ instruction: catalog.instruction,
22399
+ projectRoot: catalog.projectRoot
22400
+ });
22401
+ await bindTicketNumberOnRunDirectory(
22402
+ catalog.runDirectory,
22403
+ assertion.ticketNumber
22404
+ );
22405
+ const boundCatalog = {
22406
+ ...catalog,
22407
+ ticketNumber: assertion.ticketNumber
22408
+ };
22301
22409
  const facts = await commitDiaristSelections({
22302
- catalog,
22410
+ catalog: boundCatalog,
22303
22411
  selections: projectDiaristSelections(parameters)
22304
22412
  });
22305
- return { ...submitted ?? { receipt: parameters }, sitian: facts };
22413
+ return {
22414
+ ...submitted ?? { receipt: parameters },
22415
+ ticketNumber: assertion.ticketNumber,
22416
+ sitian: facts
22417
+ };
22306
22418
  }
22307
22419
  },
22308
22420
  dependencies
@@ -23093,6 +23205,7 @@ var init_role_runtime = __esm({
23093
23205
  init_diarist_role();
23094
23206
  init_diarist_contracts();
23095
23207
  init_diarist();
23208
+ init_invocation();
23096
23209
  init_gatekeeper_role();
23097
23210
  init_navigator_role();
23098
23211
  init_auditor_role();