@akagilnc/pi-workflow-roles 0.1.3558 → 0.1.3572

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 (49) hide show
  1. package/README.md +4 -1
  2. package/README.zh-CN.md +1 -1
  3. package/dist/acp-host/description.js +21 -0
  4. package/dist/{grok → acp-host}/mcp-relay.mjs +5 -5
  5. package/dist/{grok → acp-host}/production-host.js +860 -162
  6. package/dist/diarist-contracts.js +72 -0
  7. package/dist/host-descriptions.js +34 -0
  8. package/dist/package-contracts/terminating-tools.js +20 -2
  9. package/dist/packaged-role-registry.js +20 -0
  10. package/dist/public-cli/config.js +23 -10
  11. package/dist/public-cli/main.js +622 -671
  12. package/dist/public-cli/registry.js +4 -1
  13. package/extensions/role-runtime.ts +1 -0
  14. package/package.json +1 -1
  15. package/resources/diarist-collect.md +6 -10
  16. package/scripts/build-package.mjs +8 -8
  17. package/souls/diarist.md +9 -0
  18. package/src/acp-host/description.ts +43 -0
  19. package/src/{grok → acp-host}/mcp-relay.mjs +5 -5
  20. package/src/{grok → acp-host}/production-host.ts +31 -37
  21. package/src/{grok → acp-host}/role-envelope.ts +25 -24
  22. package/src/{grok → acp-host}/role-turn-host.ts +46 -81
  23. package/src/{grok → acp-host}/session-identity.ts +7 -7
  24. package/src/diarist-contracts.ts +88 -0
  25. package/src/diarist-role.ts +60 -0
  26. package/src/diarist.ts +253 -179
  27. package/src/host-contracts.ts +11 -4
  28. package/src/host-descriptions.ts +51 -0
  29. package/src/host-transition-prior-native.ts +12 -24
  30. package/src/package-contracts/terminating-tools.ts +22 -2
  31. package/src/packaged-role-registry.ts +20 -0
  32. package/src/pi/role-turn-host.ts +10 -1
  33. package/src/public-cli/cli.ts +39 -9
  34. package/src/public-cli/config.ts +24 -11
  35. package/src/public-cli/countersign-run.ts +9 -129
  36. package/src/public-cli/diarist-run.ts +312 -0
  37. package/src/public-cli/invocation.ts +23 -2
  38. package/src/public-cli/load-production-acp-host.ts +52 -0
  39. package/src/public-cli/option-definitions.ts +18 -0
  40. package/src/public-cli/post-admission.ts +3 -3
  41. package/src/public-cli/registry.ts +3 -0
  42. package/src/public-cli/run-lifecycle.ts +31 -3
  43. package/src/public-cli/settlement.ts +50 -2
  44. package/src/public-cli/terminal.ts +2 -1
  45. package/src/role-runtime.ts +117 -6
  46. package/src/ticket-provenance-contracts.ts +1 -0
  47. package/src/ticket-provenance.ts +0 -23
  48. package/src/diarist-llm-collector.ts +0 -324
  49. package/src/public-cli/load-production-grok-host.ts +0 -35
@@ -15023,6 +15023,45 @@ var init_inspector_contracts = __esm({
15023
15023
  }
15024
15024
  });
15025
15025
 
15026
+ // src/diarist-contracts.ts
15027
+ function validateRecordedDiaristOutput(value) {
15028
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
15029
+ throw new Error("Diarist output has no execution discriminator");
15030
+ }
15031
+ let status;
15032
+ try {
15033
+ status = value.status;
15034
+ } catch {
15035
+ throw new Error("Diarist output has no execution discriminator");
15036
+ }
15037
+ if (status === "completed") {
15038
+ return value;
15039
+ }
15040
+ throw new Error("Diarist output has no execution discriminator");
15041
+ }
15042
+ function diaristDecisiveFacts(output) {
15043
+ const facts = { status: output.status };
15044
+ const selections = output.selections;
15045
+ if (Array.isArray(selections)) facts.selections = selections;
15046
+ const sitian = output.sitian;
15047
+ if (sitian !== void 0) facts.sitian = sitian;
15048
+ return facts;
15049
+ }
15050
+ var DIARIST_OUTPUT_TOOL_NAME, DIARIST_SOURCES_FLAG;
15051
+ var init_diarist_contracts = __esm({
15052
+ "src/diarist-contracts.ts"() {
15053
+ "use strict";
15054
+ DIARIST_OUTPUT_TOOL_NAME = "ak_diarist_output";
15055
+ DIARIST_SOURCES_FLAG = {
15056
+ name: "ak-diarist-sources",
15057
+ definition: {
15058
+ description: "Frozen per-ticket source catalog the diarist selects from",
15059
+ type: "string"
15060
+ }
15061
+ };
15062
+ }
15063
+ });
15064
+
15026
15065
  // src/packaged-role-registry.ts
15027
15066
  function packagedRoleMetadata(role) {
15028
15067
  return PACKAGED_ROLE_REGISTRY.find((entry) => entry.role === role);
@@ -15043,6 +15082,7 @@ var init_packaged_role_registry = __esm({
15043
15082
  init_countersign_contracts();
15044
15083
  init_gleaner_left_contracts();
15045
15084
  init_inspector_contracts();
15085
+ init_diarist_contracts();
15046
15086
  NOTARY_SESSION_MATERIALS = [
15047
15087
  "CLAUDE.md",
15048
15088
  "souls/notary.md",
@@ -15208,6 +15248,22 @@ var init_packaged_role_registry = __esm({
15208
15248
  phaseFlag: void 0,
15209
15249
  activationStage: "load-and-install",
15210
15250
  sessionMaterials: ["CLAUDE.md", "souls/navigator.md"]
15251
+ },
15252
+ // #708 / ADR 0075 `diarist-is-role`: 起居郎 is a seat like any other. The
15253
+ // frozen source catalog rides the shared input-flag seam; it is absent for a
15254
+ // true-unbound summons (no ticket → no diary).
15255
+ {
15256
+ role: "diarist",
15257
+ phases: [null],
15258
+ outputTool: DIARIST_OUTPUT_TOOL_NAME,
15259
+ inputFlag: DIARIST_SOURCES_FLAG.name,
15260
+ phaseFlag: void 0,
15261
+ activationStage: "load-and-install",
15262
+ sessionMaterials: [
15263
+ "CLAUDE.md",
15264
+ "souls/diarist.md",
15265
+ "resources/diarist-collect.md"
15266
+ ]
15211
15267
  }
15212
15268
  ];
15213
15269
  PACKAGED_ROLE_REGISTRY = PUBLIC_ROLE_RECORDS.map(({ sessionMaterials: _omit, ...metadata }) => metadata);
@@ -15319,7 +15375,10 @@ var init_registry2 = __esm({
15319
15375
  navigator: [
15320
15376
  { provider: "openai-codex", model: "gpt-5.6-luna", thinking: "medium" },
15321
15377
  { provider: "xai", model: "grok-4.5", thinking: "high" }
15322
- ]
15378
+ ],
15379
+ // #708 `diarist-seat-default`: owner-set initial value; changed in the seat
15380
+ // table like any other seat. No engine axis, package-default host.
15381
+ diarist: [{ provider: "xai", model: "grok-4.5", thinking: "medium" }]
15323
15382
  };
15324
15383
  PUBLIC_DETERMINISTIC_COMMANDS = ["analyst"];
15325
15384
  }
@@ -15385,6 +15444,48 @@ var init_institutional_resolution = __esm({
15385
15444
  }
15386
15445
  });
15387
15446
 
15447
+ // src/host-descriptions.ts
15448
+ function lookupHostDescription(host) {
15449
+ return Object.hasOwn(HOST_DESCRIPTIONS, host) ? HOST_DESCRIPTIONS[host] : void 0;
15450
+ }
15451
+ function packagedExternalHostNames() {
15452
+ return Object.keys(HOST_DESCRIPTIONS);
15453
+ }
15454
+ function assertRegisteredHostName(host) {
15455
+ if (host === DEFAULT_ROLE_TURN_HOST || lookupHostDescription(host) !== void 0) {
15456
+ return host;
15457
+ }
15458
+ throw new Error(`unregistered host: ${host}`);
15459
+ }
15460
+ var PRIVATE_COMPAT_ENV, DEFAULT_ROLE_TURN_HOST, HOST_DESCRIPTIONS;
15461
+ var init_host_descriptions = __esm({
15462
+ "src/host-descriptions.ts"() {
15463
+ "use strict";
15464
+ PRIVATE_COMPAT_ENV = Object.fromEntries(
15465
+ ["CLAUDE", "CURSOR", "CODEX"].flatMap((vendor) => ["SKILLS", "RULES", "AGENTS", "MCPS", "HOOKS", "SESSIONS"].map((kind) => [`GROK_${vendor}_${kind}_ENABLED`, "false"]))
15466
+ );
15467
+ DEFAULT_ROLE_TURN_HOST = "pi";
15468
+ HOST_DESCRIPTIONS = Object.freeze({
15469
+ /** Operator home `~/.grok`, native session/load resume, `agent [--model X] stdio`. */
15470
+ "grok-build": Object.freeze({
15471
+ binaryFromHome: Object.freeze([".grok", "bin", "grok"]),
15472
+ argv: Object.freeze({
15473
+ prefix: Object.freeze(["agent"]),
15474
+ suffix: Object.freeze(["stdio"]),
15475
+ modelFlag: "--model"
15476
+ }),
15477
+ boundResume: "session/load",
15478
+ sessionBindingFile: "grok-acp-session.json",
15479
+ childEnv: Object.freeze({
15480
+ ...PRIVATE_COMPAT_ENV,
15481
+ GROK_MEMORY: "0",
15482
+ GROK_SUBAGENTS: "0"
15483
+ })
15484
+ })
15485
+ });
15486
+ }
15487
+ });
15488
+
15388
15489
  // src/public-cli/config.ts
15389
15490
  import { mkdir, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
15390
15491
  import { dirname as dirname4, join as join6 } from "node:path";
@@ -15468,7 +15569,8 @@ function setPersistentSeatHost(config, seat, host) {
15468
15569
  }
15469
15570
  return { ...config, seats: { ...config.seats, [seat]: rest } };
15470
15571
  }
15471
- return { ...config, seats: { ...config.seats, [seat]: { ...previous, host } } };
15572
+ const registered = assertRegisteredHostName(host);
15573
+ return { ...config, seats: { ...config.seats, [seat]: { ...previous, host: registered } } };
15472
15574
  }
15473
15575
  function setPersistentSeatEngine(config, seat, engine) {
15474
15576
  const previous = config.seats[seat];
@@ -15513,14 +15615,25 @@ function setAutoResumeLimit(config, limit) {
15513
15615
  function validatePublicCliConfigAxes(config, _packageRoot) {
15514
15616
  for (const seat of Object.keys(config.seats)) {
15515
15617
  const row = config.seats[seat];
15516
- if (row?.engine === void 0) continue;
15517
- try {
15518
- assertLegalEngineName(row.engine);
15519
- } catch (error) {
15520
- throw new Error(
15521
- `config seat ${seat} engine is illegal: ${row.engine}`,
15522
- { cause: error }
15523
- );
15618
+ if (row?.engine !== void 0) {
15619
+ try {
15620
+ assertLegalEngineName(row.engine);
15621
+ } catch (error) {
15622
+ throw new Error(
15623
+ `config seat ${seat} engine is illegal: ${row.engine}`,
15624
+ { cause: error }
15625
+ );
15626
+ }
15627
+ }
15628
+ if (row?.host !== void 0) {
15629
+ try {
15630
+ assertRegisteredHostName(row.host);
15631
+ } catch (error) {
15632
+ throw new Error(
15633
+ `config seat ${seat} host is unregistered: ${row.host}`,
15634
+ { cause: error }
15635
+ );
15636
+ }
15524
15637
  }
15525
15638
  }
15526
15639
  }
@@ -15667,7 +15780,7 @@ function attachHostAxis(seat, config, invocation) {
15667
15780
  if (invocation?.host !== void 0) return { ...seat, host: invocation.host, hostSource: "invocation" };
15668
15781
  const persistent = config.seats[seat.seat]?.host;
15669
15782
  if (persistent !== void 0) return { ...seat, host: persistent, hostSource: "persistent" };
15670
- return { ...seat, host: "pi", hostSource: "default" };
15783
+ return { ...seat, host: DEFAULT_ROLE_TURN_HOST, hostSource: "default" };
15671
15784
  }
15672
15785
  function attachEngineAxis(seat, config, invocation) {
15673
15786
  if (!isPublicCallableRole(seat.seat)) {
@@ -15788,6 +15901,7 @@ var GATE_OFFICER_SEATS;
15788
15901
  var init_config2 = __esm({
15789
15902
  "src/public-cli/config.ts"() {
15790
15903
  "use strict";
15904
+ init_host_descriptions();
15791
15905
  init_engine_material();
15792
15906
  init_institutional_resolution();
15793
15907
  init_registry2();
@@ -15817,21 +15931,27 @@ var init_cli_errors = __esm({
15817
15931
  }
15818
15932
  });
15819
15933
 
15820
- // src/public-cli/load-production-grok-host.ts
15934
+ // src/public-cli/load-production-acp-host.ts
15821
15935
  import { existsSync as existsSync3 } from "node:fs";
15822
15936
  import { join as join7 } from "node:path";
15823
15937
  import { pathToFileURL } from "node:url";
15824
- async function loadProductionGrokHostFactory(packageRoot2) {
15825
- const built = join7(packageRoot2, "dist/grok/production-host.js");
15826
- const source = join7(packageRoot2, "src/grok/production-host.ts");
15938
+ async function loadProductionAcpHostFactory(packageRoot2, host) {
15939
+ const description = lookupHostDescription(host);
15940
+ if (description === void 0) {
15941
+ throw new Error(`unregistered host: ${host}`);
15942
+ }
15943
+ const built = join7(packageRoot2, "dist/acp-host/production-host.js");
15944
+ const source = join7(packageRoot2, "src/acp-host/production-host.ts");
15827
15945
  const target = existsSync3(built) ? built : source;
15828
15946
  const href = pathToFileURL(target).href;
15829
15947
  const mod = await import(href);
15830
- return mod.createProductionGrokRoleTurnHost;
15948
+ const create = mod.createProductionAcpRoleTurnHost;
15949
+ return (options) => create({ ...options, description });
15831
15950
  }
15832
- var init_load_production_grok_host = __esm({
15833
- "src/public-cli/load-production-grok-host.ts"() {
15951
+ var init_load_production_acp_host = __esm({
15952
+ "src/public-cli/load-production-acp-host.ts"() {
15834
15953
  "use strict";
15954
+ init_host_descriptions();
15835
15955
  }
15836
15956
  });
15837
15957
 
@@ -16398,6 +16518,12 @@ function buildActivationFlagArgs(activation) {
16398
16518
  return ["--ak-role", "gatekeeper"];
16399
16519
  case "navigator":
16400
16520
  return ["--ak-role", "navigator"];
16521
+ case "diarist":
16522
+ return [
16523
+ "--ak-role",
16524
+ "diarist",
16525
+ ...activation.sourcesPath === void 0 ? [] : ["--ak-diarist-sources", activation.sourcesPath]
16526
+ ];
16401
16527
  default: {
16402
16528
  const _exhaustive = activation;
16403
16529
  return _exhaustive;
@@ -16548,7 +16674,7 @@ function createPiRoleTurnHost(config) {
16548
16674
  return {
16549
16675
  async executeTurn(request) {
16550
16676
  let turnRequest = request;
16551
- const paths = request.hostTransition?.previousHost === "grok-build" ? request.hostTransition.priorNativePaths : void 0;
16677
+ const paths = request.hostTransition?.priorNativeKind === "sitian" ? request.hostTransition.priorNativePaths : void 0;
16552
16678
  if (request.continuation.kind === "resume" && paths !== void 0 && paths.length > 0) {
16553
16679
  turnRequest = {
16554
16680
  ...request,
@@ -16742,7 +16868,8 @@ function validateAcceptedDetails(toolName, details) {
16742
16868
  [GLEANER_LEFT_OUTPUT_TOOL_NAME]: ["completed"],
16743
16869
  [INSPECTOR_OUTPUT_TOOL_NAME]: ["pass", "bounce"],
16744
16870
  [GATEKEEPER_OUTPUT_TOOL_NAME]: ["dispatch", "pass"],
16745
- [NAVIGATOR_OUTPUT_TOOL_NAME]: ["advice"]
16871
+ [NAVIGATOR_OUTPUT_TOOL_NAME]: ["advice"],
16872
+ [DIARIST_OUTPUT_TOOL_NAME]: ["completed"]
16746
16873
  };
16747
16874
  const collectorDiscriminator = toolName === COLLECTOR_OUTPUT_TOOL && Array.isArray(candidate?.groups);
16748
16875
  const baseDiscriminator = discriminator;
@@ -16778,6 +16905,8 @@ function validateAcceptedDetails(toolName, details) {
16778
16905
  return validateRecordedGatekeeperOutput(details);
16779
16906
  case NAVIGATOR_OUTPUT_TOOL_NAME:
16780
16907
  return validateRecordedNavigatorOutput(details);
16908
+ case DIARIST_OUTPUT_TOOL_NAME:
16909
+ return validateRecordedDiaristOutput(details);
16781
16910
  }
16782
16911
  } catch (error) {
16783
16912
  if (error instanceof Error && error.constructor === Error) throw new AcceptedDetailsContractError(error.message, { cause: error });
@@ -16795,6 +16924,7 @@ function acceptedFacts(toolName, details) {
16795
16924
  case INSPECTOR_OUTPUT_TOOL_NAME:
16796
16925
  case GATEKEEPER_OUTPUT_TOOL_NAME:
16797
16926
  case NAVIGATOR_OUTPUT_TOOL_NAME:
16927
+ case DIARIST_OUTPUT_TOOL_NAME:
16798
16928
  return { status: details.status };
16799
16929
  case JUDGE_OUTPUT_TOOL_NAME:
16800
16930
  return { status: details.judgeStatus };
@@ -16826,6 +16956,7 @@ var init_terminating_tools = __esm({
16826
16956
  init_countersign_contracts();
16827
16957
  init_gleaner_left_contracts();
16828
16958
  init_inspector_contracts();
16959
+ init_diarist_contracts();
16829
16960
  init_worker_output();
16830
16961
  TERMINATING_TOOL_NAMES = [
16831
16962
  CODER_OUTPUT_TOOL_NAME,
@@ -16840,7 +16971,8 @@ var init_terminating_tools = __esm({
16840
16971
  GLEANER_LEFT_OUTPUT_TOOL_NAME,
16841
16972
  INSPECTOR_OUTPUT_TOOL_NAME,
16842
16973
  GATEKEEPER_OUTPUT_TOOL_NAME,
16843
- NAVIGATOR_OUTPUT_TOOL_NAME
16974
+ NAVIGATOR_OUTPUT_TOOL_NAME,
16975
+ DIARIST_OUTPUT_TOOL_NAME
16844
16976
  ];
16845
16977
  AcceptedDetailsContractError = class extends CorrectableSubmissionError {
16846
16978
  code = "accepted_details_contract";
@@ -17319,7 +17451,7 @@ async function readRoleRunStateDisk(runDirectory) {
17319
17451
  if (typeof record4.runId !== "string" || record4.runId.trim() === "") {
17320
17452
  return void 0;
17321
17453
  }
17322
- if (record4.role !== "judge" && record4.role !== "coder" && record4.role !== "fixer" && record4.role !== "collector" && record4.role !== "doctor" && record4.role !== "reviewer" && record4.role !== "merger" && record4.role !== "notary" && record4.role !== "countersign" && record4.role !== "gleaner-left" && record4.role !== "inspector" && record4.role !== "gatekeeper" && record4.role !== "navigator") {
17454
+ if (record4.role !== "judge" && record4.role !== "coder" && record4.role !== "fixer" && record4.role !== "collector" && record4.role !== "doctor" && record4.role !== "reviewer" && record4.role !== "merger" && record4.role !== "notary" && record4.role !== "countersign" && record4.role !== "gleaner-left" && record4.role !== "inspector" && record4.role !== "gatekeeper" && record4.role !== "navigator" && record4.role !== "diarist") {
17323
17455
  return void 0;
17324
17456
  }
17325
17457
  if (record4.state !== "admitted" && record4.state !== "running" && record4.state !== "resumable" && record4.state !== "terminal") {
@@ -18134,6 +18266,19 @@ async function loadResumableGleanerLeftRun(home, runId, authority) {
18134
18266
  };
18135
18267
  return seatLoadedResult(loaded, admitted);
18136
18268
  }
18269
+ async function loadResumableDiaristRun(home, runId, authority) {
18270
+ const loaded = await loadResumableRunRecord(home, runId, authority);
18271
+ if (loaded.run.role !== "diarist") {
18272
+ throw new CliUsageError(
18273
+ `role run ${runId} belongs to ${loaded.run.role}, not diarist`
18274
+ );
18275
+ }
18276
+ const admitted = {
18277
+ role: "diarist",
18278
+ ...resumedBaseAdmitted(loaded)
18279
+ };
18280
+ return seatLoadedResult(loaded, admitted);
18281
+ }
18137
18282
  async function loadResumableMergerRun(home, runId, authority) {
18138
18283
  const loaded = await loadResumableRunRecord(home, runId, authority);
18139
18284
  if (loaded.run.role !== "merger") {
@@ -18650,7 +18795,7 @@ function renderHumanOwnerOptionLines(owner, locale2 = "en") {
18650
18795
  }
18651
18796
  return lines;
18652
18797
  }
18653
- var ANALYST_REQUIRE_ANY_OF, ANALYST_DEFAULT_MODE, REJECTED_PUBLIC_SPELLINGS, GLOBAL_OPTIONS, SHARED_PROJECT_SEMANTICS, SHARED_ATTACH_SEMANTICS, JUDGE_OPTIONS, GLEANER_LEFT_OPTIONS, INSPECTOR_OPTIONS, GATEKEEPER_OPTIONS, NAVIGATOR_OPTIONS, COUNTERSIGN_OPTIONS, CODER_OPTIONS, FIXER_OPTIONS, REVIEWER_OPTIONS, COLLECTOR_OPTIONS, DOCTOR_OPTIONS, NOTARY_OPTIONS, MERGER_OPTIONS, ANALYST_OPTIONS, PUBLIC_OPTION_TABLE, PUBLIC_NAVIGATOR_HELP_NOTE, TOP_LEVEL_HELP, ROLE_COMMAND_HELP, SUPPORT_COMMAND_HELP, PUBLIC_COMMAND_HELP;
18798
+ var ANALYST_REQUIRE_ANY_OF, ANALYST_DEFAULT_MODE, REJECTED_PUBLIC_SPELLINGS, GLOBAL_OPTIONS, SHARED_PROJECT_SEMANTICS, SHARED_ATTACH_SEMANTICS, JUDGE_OPTIONS, GLEANER_LEFT_OPTIONS, INSPECTOR_OPTIONS, GATEKEEPER_OPTIONS, NAVIGATOR_OPTIONS, COUNTERSIGN_OPTIONS, DIARIST_OPTIONS, CODER_OPTIONS, FIXER_OPTIONS, REVIEWER_OPTIONS, COLLECTOR_OPTIONS, DOCTOR_OPTIONS, NOTARY_OPTIONS, MERGER_OPTIONS, ANALYST_OPTIONS, PUBLIC_OPTION_TABLE, PUBLIC_NAVIGATOR_HELP_NOTE, TOP_LEVEL_HELP, ROLE_COMMAND_HELP, SUPPORT_COMMAND_HELP, PUBLIC_COMMAND_HELP;
18654
18799
  var init_option_definitions = __esm({
18655
18800
  "src/public-cli/option-definitions.ts"() {
18656
18801
  "use strict";
@@ -18827,6 +18972,10 @@ var init_option_definitions = __esm({
18827
18972
  bindOwner("countersign", SHARED_PROJECT_SEMANTICS),
18828
18973
  bindOwner("countersign", SHARED_ATTACH_SEMANTICS)
18829
18974
  ];
18975
+ DIARIST_OPTIONS = [
18976
+ bindOwner("diarist", SHARED_PROJECT_SEMANTICS),
18977
+ bindOwner("diarist", SHARED_ATTACH_SEMANTICS)
18978
+ ];
18830
18979
  CODER_OPTIONS = [
18831
18980
  {
18832
18981
  id: "phase",
@@ -19172,6 +19321,7 @@ var init_option_definitions = __esm({
19172
19321
  inspector: INSPECTOR_OPTIONS,
19173
19322
  gatekeeper: GATEKEEPER_OPTIONS,
19174
19323
  navigator: NAVIGATOR_OPTIONS,
19324
+ diarist: DIARIST_OPTIONS,
19175
19325
  analyst: ANALYST_OPTIONS
19176
19326
  };
19177
19327
  PUBLIC_NAVIGATOR_HELP_NOTE = "Navigator also attends automatically on every run; that sidecar is unchanged by direct `ak-role navigator` calls.";
@@ -19290,6 +19440,15 @@ var init_option_definitions = __esm({
19290
19440
  'ak-role navigator "\u521A\u5B8C\u6210 coder apply \u6536\u655B\uFF0C\u4E0B\u4E00\u6B65\uFF1F"'
19291
19441
  ]
19292
19442
  },
19443
+ diarist: {
19444
+ command: "diarist",
19445
+ summary: "Direct Diarist (\u8D77\u5C45\u90CE) pass: gather and organize this case's decision basis into its \u8D77\u5C45\u5F55.",
19446
+ usage: ["ak-role diarist [options] [instruction]"],
19447
+ examples: [
19448
+ 'ak-role diarist "\u6574\u7406 #708 \u7684\u672C\u6848\u4F9D\u636E\u3002"',
19449
+ 'ak-role diarist --attach ./design.md "\u8865\u5F55\u672C\u8F6E\u8BBE\u8BA1\u4FEE\u8BA2\u3002"'
19450
+ ]
19451
+ },
19293
19452
  notary: {
19294
19453
  command: "notary",
19295
19454
  summary: "Direct Notary document check (quote fidelity + ticket alignment); zero prompt/attachment.",
@@ -19668,6 +19827,9 @@ function parseGatekeeperArgv(args) {
19668
19827
  function parseNavigatorArgv(args) {
19669
19828
  return parseInstructionArgv(args, "navigator");
19670
19829
  }
19830
+ function parseDiaristArgv(args) {
19831
+ return parseInstructionArgv(args, "diarist");
19832
+ }
19671
19833
  function parseCoderArgv(args) {
19672
19834
  const attachmentPaths = [];
19673
19835
  let project;
@@ -19887,6 +20049,9 @@ async function admitGatekeeperInvocation(options) {
19887
20049
  async function admitNavigatorInvocation(options) {
19888
20050
  return admitStandardMaterialInvocation("navigator", options);
19889
20051
  }
20052
+ async function admitDiaristInvocation(options) {
20053
+ return admitStandardMaterialInvocation("diarist", options);
20054
+ }
19890
20055
  function buildInstructionTransportPrompt(admitted, engineMaterial) {
19891
20056
  const lines = [admitted.instructionEmpty ? "" : admitted.instruction];
19892
20057
  if (admitted.attachments.length > 0) {
@@ -22389,21 +22554,6 @@ function extractCornerQuotes(text, minLength = DEFAULT_QUOTE_MIN) {
22389
22554
  }
22390
22555
  return out;
22391
22556
  }
22392
- function buildDiaristAnchors(input) {
22393
- const fromBody = input.ticketBody === void 0 ? [] : extractCornerQuotes(input.ticketBody);
22394
- const quotes = [...fromBody, ...input.extraQuotes ?? []];
22395
- const seen = /* @__PURE__ */ new Set();
22396
- const uniqueQuotes = [];
22397
- for (const q of quotes) {
22398
- if (seen.has(q)) continue;
22399
- seen.add(q);
22400
- uniqueQuotes.push(q);
22401
- }
22402
- return {
22403
- ticketNumber: input.ticketNumber,
22404
- quotes: uniqueQuotes
22405
- };
22406
- }
22407
22557
  function filterNotifications(blocks) {
22408
22558
  return blocks.filter((b) => !b.isNotification);
22409
22559
  }
@@ -22429,15 +22579,6 @@ function dedupeSourceBlocks(blocks) {
22429
22579
  }
22430
22580
  return out;
22431
22581
  }
22432
- function verifyQuotesVerbatim(sourceText, quotes) {
22433
- const failed = [];
22434
- for (const q of quotes) {
22435
- if (q.length === 0) continue;
22436
- if (!sourceText.includes(q)) failed.push(q);
22437
- }
22438
- if (failed.length === 0) return { ok: true };
22439
- return { ok: false, failedQuotes: failed };
22440
- }
22441
22582
  function mechanicalSafeguardPipeline(blocks) {
22442
22583
  return dedupeSourceBlocks(filterNotifications(blocks));
22443
22584
  }
@@ -22693,38 +22834,6 @@ function readAdrDecisionKeyBlocks(input) {
22693
22834
  }
22694
22835
  return blocks;
22695
22836
  }
22696
- function blockToLlmEntry(block, input) {
22697
- const verify = verifyQuotesVerbatim(block.transcript, input.quotes);
22698
- if (!verify.ok) {
22699
- return {
22700
- ok: false,
22701
- failedQuotes: verify.failedQuotes,
22702
- cause: `verbatim verify failed: ${verify.failedQuotes.join(" | ")}`
22703
- };
22704
- }
22705
- const anchorNotes = [`#${input.anchors.ticketNumber}`];
22706
- const seen = new Set(anchorNotes);
22707
- for (const q of [...input.anchors.quotes, ...input.quotes]) {
22708
- if (seen.has(q)) continue;
22709
- seen.add(q);
22710
- anchorNotes.push(q);
22711
- if (anchorNotes.length >= 12) break;
22712
- }
22713
- return {
22714
- ok: true,
22715
- entry: {
22716
- basis: {
22717
- method: "llm-semantic",
22718
- anchors: anchorNotes,
22719
- ...input.note === void 0 ? {} : { note: input.note }
22720
- },
22721
- sourceKind: block.sourceKind,
22722
- sourceRef: block.sourceRef,
22723
- transcript: block.transcript,
22724
- timestamp: block.timestamp
22725
- }
22726
- };
22727
- }
22728
22837
  var DEFAULT_QUOTE_MIN, DiaristSourceReadError, DIARIST_ADR_ROOT_REL;
22729
22838
  var init_diarist_mechanical = __esm({
22730
22839
  "src/diarist-mechanical.ts"() {
@@ -22746,193 +22855,6 @@ var init_diarist_mechanical = __esm({
22746
22855
  }
22747
22856
  });
22748
22857
 
22749
- // src/diarist-llm-collector.ts
22750
- import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
22751
- import { join as join19 } from "node:path";
22752
- import { fileURLToPath as fileURLToPath2 } from "node:url";
22753
- function resolveDiaristCollectMethodPath(packageRoot2 = fileURLToPath2(packageRootUrl)) {
22754
- return join19(packageRoot2, DIARIST_COLLECT_METHOD_RELATIVE);
22755
- }
22756
- function isRecord11(value) {
22757
- return typeof value === "object" && value !== null && !Array.isArray(value);
22758
- }
22759
- function parseDiaristLlmStdout(stdout, candidateCount) {
22760
- const trimmed = stdout.trim();
22761
- if (trimmed.length === 0) {
22762
- throw new DiaristLlmStdoutError("empty-stdout", "diarist collector stdout is empty");
22763
- }
22764
- let parsed;
22765
- try {
22766
- parsed = JSON.parse(trimmed);
22767
- } catch (error) {
22768
- throw new DiaristLlmStdoutError(
22769
- "unparseable-json",
22770
- "diarist collector stdout is not JSON",
22771
- { cause: error }
22772
- );
22773
- }
22774
- if (!isRecord11(parsed)) {
22775
- throw new DiaristLlmStdoutError(
22776
- "not-object",
22777
- "diarist collector stdout must be one JSON object"
22778
- );
22779
- }
22780
- if (!Object.prototype.hasOwnProperty.call(parsed, "selections")) {
22781
- throw new DiaristLlmStdoutError(
22782
- "selections-missing",
22783
- "diarist collector stdout missing selections"
22784
- );
22785
- }
22786
- if (!Array.isArray(parsed.selections)) {
22787
- throw new DiaristLlmStdoutError(
22788
- "selections-wrong-type",
22789
- "diarist collector selections must be an array"
22790
- );
22791
- }
22792
- const out = [];
22793
- for (let rowIndex = 0; rowIndex < parsed.selections.length; rowIndex += 1) {
22794
- const row = parsed.selections[rowIndex];
22795
- if (!isRecord11(row)) {
22796
- throw new DiaristLlmStdoutError(
22797
- "selection-uninterpretable",
22798
- `diarist collector selection[${rowIndex}] is not an object`
22799
- );
22800
- }
22801
- if (typeof row.candidateIndex !== "number" || !Number.isInteger(row.candidateIndex)) {
22802
- throw new DiaristLlmStdoutError(
22803
- "selection-uninterpretable",
22804
- `diarist collector selection[${rowIndex}].candidateIndex is not an integer`
22805
- );
22806
- }
22807
- const index = row.candidateIndex;
22808
- if (index < 0 || index >= candidateCount) {
22809
- throw new DiaristLlmStdoutError(
22810
- "selection-uninterpretable",
22811
- `diarist collector selection[${rowIndex}].candidateIndex ${index} out of range 0..${candidateCount - 1}`
22812
- );
22813
- }
22814
- if (!Object.prototype.hasOwnProperty.call(row, "quotes")) {
22815
- throw new DiaristLlmStdoutError(
22816
- "selection-uninterpretable",
22817
- `diarist collector selection[${rowIndex}].quotes missing`
22818
- );
22819
- }
22820
- if (!Array.isArray(row.quotes)) {
22821
- throw new DiaristLlmStdoutError(
22822
- "selection-uninterpretable",
22823
- `diarist collector selection[${rowIndex}].quotes must be an array`
22824
- );
22825
- }
22826
- const quotes = [];
22827
- for (let qIndex = 0; qIndex < row.quotes.length; qIndex += 1) {
22828
- const q = row.quotes[qIndex];
22829
- if (typeof q !== "string") {
22830
- throw new DiaristLlmStdoutError(
22831
- "selection-uninterpretable",
22832
- `diarist collector selection[${rowIndex}].quotes[${qIndex}] is not a string`
22833
- );
22834
- }
22835
- if (q.length > 0) quotes.push(q);
22836
- }
22837
- const triage = row.triage === "relevant" || row.triage === "context" || row.triage === "irrelevant" ? row.triage : void 0;
22838
- out.push({
22839
- candidateIndex: index,
22840
- quotes,
22841
- ...typeof row.note === "string" ? { note: row.note } : {},
22842
- ...triage === void 0 ? {} : { triage }
22843
- });
22844
- }
22845
- return out;
22846
- }
22847
- function buildDiaristCollectorEnginePayload(input) {
22848
- return {
22849
- method: input.method,
22850
- ticketNumber: input.ticketNumber,
22851
- candidates: input.candidates.map((block, index) => ({
22852
- candidateIndex: index,
22853
- sourceKind: block.sourceKind,
22854
- isUserTurn: block.isUserTurn,
22855
- timestamp: block.timestamp,
22856
- transcript: block.transcript
22857
- }))
22858
- };
22859
- }
22860
- function serializeDiaristCollectorEnginePayload(payload) {
22861
- return JSON.stringify(payload);
22862
- }
22863
- function createHermesDiaristCollector(options = {}) {
22864
- const executable = options.executable ?? "hermes";
22865
- const methodPath = resolveDiaristCollectMethodPath(options.packageRoot);
22866
- if (!existsSync8(methodPath)) {
22867
- throw new Error(`diarist collect method material missing (${methodPath})`);
22868
- }
22869
- const method = readFileSync4(methodPath, "utf8");
22870
- if (method.trim().length === 0) {
22871
- throw new Error(`diarist collect method material is empty (${methodPath})`);
22872
- }
22873
- return async (input) => {
22874
- const payload = buildDiaristCollectorEnginePayload({
22875
- ticketNumber: input.ticketNumber,
22876
- candidates: input.candidates,
22877
- method
22878
- });
22879
- const prompt = serializeDiaristCollectorEnginePayload(payload);
22880
- const argv = [
22881
- executable,
22882
- ...options.extraArgv ?? [],
22883
- "chat",
22884
- "--query-file",
22885
- ENGINE_DETOUR_STAGED_PROMPT_TOKEN,
22886
- "-Q",
22887
- "--no-restore-cwd",
22888
- "--ignore-rules",
22889
- "-t",
22890
- HERMES_DIARIST_COLLECTOR_TOOLSET
22891
- ];
22892
- const result2 = await runEngineDetourOnce({
22893
- argv,
22894
- stagedPrompt: prompt,
22895
- cwd: options.cwd ?? process.cwd(),
22896
- ...options.env === void 0 ? {} : { env: options.env },
22897
- ...input.signal === void 0 ? {} : { signal: input.signal }
22898
- });
22899
- if (result2.code !== 0) {
22900
- throw new Error(
22901
- `diarist LLM collector engine exited ${result2.code}: ${result2.stderr.slice(0, 500)}`
22902
- );
22903
- }
22904
- const selections = parseDiaristLlmStdout(
22905
- result2.stdout,
22906
- input.candidates.length
22907
- );
22908
- return {
22909
- selections,
22910
- rawStdout: result2.stdout,
22911
- // Staged body redacted — argv face shows the path token only.
22912
- engineArgv: argv
22913
- };
22914
- };
22915
- }
22916
- var DIARIST_COLLECT_METHOD_RELATIVE, packageRootUrl, DiaristLlmStdoutError, HERMES_DIARIST_COLLECTOR_TOOLSET;
22917
- var init_diarist_llm_collector = __esm({
22918
- "src/diarist-llm-collector.ts"() {
22919
- "use strict";
22920
- init_engine_detour();
22921
- DIARIST_COLLECT_METHOD_RELATIVE = "resources/diarist-collect.md";
22922
- packageRootUrl = new URL("..", import.meta.url);
22923
- DiaristLlmStdoutError = class extends Error {
22924
- code = "diarist-llm-stdout";
22925
- reason;
22926
- constructor(reason, message, options) {
22927
- super(message, options);
22928
- this.name = "DiaristLlmStdoutError";
22929
- this.reason = reason;
22930
- }
22931
- };
22932
- HERMES_DIARIST_COLLECTOR_TOOLSET = "context_engine";
22933
- }
22934
- });
22935
-
22936
22858
  // src/reviewer-git-snapshot.ts
22937
22859
  var init_reviewer_git_snapshot = __esm({
22938
22860
  "src/reviewer-git-snapshot.ts"() {
@@ -22991,11 +22913,11 @@ var init_reviewer_pinned_git = __esm({
22991
22913
  });
22992
22914
 
22993
22915
  // src/ticket-provenance-contracts.ts
22994
- function isRecord12(value) {
22916
+ function isRecord11(value) {
22995
22917
  return typeof value === "object" && value !== null && !Array.isArray(value);
22996
22918
  }
22997
22919
  function projectTicketProvenanceDiagnostic(value) {
22998
- if (!isRecord12(value)) return void 0;
22920
+ if (!isRecord11(value)) return void 0;
22999
22921
  if (value.recordClass !== TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC) {
23000
22922
  return void 0;
23001
22923
  }
@@ -23017,18 +22939,18 @@ function projectTicketProvenanceDiagnostic(value) {
23017
22939
  };
23018
22940
  }
23019
22941
  function projectTicketProvenanceEntry(value) {
23020
- if (!isRecord12(value)) return void 0;
22942
+ if (!isRecord11(value)) return void 0;
23021
22943
  if (value.recordClass === TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC) {
23022
22944
  return void 0;
23023
22945
  }
23024
- if (!isRecord12(value.basis)) return void 0;
22946
+ if (!isRecord11(value.basis)) return void 0;
23025
22947
  if (typeof value.basis.method !== "string" || !BASIS_METHODS.has(value.basis.method)) {
23026
22948
  return void 0;
23027
22949
  }
23028
22950
  if (typeof value.sourceKind !== "string" || !SOURCE_KINDS.has(value.sourceKind)) {
23029
22951
  return void 0;
23030
22952
  }
23031
- if (!isRecord12(value.sourceRef)) return void 0;
22953
+ if (!isRecord11(value.sourceRef)) return void 0;
23032
22954
  if (typeof value.transcript !== "string" || value.transcript.length === 0) {
23033
22955
  return void 0;
23034
22956
  }
@@ -23083,8 +23005,8 @@ var init_ticket_provenance_contracts = __esm({
23083
23005
 
23084
23006
  // src/ticket-provenance.ts
23085
23007
  import { createHash as createHash6 } from "node:crypto";
23086
- import { appendFileSync as appendFileSync2, existsSync as existsSync9, mkdirSync as mkdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "node:fs";
23087
- import { join as join20 } from "node:path";
23008
+ import { appendFileSync as appendFileSync2, existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "node:fs";
23009
+ import { join as join19 } from "node:path";
23088
23010
  function ticketProvenanceSubject(ticketNumber) {
23089
23011
  if (!Number.isSafeInteger(ticketNumber) || ticketNumber < 1) {
23090
23012
  throw new Error(`ticket-provenance subject requires a positive ticket number, got ${String(ticketNumber)}`);
@@ -23107,30 +23029,6 @@ function ticketProvenanceEntryIdentity(input) {
23107
23029
  ].join("\0");
23108
23030
  return createHash6("sha256").update(material, "utf8").digest("hex");
23109
23031
  }
23110
- function appendTicketProvenanceEntry(input) {
23111
- const subject = ticketProvenanceSubject(input.ticketNumber);
23112
- const identity = ticketProvenanceEntryIdentity({
23113
- ticketNumber: input.ticketNumber,
23114
- sourceKind: input.entry.sourceKind,
23115
- sourceRef: input.entry.sourceRef,
23116
- transcript: input.entry.transcript
23117
- });
23118
- return sitianReport({
23119
- level: "event",
23120
- kind: TICKET_PROVENANCE_KIND,
23121
- identity,
23122
- subject,
23123
- cwd: input.cwd,
23124
- ...input.home === void 0 ? {} : { home: input.home },
23125
- host: input.host ?? "diarist",
23126
- source: input.source ?? "diarist",
23127
- payload: input.entry,
23128
- raw: input.entry.sourceRef.sessionFile !== void 0 && input.entry.sourceRef.entryId !== void 0 ? {
23129
- sessionFile: input.entry.sourceRef.sessionFile,
23130
- entryId: input.entry.sourceRef.entryId
23131
- } : void 0
23132
- });
23133
- }
23134
23032
  function resolveTicketProvenanceVolume(ticketNumber, cwd, home) {
23135
23033
  const path = resolveSitianRecordPath({
23136
23034
  level: "event",
@@ -23142,16 +23040,16 @@ function resolveTicketProvenanceVolume(ticketNumber, cwd, home) {
23142
23040
  return {
23143
23041
  recordFile: path.recordFile,
23144
23042
  volumeDir: path.sessionDir,
23145
- humanViewFile: join20(path.sessionDir, TICKET_PROVENANCE_HUMAN_VIEW),
23146
- offeredWatermarkFile: join20(path.sessionDir, TICKET_PROVENANCE_OFFERED_WATERMARK)
23043
+ humanViewFile: join19(path.sessionDir, TICKET_PROVENANCE_HUMAN_VIEW),
23044
+ offeredWatermarkFile: join19(path.sessionDir, TICKET_PROVENANCE_OFFERED_WATERMARK)
23147
23045
  };
23148
23046
  }
23149
23047
  function readOfferedIdentities(ticketNumber, cwd, home) {
23150
23048
  const { offeredWatermarkFile } = resolveTicketProvenanceVolume(ticketNumber, cwd, home);
23151
- if (!existsSync9(offeredWatermarkFile)) return /* @__PURE__ */ new Set();
23049
+ if (!existsSync8(offeredWatermarkFile)) return /* @__PURE__ */ new Set();
23152
23050
  let text;
23153
23051
  try {
23154
- text = readFileSync5(offeredWatermarkFile, "utf8");
23052
+ text = readFileSync4(offeredWatermarkFile, "utf8");
23155
23053
  } catch (error) {
23156
23054
  throw new TicketProvenanceWatermarkError(
23157
23055
  "unreadable",
@@ -23184,25 +23082,6 @@ function readOfferedIdentities(ticketNumber, cwd, home) {
23184
23082
  }
23185
23083
  return seen;
23186
23084
  }
23187
- function recordOfferedIdentities(input) {
23188
- if (input.identities.length === 0) return;
23189
- const { volumeDir, offeredWatermarkFile } = resolveTicketProvenanceVolume(
23190
- input.ticketNumber,
23191
- input.cwd,
23192
- input.home
23193
- );
23194
- const already = new Set(readOfferedIdentities(input.ticketNumber, input.cwd, input.home));
23195
- const rows = [];
23196
- for (const identity of input.identities) {
23197
- if (identity.length === 0 || already.has(identity)) continue;
23198
- rows.push(`${JSON.stringify({ identity })}
23199
- `);
23200
- already.add(identity);
23201
- }
23202
- if (rows.length === 0) return;
23203
- mkdirSync3(volumeDir, { recursive: true });
23204
- appendFileSync2(offeredWatermarkFile, rows.join(""), "utf8");
23205
- }
23206
23085
  async function readTicketProvenance(ticketNumber, cwd, home) {
23207
23086
  const { recordFile } = resolveTicketProvenanceVolume(ticketNumber, cwd, home);
23208
23087
  const { records: records2 } = await readSitianRecords(recordFile);
@@ -23317,21 +23196,6 @@ function appendTicketProvenanceDiagnostic(input) {
23317
23196
  payload: input.diagnostic
23318
23197
  });
23319
23198
  }
23320
- function appendCollectorFailureDiagnostic(input) {
23321
- const recordedAt = input.recordedAt ?? (/* @__PURE__ */ new Date()).toISOString();
23322
- return appendTicketProvenanceDiagnostic({
23323
- ticketNumber: input.ticketNumber,
23324
- cwd: input.cwd,
23325
- ...input.home === void 0 ? {} : { home: input.home },
23326
- source: "diarist-collector-fail",
23327
- diagnostic: {
23328
- recordClass: TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC,
23329
- diagnosticKind: "collector-failed",
23330
- cause: input.collectorError,
23331
- recordedAt
23332
- }
23333
- });
23334
- }
23335
23199
  function appendIssueSourceFailureDiagnostic(input) {
23336
23200
  const recordedAt = input.recordedAt ?? (/* @__PURE__ */ new Date()).toISOString();
23337
23201
  return appendTicketProvenanceDiagnostic({
@@ -23348,21 +23212,6 @@ function appendIssueSourceFailureDiagnostic(input) {
23348
23212
  }
23349
23213
  });
23350
23214
  }
23351
- function appendQuoteVerifyFailureDiagnostic(input) {
23352
- const recordedAt = input.recordedAt ?? (/* @__PURE__ */ new Date()).toISOString();
23353
- return appendTicketProvenanceDiagnostic({
23354
- ticketNumber: input.ticketNumber,
23355
- cwd: input.cwd,
23356
- ...input.home === void 0 ? {} : { home: input.home },
23357
- source: "diarist-quote-verify",
23358
- diagnostic: {
23359
- recordClass: TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC,
23360
- diagnosticKind: "quote-verify-failed",
23361
- cause: input.cause,
23362
- recordedAt
23363
- }
23364
- });
23365
- }
23366
23215
  function writeTicketProvenanceHumanView(input) {
23367
23216
  const volume = ensureTicketProvenanceVolume(input.ticketNumber, input.cwd, input.home);
23368
23217
  const md = renderTicketProvenanceMarkdown({
@@ -23472,6 +23321,43 @@ function resolveDiaristGithubOrigin(projectRoot) {
23472
23321
  if (remoteUrl.length === 0) return void 0;
23473
23322
  return parseGitHubOriginRemote(remoteUrl);
23474
23323
  }
23324
+ async function loadDiaristIssueFace(input) {
23325
+ const persistAndThrow = (error) => {
23326
+ appendIssueSourceFailureDiagnostic({
23327
+ ticketNumber: input.ticketNumber,
23328
+ cwd: input.projectRoot,
23329
+ ...input.home === void 0 ? {} : { home: input.home },
23330
+ cause: error.message,
23331
+ reason: error.reason
23332
+ });
23333
+ return error;
23334
+ };
23335
+ const origin = resolveDiaristGithubOrigin(input.projectRoot);
23336
+ if (origin === void 0) {
23337
+ throw persistAndThrow(
23338
+ new DiaristIssueSourceError(
23339
+ "origin-unresolved",
23340
+ `bound ticket #${input.ticketNumber} issue face requires a resolvable github.com origin remote`
23341
+ )
23342
+ );
23343
+ }
23344
+ const fetcher = input.fetcher ?? createDiaristIssueFaceFetcher();
23345
+ try {
23346
+ return await fetcher({
23347
+ owner: origin.owner,
23348
+ repo: origin.repo,
23349
+ ticketNumber: input.ticketNumber
23350
+ });
23351
+ } catch (error) {
23352
+ throw persistAndThrow(
23353
+ error instanceof DiaristIssueSourceError ? error : new DiaristIssueSourceError(
23354
+ "issue-unavailable",
23355
+ `issue face fetch failed for ${origin.owner}/${origin.repo}#${input.ticketNumber}`,
23356
+ { cause: error }
23357
+ )
23358
+ );
23359
+ }
23360
+ }
23475
23361
  async function loadSeenEntryIdentities(ticketNumber, cwd, home) {
23476
23362
  const { recordFile } = resolveTicketProvenanceVolume(ticketNumber, cwd, home);
23477
23363
  const { records: records2 } = await readSitianRecords(recordFile);
@@ -23494,7 +23380,7 @@ function blockEntryIdentity(ticketNumber, block) {
23494
23380
  transcript: block.transcript
23495
23381
  });
23496
23382
  }
23497
- async function loadSourceBlocks(input) {
23383
+ function loadSourceBlocks(input) {
23498
23384
  const cwds = input.sessionCwds ?? [input.cwd];
23499
23385
  const blocks = [...readCcSessionBlocks({ cwds })];
23500
23386
  if (input.issueFace !== void 0) {
@@ -23515,124 +23401,31 @@ async function loadSourceBlocks(input) {
23515
23401
  }
23516
23402
  return blocks;
23517
23403
  }
23518
- function faceTextForAnchors(face) {
23519
- if (face === void 0) return void 0;
23520
- const parts = [face.body, ...face.comments.map((c) => c.body)].filter(
23521
- (t) => t.trim() !== ""
23522
- );
23523
- if (parts.length === 0) return void 0;
23524
- return parts.join("\n");
23525
- }
23526
- async function runDiarist(input) {
23527
- const homeOpt = input.home === void 0 ? {} : { home: input.home };
23528
- const volumePaths = ensureTicketProvenanceVolume(input.ticketNumber, input.cwd, input.home);
23529
- const anchorText = faceTextForAnchors(input.issueFace);
23530
- const anchors = buildDiaristAnchors({
23404
+ async function prepareDiaristSourceCatalog(input) {
23405
+ ensureTicketProvenanceVolume(input.ticketNumber, input.cwd, input.home);
23406
+ const volume = await readTicketProvenance(input.ticketNumber, input.cwd, input.home);
23407
+ writeTicketProvenanceHumanView({
23531
23408
  ticketNumber: input.ticketNumber,
23532
- ...anchorText === void 0 ? {} : { ticketBody: anchorText }
23409
+ cwd: input.cwd,
23410
+ ...input.home === void 0 ? {} : { home: input.home },
23411
+ entries: volume.entries
23533
23412
  });
23534
- const rawBlocks = await loadSourceBlocks(input);
23413
+ const rawBlocks = loadSourceBlocks(input);
23535
23414
  const safeguarded = mechanicalSafeguardPipeline(rawBlocks);
23536
23415
  const seen = await loadSeenEntryIdentities(input.ticketNumber, input.cwd, input.home);
23537
23416
  const fresh = safeguarded.filter(
23538
23417
  (block) => !seen.has(blockEntryIdentity(input.ticketNumber, block))
23539
23418
  );
23540
- let collectorStatus;
23541
- let collectorError;
23542
- let llmRawStdout;
23543
- let collect;
23544
- const collector = createHermesDiaristCollector({
23545
- cwd: input.cwd,
23546
- ...input.packageRoot === void 0 ? {} : { packageRoot: input.packageRoot }
23547
- });
23548
- if (fresh.length === 0) {
23549
- collectorStatus = "skipped-no-fresh";
23550
- } else {
23551
- try {
23552
- collect = await collector({
23553
- ticketNumber: input.ticketNumber,
23554
- candidates: fresh,
23555
- ...input.signal === void 0 ? {} : { signal: input.signal }
23556
- });
23557
- llmRawStdout = collect.rawStdout;
23558
- collectorStatus = collect.selections.length === 0 ? "empty-selection" : "ok";
23559
- } catch (error) {
23560
- collectorStatus = "failed";
23561
- collectorError = error instanceof Error ? error.message : String(error);
23562
- appendCollectorFailureDiagnostic({
23563
- ticketNumber: input.ticketNumber,
23564
- cwd: input.cwd,
23565
- ...homeOpt,
23566
- collectorError
23567
- });
23568
- }
23569
- }
23570
- const pointers = [];
23571
- const accepted = [];
23572
- let rejectedQuotes = 0;
23573
- if (collect !== void 0 && collectorStatus === "ok") {
23574
- for (const selection of collect.selections) {
23575
- const block = fresh[selection.candidateIndex];
23576
- if (block === void 0) continue;
23577
- const projected = blockToLlmEntry(block, {
23578
- anchors,
23579
- quotes: selection.quotes,
23580
- ...selection.note === void 0 ? {} : { note: selection.note }
23581
- });
23582
- if (!projected.ok) {
23583
- rejectedQuotes += 1;
23584
- const ptr2 = appendQuoteVerifyFailureDiagnostic({
23585
- ticketNumber: input.ticketNumber,
23586
- cwd: input.cwd,
23587
- ...homeOpt,
23588
- cause: projected.cause
23589
- });
23590
- pointers.push(ptr2);
23591
- continue;
23592
- }
23593
- const ptr = appendTicketProvenanceEntry({
23594
- ticketNumber: input.ticketNumber,
23595
- cwd: input.cwd,
23596
- ...homeOpt,
23597
- entry: projected.entry,
23598
- source: "diarist"
23599
- });
23600
- pointers.push(ptr);
23601
- accepted.push(projected.entry);
23602
- }
23603
- }
23604
- if (collect !== void 0 && (collectorStatus === "ok" || collectorStatus === "empty-selection")) {
23605
- recordOfferedIdentities({
23606
- ticketNumber: input.ticketNumber,
23607
- cwd: input.cwd,
23608
- ...homeOpt,
23609
- identities: fresh.map(
23610
- (block) => blockEntryIdentity(input.ticketNumber, block)
23611
- )
23612
- });
23613
- }
23614
- const volume = await readTicketProvenance(input.ticketNumber, input.cwd, input.home);
23615
- const humanViewFile = writeTicketProvenanceHumanView({
23616
- ticketNumber: input.ticketNumber,
23617
- cwd: input.cwd,
23618
- ...homeOpt,
23619
- entries: volume.entries
23620
- });
23621
23419
  return {
23622
23420
  ticketNumber: input.ticketNumber,
23623
- candidateCount: safeguarded.length,
23624
- freshCount: fresh.length,
23625
- appended: accepted.length,
23626
- rejectedQuotes,
23627
- pointers,
23628
- entries: volume.entries,
23629
- humanViewFile,
23630
- volumeRecordFile: volumePaths.recordFile,
23631
- collectorStatus,
23632
- ...collectorError === void 0 ? {} : { collectorError },
23633
- ...llmRawStdout === void 0 ? {} : { llmRawStdout }
23421
+ cwd: input.cwd,
23422
+ ...input.home === void 0 ? {} : { home: input.home },
23423
+ candidates: fresh.map((block, candidateIndex) => ({ ...block, candidateIndex }))
23634
23424
  };
23635
23425
  }
23426
+ function serializeDiaristSourceCatalog(catalog) {
23427
+ return JSON.stringify(catalog);
23428
+ }
23636
23429
  var DiaristIssueSourceError;
23637
23430
  var init_diarist = __esm({
23638
23431
  "src/diarist.ts"() {
@@ -23640,7 +23433,6 @@ var init_diarist = __esm({
23640
23433
  init_adr_path_refs();
23641
23434
  init_collector_github();
23642
23435
  init_diarist_mechanical();
23643
- init_diarist_llm_collector();
23644
23436
  init_reviewer_pinned_git();
23645
23437
  init_ticket_provenance();
23646
23438
  init_sitian_facade();
@@ -23765,27 +23557,27 @@ var init_engine_detour_tool = __esm({
23765
23557
  });
23766
23558
 
23767
23559
  // src/session-opening-materials.ts
23768
- import { existsSync as existsSync10 } from "node:fs";
23769
- import { dirname as dirname8, join as join21 } from "node:path";
23770
- import { fileURLToPath as fileURLToPath3, pathToFileURL as pathToFileURL2 } from "node:url";
23560
+ import { existsSync as existsSync9 } from "node:fs";
23561
+ import { dirname as dirname8, join as join20 } from "node:path";
23562
+ import { fileURLToPath as fileURLToPath2, pathToFileURL as pathToFileURL2 } from "node:url";
23771
23563
  function resolvePackageRootDir(moduleUrl = import.meta.url) {
23772
- let dir = dirname8(fileURLToPath3(moduleUrl));
23564
+ let dir = dirname8(fileURLToPath2(moduleUrl));
23773
23565
  for (let i = 0; i < 8; i += 1) {
23774
- if (existsSync10(join21(dir, "package.json")) && existsSync10(join21(dir, "souls"))) {
23566
+ if (existsSync9(join20(dir, "package.json")) && existsSync9(join20(dir, "souls"))) {
23775
23567
  return dir;
23776
23568
  }
23777
23569
  const parent = dirname8(dir);
23778
23570
  if (parent === dir) break;
23779
23571
  dir = parent;
23780
23572
  }
23781
- return fileURLToPath3(new URL("..", moduleUrl));
23573
+ return fileURLToPath2(new URL("..", moduleUrl));
23782
23574
  }
23783
- var packageRootUrl2, MAIN_ROLE_SESSION_MATERIALS, GATEKEEPER_SESSION_MATERIALS;
23575
+ var packageRootUrl, MAIN_ROLE_SESSION_MATERIALS, GATEKEEPER_SESSION_MATERIALS;
23784
23576
  var init_session_opening_materials = __esm({
23785
23577
  "src/session-opening-materials.ts"() {
23786
23578
  "use strict";
23787
23579
  init_packaged_role_registry();
23788
- packageRootUrl2 = pathToFileURL2(resolvePackageRootDir() + "/").href;
23580
+ packageRootUrl = pathToFileURL2(resolvePackageRootDir() + "/").href;
23789
23581
  MAIN_ROLE_SESSION_MATERIALS = {
23790
23582
  ...Object.fromEntries(
23791
23583
  PUBLIC_ROLE_RECORDS.map((record4) => [record4.role, record4.sessionMaterials])
@@ -23835,11 +23627,11 @@ var init_navigator_session_contracts = __esm({
23835
23627
  });
23836
23628
 
23837
23629
  // src/receipt-delivery-policy.ts
23838
- function isRecord13(value) {
23630
+ function isRecord12(value) {
23839
23631
  return typeof value === "object" && value !== null && !Array.isArray(value);
23840
23632
  }
23841
23633
  function parseNoReceiptLifecycleFacts(input) {
23842
- if (!isRecord13(input) || typeof input.terminalToolCalled !== "boolean" || input.deliveryTurns !== RECEIPT_DELIVERY_TURN_LIMIT || input.sessionCompletion !== "settled-without-accepted-receipt" || input.acceptedReceipt !== false || typeof input.runPointer !== "string" || input.runPointer.trim() === "" || typeof input.attemptPointer !== "string" || input.attemptPointer.trim() === "" || !Array.isArray(input.rejectedReceipts) || !input.rejectedReceipts.every((item) => isRecord13(item) && typeof item.reason === "string")) {
23634
+ if (!isRecord12(input) || typeof input.terminalToolCalled !== "boolean" || input.deliveryTurns !== RECEIPT_DELIVERY_TURN_LIMIT || input.sessionCompletion !== "settled-without-accepted-receipt" || input.acceptedReceipt !== false || typeof input.runPointer !== "string" || input.runPointer.trim() === "" || typeof input.attemptPointer !== "string" || input.attemptPointer.trim() === "" || !Array.isArray(input.rejectedReceipts) || !input.rejectedReceipts.every((item) => isRecord12(item) && typeof item.reason === "string")) {
23843
23635
  throw new TypeError("malformed no-receipt lifecycle facts");
23844
23636
  }
23845
23637
  return {
@@ -23929,7 +23721,7 @@ var init_compliance_transport = __esm({
23929
23721
 
23930
23722
  // src/ledger-session-read.ts
23931
23723
  import { readFile as readFile12 } from "node:fs/promises";
23932
- function isRecord14(value) {
23724
+ function isRecord13(value) {
23933
23725
  return typeof value === "object" && value !== null && !Array.isArray(value);
23934
23726
  }
23935
23727
  async function readLedgerSessionJsonl(path) {
@@ -23953,7 +23745,7 @@ async function readLedgerSessionJsonl(path) {
23953
23745
  }
23954
23746
  break;
23955
23747
  }
23956
- if (!isRecord14(row)) {
23748
+ if (!isRecord13(row)) {
23957
23749
  const kind = row === null ? "null" : Array.isArray(row) ? "array" : typeof row;
23958
23750
  throw new LedgerSessionJsonlError(
23959
23751
  `complete non-object JSONL record in ${path} at line ${index + 1}: expected object, got ${kind}`,
@@ -23990,7 +23782,7 @@ function extractSessionModelSequence(rows) {
23990
23782
  if (row.type === "model_change" && typeof row.modelId === "string") {
23991
23783
  push(row.modelId);
23992
23784
  }
23993
- const message = isRecord14(row.message) ? row.message : void 0;
23785
+ const message = isRecord13(row.message) ? row.message : void 0;
23994
23786
  if (message?.role === "assistant" && typeof message.model === "string") {
23995
23787
  push(message.model);
23996
23788
  }
@@ -24006,11 +23798,11 @@ function extractSessionToolIntervals(rows) {
24006
23798
  const openById = /* @__PURE__ */ new Map();
24007
23799
  for (const row of rows) {
24008
23800
  const rowTimestamp = typeof row.timestamp === "string" ? row.timestamp : void 0;
24009
- const message = isRecord14(row.message) ? row.message : void 0;
23801
+ const message = isRecord13(row.message) ? row.message : void 0;
24010
23802
  if (message?.role === "assistant" && Array.isArray(message.content)) {
24011
23803
  const callTimestamp = typeof message.timestamp === "string" && message.timestamp ? message.timestamp : rowTimestamp;
24012
23804
  for (const part of message.content) {
24013
- if (!isRecord14(part) || part.type !== "toolCall") continue;
23805
+ if (!isRecord13(part) || part.type !== "toolCall") continue;
24014
23806
  if (typeof part.id !== "string" || part.id.length === 0) {
24015
23807
  throw new Error("toolCall frame missing string id");
24016
23808
  }
@@ -24023,7 +23815,7 @@ function extractSessionToolIntervals(rows) {
24023
23815
  if (openById.has(part.id)) {
24024
23816
  throw new Error(`duplicate toolCall id ${part.id}`);
24025
23817
  }
24026
- const args = isRecord14(part.arguments) ? part.arguments : void 0;
23818
+ const args = isRecord13(part.arguments) ? part.arguments : void 0;
24027
23819
  const command = part.name === "bash" && args !== void 0 && typeof args.command === "string" ? bashCommandFirstLine(args.command) : void 0;
24028
23820
  const interval = {
24029
23821
  toolCallId: part.id,
@@ -24108,8 +23900,8 @@ var init_ledger_session_read = __esm({
24108
23900
 
24109
23901
  // src/analyst-gate-cycles-read.ts
24110
23902
  import { readdir as readdir3 } from "node:fs/promises";
24111
- import { join as join22 } from "node:path";
24112
- function isRecord15(value) {
23903
+ import { join as join21 } from "node:path";
23904
+ function isRecord14(value) {
24113
23905
  return typeof value === "object" && value !== null && !Array.isArray(value);
24114
23906
  }
24115
23907
  function isParentAttemptBindingRow(row) {
@@ -24140,7 +23932,7 @@ function isGateTerminatingToolName(toolName) {
24140
23932
  function acceptedGateReceiptIds(rows) {
24141
23933
  const accepted = /* @__PURE__ */ new Set();
24142
23934
  for (const row of rows) {
24143
- const message = isRecord15(row.message) ? row.message : void 0;
23935
+ const message = isRecord14(row.message) ? row.message : void 0;
24144
23936
  if (message?.role !== "toolResult") continue;
24145
23937
  if (typeof message.toolCallId !== "string" || message.toolCallId.length === 0) continue;
24146
23938
  if (message.isError === false) accepted.add(message.toolCallId);
@@ -24179,7 +23971,7 @@ function nearestAttemptBindingBefore(rows, beforeIndex) {
24179
23971
  for (let i = beforeIndex - 1; i >= 0; i -= 1) {
24180
23972
  const row = rows[i];
24181
23973
  if (!isParentAttemptBindingRow(row)) continue;
24182
- if (!isRecord15(row.data) || !isRecord15(row.data.parent)) continue;
23974
+ if (!isRecord14(row.data) || !isRecord14(row.data.parent)) continue;
24183
23975
  const id = row.data.parent.attemptEntryId;
24184
23976
  const sessionFile = row.data.parent.sessionFile;
24185
23977
  return {
@@ -24194,10 +23986,10 @@ function extractAllAcceptedGateToolCalls(rows) {
24194
23986
  const out = [];
24195
23987
  for (let rowIndex = 0; rowIndex < rows.length; rowIndex += 1) {
24196
23988
  const row = rows[rowIndex];
24197
- const message = isRecord15(row.message) ? row.message : void 0;
23989
+ const message = isRecord14(row.message) ? row.message : void 0;
24198
23990
  if (message?.role !== "assistant" || !Array.isArray(message.content)) continue;
24199
23991
  for (const part of message.content) {
24200
- if (!isRecord15(part) || part.type !== "toolCall") continue;
23992
+ if (!isRecord14(part) || part.type !== "toolCall") continue;
24201
23993
  if (typeof part.id !== "string" || part.id.length === 0) continue;
24202
23994
  if (typeof part.name !== "string" || part.name.length === 0) continue;
24203
23995
  if (!isGateTerminatingToolName(part.name)) continue;
@@ -24205,7 +23997,7 @@ function extractAllAcceptedGateToolCalls(rows) {
24205
23997
  const binding = nearestAttemptBindingBefore(rows, rowIndex);
24206
23998
  out.push({
24207
23999
  toolName: part.name,
24208
- args: isRecord15(part.arguments) ? part.arguments : void 0,
24000
+ args: isRecord14(part.arguments) ? part.arguments : void 0,
24209
24001
  accepted: true,
24210
24002
  rowIndex,
24211
24003
  ...binding
@@ -24347,7 +24139,7 @@ async function readAnalystGateCyclesFromAuditorRoles(auditorRolesDirectory, opti
24347
24139
  throw error;
24348
24140
  }
24349
24141
  for (const name of names) {
24350
- const classified = await classifyAuditorVolume(join22(directory, name));
24142
+ const classified = await classifyAuditorVolume(join21(directory, name));
24351
24143
  for (const volume of classified) {
24352
24144
  if (options.parentSessionFile !== void 0 && volume.parentSessionFile !== void 0 && volume.parentSessionFile !== options.parentSessionFile) {
24353
24145
  continue;
@@ -24405,21 +24197,21 @@ var init_gatekeeper_role = __esm({
24405
24197
 
24406
24198
  // src/run-terminal-artifacts.ts
24407
24199
  import { readdir as readdir4, readFile as readFile13 } from "node:fs/promises";
24408
- import { basename as basename7, dirname as dirname9, join as join23 } from "node:path";
24200
+ import { basename as basename7, dirname as dirname9, join as join22 } from "node:path";
24409
24201
  function isMissingPathError2(error) {
24410
24202
  return error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR");
24411
24203
  }
24412
24204
  function errorText2(error) {
24413
24205
  return error instanceof Error ? error.message : String(error);
24414
24206
  }
24415
- function isRecord16(value) {
24207
+ function isRecord15(value) {
24416
24208
  return typeof value === "object" && value !== null && !Array.isArray(value);
24417
24209
  }
24418
24210
  function readUsableTerminalArtifactBody(body) {
24419
24211
  if (body === null) {
24420
24212
  return { ok: false, reason: "terminal artifact JSON value is null" };
24421
24213
  }
24422
- if (!isRecord16(body)) {
24214
+ if (!isRecord15(body)) {
24423
24215
  return {
24424
24216
  ok: false,
24425
24217
  reason: `terminal artifact JSON value is not a typed object (${Array.isArray(body) ? "array" : typeof body})`
@@ -24480,7 +24272,7 @@ async function listUniqueErrorFallbackPaths(directories) {
24480
24272
  }
24481
24273
  for (const name of names.sort((a, b) => a.localeCompare(b))) {
24482
24274
  if (!UNIQUE_ERROR_FALLBACK_NAME.test(name)) continue;
24483
- found.push(join23(dir, name));
24275
+ found.push(join22(dir, name));
24484
24276
  }
24485
24277
  }
24486
24278
  return found;
@@ -24496,14 +24288,14 @@ function presentUniqueFallbackBoundToRun(body, expectedRunId) {
24496
24288
  return typeof body.runId === "string" && body.runId === expectedRunId;
24497
24289
  }
24498
24290
  async function readRunTerminalArtifact(runDirectory) {
24499
- const artifactsDir = join23(runDirectory, "artifacts");
24291
+ const artifactsDir = join22(runDirectory, "artifacts");
24500
24292
  for (const file of RUN_TERMINAL_ARTIFACT_FILES) {
24501
- const path = join23(artifactsDir, file);
24293
+ const path = join22(artifactsDir, file);
24502
24294
  const read3 = await readTerminalArtifactAtPath(path, file);
24503
24295
  if (read3 !== void 0) return read3;
24504
24296
  }
24505
24297
  for (const relative3 of RUN_TERMINAL_ERROR_FALLBACK_RELATIVE_PATHS) {
24506
- const path = join23(runDirectory, relative3);
24298
+ const path = join22(runDirectory, relative3);
24507
24299
  const read3 = await readTerminalArtifactAtPath(path, "error.json");
24508
24300
  if (read3 !== void 0) return read3;
24509
24301
  }
@@ -24790,12 +24582,12 @@ var init_reviewer_dispatch = __esm({
24790
24582
 
24791
24583
  // src/public-cli/reviewer-dispatch-rejection.ts
24792
24584
  import { readFile as readFile14, unlink as unlink3 } from "node:fs/promises";
24793
- import { join as join24 } from "node:path";
24585
+ import { join as join23 } from "node:path";
24794
24586
  function isReviewerPreflightViolation(value) {
24795
24587
  return typeof value === "string" && REVIEWER_PREFLIGHT_VIOLATIONS.includes(value);
24796
24588
  }
24797
24589
  function reviewerDispatchRejectionPath(runDirectory) {
24798
- return join24(runDirectory, REVIEWER_DISPATCH_REJECTION_FILE);
24590
+ return join23(runDirectory, REVIEWER_DISPATCH_REJECTION_FILE);
24799
24591
  }
24800
24592
  async function clearReviewerDispatchRejection(runDirectory) {
24801
24593
  try {
@@ -25177,7 +24969,7 @@ var init_terminal = __esm({
25177
24969
  // src/public-cli/settlement.ts
25178
24970
  import { randomUUID as randomUUID3 } from "node:crypto";
25179
24971
  import { appendFile as appendFile2, readFile as readFile15, readdir as readdir5, writeFile as writeFile7 } from "node:fs/promises";
25180
- import { dirname as dirname10, join as join25 } from "node:path";
24972
+ import { dirname as dirname10, join as join24 } from "node:path";
25181
24973
  function sealedLedgerHome(admitted) {
25182
24974
  return homeFromRunDirectory(admitted.runDirectory);
25183
24975
  }
@@ -25557,7 +25349,7 @@ async function readSitianRetainedAuditorProviderStop(sessionFile) {
25557
25349
  const { records: records2 } = await readSitianRecords(recordFile);
25558
25350
  for (let i = records2.length - 1; i >= 0; i -= 1) {
25559
25351
  const payload = records2[i]?.payload;
25560
- if (!isRecord17(payload) || !isRecord17(payload.response)) continue;
25352
+ if (!isRecord16(payload) || !isRecord16(payload.response)) continue;
25561
25353
  if (typeof payload.type === "string") continue;
25562
25354
  const stop = sessionProviderStopFromAssistant(payload.response);
25563
25355
  if (stop !== void 0) return stop;
@@ -25578,7 +25370,7 @@ async function readSessionProviderStop(sessionFile) {
25578
25370
  }
25579
25371
  }
25580
25372
  async function readBoundEvidenceChildKnownFailure(sessionFile) {
25581
- const childDirectory = join25(dirname10(sessionFile), "evidence-children");
25373
+ const childDirectory = join24(dirname10(sessionFile), "evidence-children");
25582
25374
  let names;
25583
25375
  try {
25584
25376
  names = await readdir5(childDirectory);
@@ -25589,12 +25381,12 @@ async function readBoundEvidenceChildKnownFailure(sessionFile) {
25589
25381
  for (const file of names.filter((name) => name.endsWith(".jsonl")).sort().reverse()) {
25590
25382
  let entries;
25591
25383
  try {
25592
- entries = await readBoundSessionEntries(join25(childDirectory, file));
25384
+ entries = await readBoundSessionEntries(join24(childDirectory, file));
25593
25385
  } catch (error) {
25594
25386
  throw sessionReadFailure(error, "failed to read discovered evidence-child session");
25595
25387
  }
25596
25388
  const header = entries.find((entry) => entry.type === "session");
25597
- if (!isRecord17(header) || header.parentSession !== sessionFile) continue;
25389
+ if (!isRecord16(header) || header.parentSession !== sessionFile) continue;
25598
25390
  const stop = extractSessionProviderStop(entries);
25599
25391
  if (stop === void 0) continue;
25600
25392
  const primary = knownFailureFromProviderStop(stop);
@@ -25626,12 +25418,12 @@ async function loadBoundAuditorVolumes(sessionFile) {
25626
25418
  return firstLine === RESUME_ENVELOPE;
25627
25419
  };
25628
25420
  const isResumeEnvelope = (msg) => {
25629
- if (!isRecord17(msg) || msg.role !== "user") return false;
25421
+ if (!isRecord16(msg) || msg.role !== "user") return false;
25630
25422
  const text = typeof msg.text === "string" ? msg.text : typeof msg.content === "string" ? msg.content : void 0;
25631
25423
  if (isResumeEnvelopeBytes(text)) return true;
25632
25424
  const content = msg.content;
25633
25425
  if (Array.isArray(content)) {
25634
- return content.some((p) => isRecord17(p) && (isResumeEnvelopeBytes(p.text) || isResumeEnvelopeBytes(p.content)));
25426
+ return content.some((p) => isRecord16(p) && (isResumeEnvelopeBytes(p.text) || isResumeEnvelopeBytes(p.content)));
25635
25427
  }
25636
25428
  return false;
25637
25429
  };
@@ -25643,7 +25435,7 @@ async function loadBoundAuditorVolumes(sessionFile) {
25643
25435
  latestParentUserIndex = i;
25644
25436
  break;
25645
25437
  }
25646
- const childDirectories = [join25(dirname10(sessionFile), "auditor-roles")];
25438
+ const childDirectories = [join24(dirname10(sessionFile), "auditor-roles")];
25647
25439
  const valid = [];
25648
25440
  let sawAnyDirectory = false;
25649
25441
  for (const childDirectory of childDirectories) {
@@ -25658,12 +25450,12 @@ async function loadBoundAuditorVolumes(sessionFile) {
25658
25450
  for (const file of names.filter((name) => name.endsWith(".jsonl")).sort().reverse()) {
25659
25451
  let entries;
25660
25452
  try {
25661
- entries = await readBoundSessionEntries(join25(childDirectory, file));
25453
+ entries = await readBoundSessionEntries(join24(childDirectory, file));
25662
25454
  } catch (error) {
25663
25455
  throw sessionReadFailure(error, "failed to read discovered auditor session");
25664
25456
  }
25665
25457
  const header = entries.find((entry) => entry.type === "session");
25666
- if (!isRecord17(header)) continue;
25458
+ if (!isRecord16(header)) continue;
25667
25459
  const bindingIndexes = [];
25668
25460
  for (let i = 0; i < entries.length; i += 1) {
25669
25461
  const entry = entries[i];
@@ -25677,7 +25469,7 @@ async function loadBoundAuditorVolumes(sessionFile) {
25677
25469
  end: idx + 1 < bindingIndexes.length ? bindingIndexes[idx + 1] : entries.length
25678
25470
  })) : [{ entry: void 0, start: 0, end: entries.length }];
25679
25471
  for (const { entry: bindingEntry, start, end } of bindingPasses) {
25680
- const bindingParent = bindingEntry !== void 0 && isRecord17(bindingEntry.data) && isRecord17(bindingEntry.data.parent) ? bindingEntry.data.parent : void 0;
25472
+ const bindingParent = bindingEntry !== void 0 && isRecord16(bindingEntry.data) && isRecord16(bindingEntry.data.parent) ? bindingEntry.data.parent : void 0;
25681
25473
  const attemptEntryId = typeof bindingParent?.attemptEntryId === "string" ? bindingParent.attemptEntryId : void 0;
25682
25474
  const attemptEntryIndex = attemptEntryId === void 0 ? -1 : parentEntries.findIndex((entry) => entry.id === attemptEntryId);
25683
25475
  const boundSessionFile = typeof bindingParent?.sessionFile === "string" ? bindingParent.sessionFile : typeof header.parentSession === "string" ? header.parentSession : void 0;
@@ -25704,11 +25496,11 @@ function complianceFailureFromAuditorVolumes(volumes) {
25704
25496
  if (stop === void 0) continue;
25705
25497
  for (let i = entries.length - 1; i >= 0; i -= 1) {
25706
25498
  const entry = entries[i];
25707
- if (entry?.type !== "custom" || entry.customType !== AUDITOR_COMPLIANCE_FAILURE_ENTRY_TYPE || !isRecord17(entry.data)) continue;
25708
- const parent = isRecord17(entry.data.parent) ? entry.data.parent : void 0;
25709
- const failure = isRecord17(entry.data.failure) ? entry.data.failure : void 0;
25499
+ if (entry?.type !== "custom" || entry.customType !== AUDITOR_COMPLIANCE_FAILURE_ENTRY_TYPE || !isRecord16(entry.data)) continue;
25500
+ const parent = isRecord16(entry.data.parent) ? entry.data.parent : void 0;
25501
+ const failure = isRecord16(entry.data.failure) ? entry.data.failure : void 0;
25710
25502
  if (parent?.sessionId !== parentId || parent.sessionFile !== sessionFile || parent.attemptEntryId !== attemptEntryId || failure?.cause !== "provider" && failure?.cause !== "unrecognized") continue;
25711
- const identity = isRecord17(failure.identity) ? failure.identity : void 0;
25503
+ const identity = isRecord16(failure.identity) ? failure.identity : void 0;
25712
25504
  return {
25713
25505
  cause: failure.cause === "provider" ? "provider" : "unrecognized",
25714
25506
  ...identity === void 0 ? {} : { identity: {
@@ -25716,7 +25508,7 @@ function complianceFailureFromAuditorVolumes(volumes) {
25716
25508
  ...typeof identity.code === "string" || typeof identity.code === "number" ? { code: identity.code } : {}
25717
25509
  } },
25718
25510
  ...typeof failure.diagnostic === "string" ? { diagnostic: failure.diagnostic } : {},
25719
- ...isRecord17(failure.details) ? { details: failure.details } : {}
25511
+ ...isRecord16(failure.details) ? { details: failure.details } : {}
25720
25512
  };
25721
25513
  }
25722
25514
  }
@@ -25763,9 +25555,9 @@ function typedFailedTerminatingToolKnownFailure(entries) {
25763
25555
  if (classification.kind !== "infrastructure") continue;
25764
25556
  if (typeof message.toolCallId !== "string" || typeof message.toolName !== "string") continue;
25765
25557
  if (boundRoleToolCallForResult(attemptEntries, i, message, message.toolName) === void 0) continue;
25766
- const textPart = Array.isArray(message.content) ? message.content.find((part) => isRecord17(part) && part.type === "text" && typeof part.text === "string") : void 0;
25767
- const diagnostic = isRecord17(textPart) ? textPart.text : void 0;
25768
- const details = isRecord17(message.details) ? message.details : classification.fact;
25558
+ const textPart = Array.isArray(message.content) ? message.content.find((part) => isRecord16(part) && part.type === "text" && typeof part.text === "string") : void 0;
25559
+ const diagnostic = isRecord16(textPart) ? textPart.text : void 0;
25560
+ const details = isRecord16(message.details) ? message.details : classification.fact;
25769
25561
  return {
25770
25562
  cause: "output",
25771
25563
  identity: { name: message.toolName, code: message.toolCallId },
@@ -25923,7 +25715,7 @@ function controlledFailureInputFromResolution(resolution) {
25923
25715
  } : {}
25924
25716
  };
25925
25717
  }
25926
- function isRecord17(value) {
25718
+ function isRecord16(value) {
25927
25719
  return typeof value === "object" && value !== null && !Array.isArray(value);
25928
25720
  }
25929
25721
  function safelyRead(object, key) {
@@ -25946,7 +25738,7 @@ function countersignDecisiveFacts(verdict, countersignStatus) {
25946
25738
  const facts = { countersignStatus };
25947
25739
  if (countersignStatus === "continue") {
25948
25740
  const fix = safelyRead(verdict, "fix");
25949
- if (fix.readable && isRecord17(fix.value)) {
25741
+ if (fix.readable && isRecord16(fix.value)) {
25950
25742
  const summary = safelyRead(fix.value, "summary");
25951
25743
  if (summary.readable && typeof summary.value === "string") {
25952
25744
  facts.fixSummary = summary.value;
@@ -25955,7 +25747,7 @@ function countersignDecisiveFacts(verdict, countersignStatus) {
25955
25747
  }
25956
25748
  if (countersignStatus === "escalate") {
25957
25749
  const gate = safelyRead(verdict, "decisionGate");
25958
- if (gate.readable && isRecord17(gate.value)) {
25750
+ if (gate.readable && isRecord16(gate.value)) {
25959
25751
  const question = safelyRead(gate.value, "question");
25960
25752
  const options = safelyRead(gate.value, "options");
25961
25753
  if (question.readable && typeof question.value === "string") {
@@ -25980,7 +25772,7 @@ function judgeDecisiveFacts(verdict, judgeStatus) {
25980
25772
  const statusBase = judgeStatus;
25981
25773
  if (statusBase === "continue") {
25982
25774
  const fix = safelyRead(verdict, "fix");
25983
- if (fix.readable && isRecord17(fix.value)) {
25775
+ if (fix.readable && isRecord16(fix.value)) {
25984
25776
  const summary = safelyRead(fix.value, "summary");
25985
25777
  if (summary.readable && typeof summary.value === "string") {
25986
25778
  facts.fixSummary = summary.value;
@@ -25990,7 +25782,7 @@ function judgeDecisiveFacts(verdict, judgeStatus) {
25990
25782
  if (classes.readable && Array.isArray(classes.value)) {
25991
25783
  try {
25992
25784
  facts.classes = classes.value.map((entry) => {
25993
- if (!isRecord17(entry)) throw new Error("unreadable Judge class");
25785
+ if (!isRecord16(entry)) throw new Error("unreadable Judge class");
25994
25786
  return {
25995
25787
  name: entry.name,
25996
25788
  owner: entry.owner,
@@ -26005,7 +25797,7 @@ function judgeDecisiveFacts(verdict, judgeStatus) {
26005
25797
  }
26006
25798
  if (statusBase === "escalate") {
26007
25799
  const gate = safelyRead(verdict, "decisionGate");
26008
- if (gate.readable && isRecord17(gate.value)) {
25800
+ if (gate.readable && isRecord16(gate.value)) {
26009
25801
  const question = safelyRead(gate.value, "question");
26010
25802
  const options = safelyRead(gate.value, "options");
26011
25803
  if (question.readable && typeof question.value === "string") {
@@ -26051,7 +25843,7 @@ function fixerDecisiveFacts(output) {
26051
25843
  facts.reason = reason.value;
26052
25844
  }
26053
25845
  const blockerRead = safelyRead(candidate, "blocker");
26054
- if (statusBase === "refused" && blockerRead.readable && isRecord17(blockerRead.value)) {
25846
+ if (statusBase === "refused" && blockerRead.readable && isRecord16(blockerRead.value)) {
26055
25847
  const cause = safelyRead(blockerRead.value, "cause");
26056
25848
  if (cause.readable && typeof cause.value === "string") facts.blockerCause = cause.value;
26057
25849
  const prerequisiteId = safelyRead(blockerRead.value, "prerequisiteId");
@@ -26063,13 +25855,13 @@ function fixerDecisiveFacts(output) {
26063
25855
  const blockers = [];
26064
25856
  try {
26065
25857
  for (const entry of classResults.value) {
26066
- if (!isRecord17(entry)) throw new Error("unreadable class result");
25858
+ if (!isRecord16(entry)) throw new Error("unreadable class result");
26067
25859
  const name = safelyRead(entry, "name");
26068
25860
  const disposition = safelyRead(entry, "disposition");
26069
25861
  if (!name.readable || !disposition.readable) throw new Error("unreadable class result");
26070
25862
  rows.push({ name: name.value, disposition: disposition.value });
26071
25863
  const blocker = safelyRead(entry, "blocker");
26072
- if (disposition.value === "refused" && blocker.readable && isRecord17(blocker.value)) blockers.push(blocker.value);
25864
+ if (disposition.value === "refused" && blocker.readable && isRecord16(blocker.value)) blockers.push(blocker.value);
26073
25865
  }
26074
25866
  facts.classResultCount = rows.length;
26075
25867
  facts.classDispositions = rows;
@@ -26102,7 +25894,7 @@ function collectorDecisiveFacts(receipt) {
26102
25894
  if (groups.readable && Array.isArray(groups.value)) {
26103
25895
  try {
26104
25896
  facts.groups = groups.value.map((group) => {
26105
- if (!isRecord17(group)) throw new Error("unreadable Collector group");
25897
+ if (!isRecord16(group)) throw new Error("unreadable Collector group");
26106
25898
  const identity = safelyRead(group, "identity");
26107
25899
  const attendance = safelyRead(group, "attendance");
26108
25900
  const materials = safelyRead(group, "materials");
@@ -26136,7 +25928,7 @@ function doctorDecisiveFacts(output) {
26136
25928
  return facts;
26137
25929
  }
26138
25930
  const caseValue = safelyRead(candidate, "case");
26139
- if (caseValue.readable && isRecord17(caseValue.value)) {
25931
+ if (caseValue.readable && isRecord16(caseValue.value)) {
26140
25932
  const issueNumber = safelyRead(caseValue.value, "issueNumber");
26141
25933
  const runsPath = safelyRead(caseValue.value, "runsPath");
26142
25934
  if (issueNumber.readable && issueNumber.value !== void 0) facts.issueNumber = issueNumber.value;
@@ -26147,7 +25939,7 @@ function doctorDecisiveFacts(output) {
26147
25939
  return facts;
26148
25940
  }
26149
25941
  function reviewerAxes(value) {
26150
- if (!isRecord17(value)) return [];
25942
+ if (!isRecord16(value)) return [];
26151
25943
  return ["standards", "spec"].filter((axis) => {
26152
25944
  const projected = safelyRead(value, axis);
26153
25945
  return projected.readable && projected.value !== void 0;
@@ -26281,7 +26073,7 @@ function boundRoleToolCallForResult(entries, resultIndex, message, outputToolNam
26281
26073
  const candidateMessage = entries[index]?.message;
26282
26074
  if (candidateMessage?.role === "assistant" && Array.isArray(candidateMessage.content)) {
26283
26075
  for (const part of candidateMessage.content) {
26284
- if (!isRecord17(part) || part.type !== "toolCall" || part.id !== callId) {
26076
+ if (!isRecord16(part) || part.type !== "toolCall" || part.id !== callId) {
26285
26077
  continue;
26286
26078
  }
26287
26079
  if (part.name !== outputToolName) return void 0;
@@ -26353,7 +26145,7 @@ function parseNavigatorAttendanceDetails(details) {
26353
26145
  const advisoryDiagnostic = typeof details.routePlaybookReadFailure === "string" ? { advisoryDiagnostic: details.routePlaybookReadFailure } : {};
26354
26146
  if (disposition === "recommendation") {
26355
26147
  const next = details.next;
26356
- if (!isRecord17(next) || typeof next.role !== "string") {
26148
+ if (!isRecord16(next) || typeof next.role !== "string") {
26357
26149
  return {
26358
26150
  disposition: "unavailable",
26359
26151
  source: "unknown",
@@ -26361,7 +26153,7 @@ function parseNavigatorAttendanceDetails(details) {
26361
26153
  };
26362
26154
  }
26363
26155
  const reason = typeof details.reason === "string" ? details.reason : "";
26364
- const route = Array.isArray(details.route) ? details.route.filter(isRecord17).map((target) => ({
26156
+ const route = Array.isArray(details.route) ? details.route.filter(isRecord16).map((target) => ({
26365
26157
  role: String(target.role),
26366
26158
  phase: navigatorPhaseValue(target.phase)
26367
26159
  })) : void 0;
@@ -26424,8 +26216,8 @@ function projectTerminalGateFact(rounds) {
26424
26216
  };
26425
26217
  }
26426
26218
  async function extractGateFactFromSessionDirectory(sessionDirectory, options = {}) {
26427
- const directories = [join25(sessionDirectory, "auditor-roles")];
26428
- const parentSessionFile = options.parentSessionFile ?? join25(sessionDirectory, "session.jsonl");
26219
+ const directories = [join24(sessionDirectory, "auditor-roles")];
26220
+ const parentSessionFile = options.parentSessionFile ?? join24(sessionDirectory, "session.jsonl");
26429
26221
  const rounds = await readAnalystGateCyclesFromAuditorRoles(directories, {
26430
26222
  parentSessionFile
26431
26223
  });
@@ -26433,7 +26225,7 @@ async function extractGateFactFromSessionDirectory(sessionDirectory, options = {
26433
26225
  }
26434
26226
  async function withOptionalGateProjection(base, sessionDirectory, gateContext = {}) {
26435
26227
  const secondaryEvidence = base.roleOutcome.kind === "failure" ? base.roleOutcome.decisiveFacts.secondaryEvidence : void 0;
26436
- if (isRecord17(secondaryEvidence) && secondaryEvidence.kind === "role_infrastructure_failure" && (secondaryEvidence.stage === "gatekeeper" || secondaryEvidence.stage === "inspector" || secondaryEvidence.stage === "notary")) return base;
26228
+ if (isRecord16(secondaryEvidence) && secondaryEvidence.kind === "role_infrastructure_failure" && (secondaryEvidence.stage === "gatekeeper" || secondaryEvidence.stage === "inspector" || secondaryEvidence.stage === "notary")) return base;
26437
26229
  const gate = await extractGateFactFromSessionDirectory(sessionDirectory, gateContext);
26438
26230
  return gate === void 0 ? base : { ...base, gate };
26439
26231
  }
@@ -26473,7 +26265,7 @@ function extractNavigatorFact(entries) {
26473
26265
  const entry = entries[i];
26474
26266
  if (entry?.type === "custom_message" && entry.customType === "ak-navigator-attendance") {
26475
26267
  const details = entry.message?.details ?? entry.details;
26476
- if (!isRecord17(details)) {
26268
+ if (!isRecord16(details)) {
26477
26269
  return {
26478
26270
  disposition: "unavailable",
26479
26271
  source: "unknown",
@@ -26523,8 +26315,8 @@ async function extractNavigatorFactFromAdmittedSession(sessionFile) {
26523
26315
  async function publishJudgeArtifacts(admitted, roleOutcome, coordinates) {
26524
26316
  await appendRunAttemptHistory({ role: admitted.role, runId: admitted.runId, sessionFile: coordinates.sessionFile }, roleOutcome);
26525
26317
  const artifactsDir = await ensureRunArtifactsDir(admitted.runDirectory);
26526
- const reportPath = join25(artifactsDir, "report.json");
26527
- const evidencePath = join25(artifactsDir, "evidence.json");
26318
+ const reportPath = join24(artifactsDir, "report.json");
26319
+ const evidencePath = join24(artifactsDir, "evidence.json");
26528
26320
  await writeFile7(
26529
26321
  reportPath,
26530
26322
  `${JSON.stringify(
@@ -26568,8 +26360,8 @@ async function publishJudgeArtifacts(admitted, roleOutcome, coordinates) {
26568
26360
  async function publishCoderArtifacts(admitted, roleOutcome, coordinates, options = {}) {
26569
26361
  await appendRunAttemptHistory({ role: admitted.role, runId: admitted.runId, sessionFile: coordinates.sessionFile }, roleOutcome);
26570
26362
  const artifactsDir = await ensureRunArtifactsDir(admitted.runDirectory);
26571
- const reportPath = join25(artifactsDir, "report.json");
26572
- const evidencePath = join25(artifactsDir, "evidence.json");
26363
+ const reportPath = join24(artifactsDir, "report.json");
26364
+ const evidencePath = join24(artifactsDir, "evidence.json");
26573
26365
  await writeFile7(
26574
26366
  reportPath,
26575
26367
  `${JSON.stringify(
@@ -26728,8 +26520,8 @@ function extractFixerMethodInvocations(entries, options) {
26728
26520
  async function publishFixerArtifacts(admitted, roleOutcome, coordinates, options) {
26729
26521
  await appendRunAttemptHistory({ role: admitted.role, runId: admitted.runId, sessionFile: coordinates.sessionFile }, roleOutcome);
26730
26522
  const artifactsDir = await ensureRunArtifactsDir(admitted.runDirectory);
26731
- const reportPath = join25(artifactsDir, "report.json");
26732
- const evidencePath = join25(artifactsDir, "evidence.json");
26523
+ const reportPath = join24(artifactsDir, "report.json");
26524
+ const evidencePath = join24(artifactsDir, "evidence.json");
26733
26525
  await writeFile7(
26734
26526
  reportPath,
26735
26527
  `${JSON.stringify(
@@ -26828,8 +26620,8 @@ async function settleLawfulFixerTerminalResult(admitted, authority, options) {
26828
26620
  async function publishCollectorArtifacts(admitted, roleOutcome, coordinates, options = {}) {
26829
26621
  await appendRunAttemptHistory({ role: admitted.role, runId: admitted.runId, sessionFile: coordinates.sessionFile }, roleOutcome);
26830
26622
  const artifactsDir = await ensureRunArtifactsDir(admitted.runDirectory);
26831
- const reportPath = join25(artifactsDir, "report.json");
26832
- const evidencePath = join25(artifactsDir, "evidence.json");
26623
+ const reportPath = join24(artifactsDir, "report.json");
26624
+ const evidencePath = join24(artifactsDir, "evidence.json");
26833
26625
  await writeFile7(
26834
26626
  reportPath,
26835
26627
  `${JSON.stringify(
@@ -26888,7 +26680,7 @@ async function settleLawfulCollectorTerminalResult(admitted, authority) {
26888
26680
  const residual = boundErroredToolCandidate(entries, index, message, COLLECTOR_WAIT_TOOL);
26889
26681
  if (residual === void 0) continue;
26890
26682
  const candidate = residual.candidate;
26891
- const duration = isRecord17(candidate) ? candidate.durationMs : void 0;
26683
+ const duration = isRecord16(candidate) ? candidate.durationMs : void 0;
26892
26684
  if (Number.isSafeInteger(duration) && duration >= 1 && duration <= 9e5) {
26893
26685
  continue;
26894
26686
  }
@@ -26936,8 +26728,8 @@ async function trySettleCollectorTerminalResult(admitted, authority) {
26936
26728
  async function publishDoctorArtifacts(admitted, roleOutcome, coordinates, options = {}) {
26937
26729
  await appendRunAttemptHistory({ role: admitted.role, runId: admitted.runId, sessionFile: coordinates.sessionFile }, roleOutcome);
26938
26730
  const artifactsDir = await ensureRunArtifactsDir(admitted.runDirectory);
26939
- const reportPath = join25(artifactsDir, "report.json");
26940
- const evidencePath = join25(artifactsDir, "evidence.json");
26731
+ const reportPath = join24(artifactsDir, "report.json");
26732
+ const evidencePath = join24(artifactsDir, "evidence.json");
26941
26733
  await writeFile7(
26942
26734
  reportPath,
26943
26735
  `${JSON.stringify(
@@ -27196,6 +26988,27 @@ async function settleLawfulGleanerLeftTerminalResult(admitted, authority, scope)
27196
26988
  async function trySettleGleanerLeftTerminalResult(admitted, authority, scope) {
27197
26989
  return settleLawfulGleanerLeftTerminalResult(admitted, authority, scope);
27198
26990
  }
26991
+ async function settleLawfulDiaristTerminalResult(admitted, authority, scope) {
26992
+ return settleLawfulSeatAcceptedTerminalResult(admitted, authority, {
26993
+ role: "diarist",
26994
+ toolName: DIARIST_OUTPUT_TOOL_NAME,
26995
+ nonUsableDiagnostic: "\u8D77\u5C45\u90CE\u56DE\u6267\u65E0\u663E\u5F0F completed",
26996
+ tryAcceptDetails: tryAcceptWithValidator(validateRecordedDiaristOutput),
26997
+ projectAccepted: (sealed) => {
26998
+ const output = validateRecordedDiaristOutput(sealed.decisiveFacts);
26999
+ const accepted = {
27000
+ kind: "accepted",
27001
+ role: "diarist",
27002
+ status: sealed.status,
27003
+ decisiveFacts: diaristDecisiveFacts(output)
27004
+ };
27005
+ return accepted;
27006
+ }
27007
+ }, scope);
27008
+ }
27009
+ async function trySettleDiaristTerminalResult(admitted, authority, scope) {
27010
+ return settleLawfulDiaristTerminalResult(admitted, authority, scope);
27011
+ }
27199
27012
  async function settleLawfulInspectorTerminalResult(admitted, authority, scope) {
27200
27013
  return settleLawfulSeatAcceptedTerminalResult(admitted, authority, {
27201
27014
  role: "inspector",
@@ -27284,8 +27097,8 @@ function extractReviewerMethodInvocations(entries, options) {
27284
27097
  async function publishReviewerArtifacts(admitted, roleOutcome, coordinates, options) {
27285
27098
  await appendRunAttemptHistory({ role: admitted.role, runId: admitted.runId, sessionFile: coordinates.sessionFile }, roleOutcome);
27286
27099
  const artifactsDir = await ensureRunArtifactsDir(admitted.runDirectory);
27287
- const reportPath = join25(artifactsDir, "report.json");
27288
- const evidencePath = join25(artifactsDir, "evidence.json");
27100
+ const reportPath = join24(artifactsDir, "report.json");
27101
+ const evidencePath = join24(artifactsDir, "evidence.json");
27289
27102
  await writeFile7(
27290
27103
  reportPath,
27291
27104
  `${JSON.stringify(
@@ -27412,8 +27225,8 @@ function extractMergerMethodInvocations(entries, options) {
27412
27225
  async function publishMergerArtifacts(admitted, roleOutcome, coordinates, options) {
27413
27226
  await appendRunAttemptHistory({ role: admitted.role, runId: admitted.runId, sessionFile: coordinates.sessionFile }, roleOutcome);
27414
27227
  const artifactsDir = await ensureRunArtifactsDir(admitted.runDirectory);
27415
- const reportPath = join25(artifactsDir, "report.json");
27416
- const evidencePath = join25(artifactsDir, "evidence.json");
27228
+ const reportPath = join24(artifactsDir, "report.json");
27229
+ const evidencePath = join24(artifactsDir, "evidence.json");
27417
27230
  await writeFile7(
27418
27231
  reportPath,
27419
27232
  `${JSON.stringify(
@@ -27480,7 +27293,7 @@ async function settleLawfulMergerTerminalResult(admitted, authority, options) {
27480
27293
  if (message?.role !== "toolResult") continue;
27481
27294
  const residual = boundErroredToolCandidate(entries, index, message, MERGER_OUTPUT_TOOL_NAME);
27482
27295
  if (residual === void 0) continue;
27483
- const attemptId = isRecord17(residual.candidate) ? safelyRead(residual.candidate, "attemptId") : { readable: true, value: void 0 };
27296
+ const attemptId = isRecord16(residual.candidate) ? safelyRead(residual.candidate, "attemptId") : { readable: true, value: void 0 };
27484
27297
  if (!attemptId.readable || attemptId.value !== admitted.runId) continue;
27485
27298
  try {
27486
27299
  validateMergerOutput(residual.candidate, admitted.runId);
@@ -27562,7 +27375,7 @@ function uniqueFailureFallbackDirs(runDirectory, baseDir) {
27562
27375
  return dirs;
27563
27376
  }
27564
27377
  async function resolveFailureArtifactsBase(runDirectory) {
27565
- const artifactsDir = join25(runDirectory, "artifacts");
27378
+ const artifactsDir = join24(runDirectory, "artifacts");
27566
27379
  try {
27567
27380
  await ensureRunArtifactsDir(runDirectory);
27568
27381
  return { baseDir: artifactsDir };
@@ -27578,7 +27391,7 @@ async function writeFailureJsonRetainingCause(preferredCandidates, uniqueFallbac
27578
27391
  const candidates = [
27579
27392
  ...preferredCandidates,
27580
27393
  // One unique name per fallback dir — collisions on fixed names cannot exhaust this.
27581
- ...uniqueFallbackDirs.map((dir) => join25(dir, `${stem}.${randomUUID3()}.json`))
27394
+ ...uniqueFallbackDirs.map((dir) => join24(dir, `${stem}.${randomUUID3()}.json`))
27582
27395
  ];
27583
27396
  for (let i = 0; i < candidates.length; i += 1) {
27584
27397
  const path = candidates[i];
@@ -27623,26 +27436,26 @@ async function publishFailureArtifacts(admitted, failure, authority) {
27623
27436
  } catch (error) {
27624
27437
  priorIssues.push(publicationAttemptFromError(sessionFile, error));
27625
27438
  }
27626
- const underArtifacts = baseDir === join25(admitted.runDirectory, "artifacts");
27439
+ const underArtifacts = baseDir === join24(admitted.runDirectory, "artifacts");
27627
27440
  const uniqueFallbackDirs = uniqueFailureFallbackDirs(
27628
27441
  admitted.runDirectory,
27629
27442
  baseDir
27630
27443
  );
27631
27444
  const errorCandidates = underArtifacts ? [
27632
- join25(baseDir, "error.json"),
27633
- join25(baseDir, "error.settlement.json"),
27634
- join25(admitted.runDirectory, "error.settlement.json")
27445
+ join24(baseDir, "error.json"),
27446
+ join24(baseDir, "error.settlement.json"),
27447
+ join24(admitted.runDirectory, "error.settlement.json")
27635
27448
  ] : [
27636
- join25(baseDir, "error.settlement.json"),
27637
- join25(baseDir, "error.json")
27449
+ join24(baseDir, "error.settlement.json"),
27450
+ join24(baseDir, "error.json")
27638
27451
  ];
27639
27452
  const evidenceCandidates = underArtifacts ? [
27640
- join25(baseDir, "evidence.json"),
27641
- join25(baseDir, "evidence.settlement.json"),
27642
- join25(admitted.runDirectory, "evidence.settlement.json")
27453
+ join24(baseDir, "evidence.json"),
27454
+ join24(baseDir, "evidence.settlement.json"),
27455
+ join24(admitted.runDirectory, "evidence.settlement.json")
27643
27456
  ] : [
27644
- join25(baseDir, "evidence.settlement.json"),
27645
- join25(baseDir, "evidence.json")
27457
+ join24(baseDir, "evidence.settlement.json"),
27458
+ join24(baseDir, "evidence.json")
27646
27459
  ];
27647
27460
  const errorPayloadBase = {
27648
27461
  kind: "error",
@@ -27854,6 +27667,7 @@ var init_settlement = __esm({
27854
27667
  init_notary_contracts();
27855
27668
  init_countersign_contracts();
27856
27669
  init_gleaner_left_contracts();
27670
+ init_diarist_contracts();
27857
27671
  init_inspector_contracts();
27858
27672
  init_gatekeeper_output();
27859
27673
  init_navigator_output();
@@ -27914,10 +27728,7 @@ var init_turn_request = __esm({
27914
27728
 
27915
27729
  // src/host-transition-prior-native.ts
27916
27730
  import { access as access2, readdir as readdir6 } from "node:fs/promises";
27917
- import { dirname as dirname11, join as join26 } from "node:path";
27918
- function isKnownRoleTurnHost(value) {
27919
- return KNOWN_ROLE_TURN_HOSTS.includes(value);
27920
- }
27731
+ import { dirname as dirname11, join as join25 } from "node:path";
27921
27732
  function isEnoent2(error) {
27922
27733
  return typeof error === "object" && error !== null && error.code === "ENOENT";
27923
27734
  }
@@ -27942,7 +27753,7 @@ async function listSitianRecordPaths(sessionParent) {
27942
27753
  const recordPaths = [];
27943
27754
  for (const entry of entries) {
27944
27755
  if (!entry.isDirectory()) continue;
27945
- const recordFile = join26(sessionRoot, entry.name, "records.jsonl");
27756
+ const recordFile = join25(sessionRoot, entry.name, "records.jsonl");
27946
27757
  try {
27947
27758
  await access2(recordFile);
27948
27759
  recordPaths.push(recordFile);
@@ -27955,27 +27766,20 @@ async function listSitianRecordPaths(sessionParent) {
27955
27766
  }
27956
27767
  async function projectHostTransitionPriorNative(input) {
27957
27768
  if (input.previousHost === input.liveHost) return void 0;
27958
- if (!isKnownRoleTurnHost(input.previousHost) || !isKnownRoleTurnHost(input.liveHost)) {
27959
- return void 0;
27960
- }
27961
27769
  if (input.previousHost === "pi") {
27962
- const paths2 = await listPiNativeRecordPaths(input.piSessionFile);
27963
27770
  return {
27964
- previousHost: "pi",
27965
- priorNativePaths: paths2
27771
+ priorNativeKind: "pi-native",
27772
+ priorNativePaths: await listPiNativeRecordPaths(input.piSessionFile)
27966
27773
  };
27967
27774
  }
27968
- const paths = await listSitianRecordPaths(input.piSessionFile);
27969
27775
  return {
27970
- previousHost: "grok-build",
27971
- priorNativePaths: paths
27776
+ priorNativeKind: "sitian",
27777
+ priorNativePaths: await listSitianRecordPaths(input.piSessionFile)
27972
27778
  };
27973
27779
  }
27974
- var KNOWN_ROLE_TURN_HOSTS;
27975
27780
  var init_host_transition_prior_native = __esm({
27976
27781
  "src/host-transition-prior-native.ts"() {
27977
27782
  "use strict";
27978
- KNOWN_ROLE_TURN_HOSTS = ["pi", "grok-build"];
27979
27783
  }
27980
27784
  });
27981
27785
 
@@ -28019,7 +27823,7 @@ var init_public_run_credentials = __esm({
28019
27823
  import { constants as fsConstants } from "node:fs";
28020
27824
  import { randomUUID as randomUUID4 } from "node:crypto";
28021
27825
  import { lstat as lstat5, mkdir as mkdir4, open as open2 } from "node:fs/promises";
28022
- import { join as join27 } from "node:path";
27826
+ import { join as join26 } from "node:path";
28023
27827
  function presentTerminal(terminal, io) {
28024
27828
  if (terminal.roleOutcome.kind === "failure" || terminal.roleOutcome.kind === "no_receipt") {
28025
27829
  presentFailureTerminal(terminal, io);
@@ -28038,7 +27842,7 @@ async function finalizeExceptionRunBestEffort(runDirectory, io) {
28038
27842
  }
28039
27843
  }
28040
27844
  function runArtifactsDirectory(runDirectory) {
28041
- return join27(runDirectory, "artifacts");
27845
+ return join26(runDirectory, "artifacts");
28042
27846
  }
28043
27847
  async function ensureRealArtifactsDirectory(runDirectory) {
28044
27848
  const runStat = await lstat5(runDirectory);
@@ -28121,7 +27925,7 @@ function jsonSafeReplacer() {
28121
27925
  }
28122
27926
  async function retainDispatchError(admitted, principalAuthority, sessionAppender, attempt, error) {
28123
27927
  const artifactsDir = await ensureRealArtifactsDirectory(admitted.runDirectory);
28124
- const filePath = join27(
27928
+ const filePath = join26(
28125
27929
  artifactsDir,
28126
27930
  `dispatch-error-attempt-${attempt}-${randomUUID4()}.json`
28127
27931
  );
@@ -28370,10 +28174,10 @@ var init_auto_resume = __esm({
28370
28174
  // src/public-cli/post-admission.ts
28371
28175
  import { randomUUID as randomUUID5 } from "node:crypto";
28372
28176
  import { readFile as readFile16, writeFile as writeFile8 } from "node:fs/promises";
28373
- import { isAbsolute as isAbsolute6, join as join28, resolve as resolve9 } from "node:path";
28177
+ import { isAbsolute as isAbsolute6, join as join27, resolve as resolve9 } from "node:path";
28374
28178
  async function readInvocationHost(runDirectory) {
28375
28179
  try {
28376
- const raw = JSON.parse(await readFile16(join28(runDirectory, "invocation.json"), "utf8"));
28180
+ const raw = JSON.parse(await readFile16(join27(runDirectory, "invocation.json"), "utf8"));
28377
28181
  return typeof raw.host === "string" && raw.host.trim() !== "" ? raw.host : void 0;
28378
28182
  } catch (error) {
28379
28183
  if (error.code === "ENOENT") return void 0;
@@ -28513,7 +28317,7 @@ async function dispatchPostAdmissionTurn(input) {
28513
28317
  }
28514
28318
  try {
28515
28319
  await writeFile8(
28516
- join28(admitted.runDirectory, "stderr.log"),
28320
+ join27(admitted.runDirectory, "stderr.log"),
28517
28321
  result2.stderr,
28518
28322
  "utf8"
28519
28323
  );
@@ -28625,7 +28429,7 @@ function resumeTurnRequestProjectionOptions(admitted, request, env, summonsPrepa
28625
28429
  }
28626
28430
  function isAlreadyFrozenSummonsAttachment(runDirectory, attachmentPath) {
28627
28431
  const absolute = isAbsolute6(attachmentPath) ? attachmentPath : resolve9(attachmentPath);
28628
- return pathContainedIn(join28(runDirectory, "attachments"), absolute);
28432
+ return pathContainedIn(join27(runDirectory, "attachments"), absolute);
28629
28433
  }
28630
28434
  async function prepareSummonsResumeMaterials(runDirectory, summons) {
28631
28435
  if (summons === void 0) return void 0;
@@ -29428,7 +29232,6 @@ async function runPublicCountersign(argv, env, io, parseCountersignArgv2) {
29428
29232
  turnRequest,
29429
29233
  buildCountersignTurnRequest(admitted2, turnProjection)
29430
29234
  );
29431
- await runCountersignDiaristStation(admitted2, env);
29432
29235
  }
29433
29236
  }),
29434
29237
  ...env.engine === void 0 ? {} : { effectiveEngine: env.engine }
@@ -29467,97 +29270,219 @@ async function runPublicCountersignResume(request, env, io) {
29467
29270
  )
29468
29271
  );
29469
29272
  },
29470
- adapters: countersignAdapters({
29471
- beforeDispatch: async (admitted) => {
29472
- await runCountersignDiaristStation(admitted, env);
29473
- }
29474
- }),
29273
+ adapters: countersignAdapters(),
29475
29274
  ...env.engine === void 0 ? {} : { effectiveEngine: env.engine }
29476
29275
  });
29477
29276
  }
29478
- async function runCountersignDiaristStation(admitted, env) {
29277
+ var init_countersign_run = __esm({
29278
+ "src/public-cli/countersign-run.ts"() {
29279
+ "use strict";
29280
+ init_engine_material();
29281
+ init_cli_errors();
29282
+ init_invocation();
29283
+ init_seat_ticket_binding();
29284
+ init_post_admission();
29285
+ init_run_lifecycle();
29286
+ init_settlement();
29287
+ init_turn_request();
29288
+ }
29289
+ });
29290
+
29291
+ // src/public-cli/diarist-run.ts
29292
+ import { existsSync as existsSync10 } from "node:fs";
29293
+ import { writeFile as writeFile9 } from "node:fs/promises";
29294
+ import { join as join28 } from "node:path";
29295
+ function withDiaristCatalogPath(prompt, sourcesPath) {
29296
+ if (sourcesPath === void 0 || sourcesPath.trim() === "") return prompt;
29297
+ return `${prompt}
29298
+
29299
+ \u5DF2\u51BB\u7ED3\u6765\u6E90\u6587\u4EF6\uFF08\u8DEF\u5F84\uFF09\uFF1A
29300
+ - ${sourcesPath}`;
29301
+ }
29302
+ function buildDiaristTurnRequest(admitted, options, sourcesPath) {
29303
+ const continuation = sourcesPath === void 0 ? options.continuation : {
29304
+ ...options.continuation,
29305
+ prompt: withDiaristCatalogPath(options.continuation.prompt, sourcesPath)
29306
+ };
29307
+ return projectRoleTurnRequest(
29308
+ admitted,
29309
+ {
29310
+ activation: {
29311
+ role: "diarist",
29312
+ ...sourcesPath === void 0 ? {} : { sourcesPath }
29313
+ }
29314
+ },
29315
+ { ...options, continuation }
29316
+ );
29317
+ }
29318
+ async function freezeDiaristSourceCatalog(admitted, env) {
29479
29319
  if (admitted.ticketNumber === void 0) return void 0;
29480
- const issueFace = await loadBoundIssueFace(admitted);
29481
- const home = tryHomeFromAkRolesPath(admitted.runDirectory);
29482
- const result2 = await runDiarist({
29320
+ const path = join28(admitted.runDirectory, DIARIST_SOURCE_CATALOG_FILE);
29321
+ if (existsSync10(path)) {
29322
+ const identity = await readRoleRunIdentity(admitted.runDirectory);
29323
+ if (identity !== void 0 && identity.state !== "terminal") return path;
29324
+ }
29325
+ const issueFace = await loadDiaristIssueFace({
29326
+ ticketNumber: admitted.ticketNumber,
29327
+ projectRoot: admitted.projectRoot,
29328
+ home: env.home
29329
+ });
29330
+ const catalog = await prepareDiaristSourceCatalog({
29483
29331
  ticketNumber: admitted.ticketNumber,
29484
29332
  cwd: admitted.projectRoot,
29485
- ...home === void 0 ? {} : { home },
29333
+ home: env.home,
29486
29334
  issueFace,
29487
- sessionCwds: [admitted.projectRoot, env.cwd],
29488
- ...env.packageRoot === void 0 ? {} : { packageRoot: env.packageRoot }
29335
+ sessionCwds: [admitted.projectRoot, env.cwd]
29489
29336
  });
29490
- return result2;
29337
+ await writeFile9(path, serializeDiaristSourceCatalog(catalog), "utf8");
29338
+ return path;
29491
29339
  }
29492
- function persistIssueSourceFailure(admitted, ticketNumber, error) {
29493
- const home = tryHomeFromAkRolesPath(admitted.runDirectory);
29494
- appendIssueSourceFailureDiagnostic({
29495
- ticketNumber,
29496
- cwd: admitted.projectRoot,
29497
- ...home === void 0 ? {} : { home },
29498
- cause: error.message,
29499
- reason: error.reason
29500
- });
29501
- throw error;
29340
+ function diaristAdapters(options) {
29341
+ return {
29342
+ trySettle: (admitted, authority, scope) => trySettleDiaristTerminalResult(admitted, authority, scope),
29343
+ shouldPresentSettled: () => true,
29344
+ ...options?.beforeDispatch === void 0 ? {} : { beforeDispatch: options.beforeDispatch }
29345
+ };
29502
29346
  }
29503
- async function loadBoundIssueFace(admitted) {
29504
- const ticketNumber = admitted.ticketNumber;
29505
- if (ticketNumber === void 0) {
29506
- throw new Error("loadBoundIssueFace requires a bound ticketNumber");
29347
+ async function runPublicDiarist(argv, env, io, parseDiaristArgv2) {
29348
+ let parsed;
29349
+ try {
29350
+ parsed = parseDiaristArgv2(argv);
29351
+ } catch (error) {
29352
+ if (error instanceof CliUsageError) {
29353
+ presentStructuralRejection(error, io);
29354
+ return { exitCode: 2 };
29355
+ }
29356
+ throw error;
29507
29357
  }
29508
- const origin = resolveDiaristGithubOrigin(admitted.projectRoot);
29509
- if (origin === void 0) {
29510
- persistIssueSourceFailure(
29511
- admitted,
29512
- ticketNumber,
29513
- new DiaristIssueSourceError(
29514
- "origin-unresolved",
29515
- `bound ticket #${ticketNumber} issue face requires a resolvable github.com origin remote`
29358
+ const projectRoot = parsed.project ?? env.cwd;
29359
+ const ticketProbe = await probeInstructionTicket(
29360
+ parsed.instruction,
29361
+ projectRoot,
29362
+ env
29363
+ );
29364
+ const probedTicketNumber = ticketNumberFromProbe(ticketProbe);
29365
+ if (probedTicketNumber !== void 0) {
29366
+ const summons = {
29367
+ instruction: parsed.instruction,
29368
+ instructionEmpty: parsed.instruction.trim() === "",
29369
+ attachmentPaths: parsed.attachmentPaths
29370
+ };
29371
+ const resumed = await tryResumeSameTicketSeatRun({
29372
+ home: env.home,
29373
+ projectRoot,
29374
+ role: "diarist",
29375
+ ticketNumber: probedTicketNumber,
29376
+ freshSummons: env.freshSummons,
29377
+ summons,
29378
+ resume: (runId, materials) => runPublicDiaristResume(
29379
+ { runId, ...materials === void 0 ? {} : { summons: materials } },
29380
+ env,
29381
+ io
29516
29382
  )
29517
- );
29383
+ });
29384
+ if (resumed !== void 0) return resumed;
29518
29385
  }
29519
- const fetcher = createDiaristIssueFaceFetcher();
29520
- let face;
29386
+ let admitted;
29521
29387
  try {
29522
- face = await fetcher({
29523
- owner: origin.owner,
29524
- repo: origin.repo,
29525
- ticketNumber
29388
+ admitted = await admitDiaristInvocation({
29389
+ home: env.home,
29390
+ principalAuthority: env.principalAuthority,
29391
+ cwd: env.cwd,
29392
+ instruction: parsed.instruction,
29393
+ attachmentPaths: parsed.attachmentPaths,
29394
+ ...parsed.project === void 0 ? {} : { project: parsed.project },
29395
+ ...env.createRunId === void 0 ? {} : { createRunId: env.createRunId },
29396
+ ...env.model === void 0 ? {} : { model: env.model },
29397
+ ...env.correlationId === void 0 ? {} : { correlationId: env.correlationId }
29526
29398
  });
29527
29399
  } catch (error) {
29528
- const typed = error instanceof DiaristIssueSourceError ? error : new DiaristIssueSourceError(
29529
- "issue-unavailable",
29530
- `issue face fetch failed for ${origin.owner}/${origin.repo}#${ticketNumber}`,
29531
- { cause: error }
29532
- );
29533
- persistIssueSourceFailure(admitted, ticketNumber, typed);
29400
+ if (error instanceof CliUsageError) {
29401
+ presentStructuralRejection(error, io);
29402
+ return { exitCode: 2 };
29403
+ }
29404
+ throw error;
29534
29405
  }
29535
- if (face === void 0) {
29536
- persistIssueSourceFailure(
29537
- admitted,
29538
- ticketNumber,
29539
- new DiaristIssueSourceError(
29540
- "issue-unavailable",
29541
- `issue face unavailable for ${origin.owner}/${origin.repo}#${ticketNumber}`
29406
+ await markRunAdmitted(admitted, env.principalAuthority);
29407
+ const turnProjection = {
29408
+ packageRoot: env.packageRoot,
29409
+ home: env.home,
29410
+ agentDir: env.agentDir,
29411
+ ...env.model === void 0 ? {} : { model: env.model },
29412
+ ...env.engine === void 0 ? {} : { engine: env.engine },
29413
+ ...env.timeoutMs === void 0 ? {} : { timeoutMs: env.timeoutMs },
29414
+ ...env.correlationId === void 0 || env.correlationId.trim() === "" ? {} : { correlationId: env.correlationId },
29415
+ continuation: {
29416
+ kind: "initial",
29417
+ prompt: buildInstructionTransportPrompt(
29418
+ admitted,
29419
+ engineSessionMaterialFromOptions({
29420
+ ...env.engine === void 0 ? {} : { engine: env.engine },
29421
+ packageRoot: env.packageRoot
29422
+ })
29542
29423
  )
29543
- );
29544
- }
29545
- return face;
29424
+ }
29425
+ };
29426
+ const turnRequest = buildDiaristTurnRequest(admitted, turnProjection);
29427
+ return await runPostAdmissionOneShot({
29428
+ admitted,
29429
+ env,
29430
+ io,
29431
+ request: turnRequest,
29432
+ adapters: diaristAdapters({
29433
+ beforeDispatch: async (admittedSeat) => {
29434
+ await applyInstructionTicketProbe(admittedSeat, ticketProbe);
29435
+ const sourcesPath = await freezeDiaristSourceCatalog(admittedSeat, env);
29436
+ Object.assign(
29437
+ turnRequest,
29438
+ buildDiaristTurnRequest(admittedSeat, turnProjection, sourcesPath)
29439
+ );
29440
+ }
29441
+ }),
29442
+ ...env.engine === void 0 ? {} : { effectiveEngine: env.engine }
29443
+ });
29546
29444
  }
29547
- var init_countersign_run = __esm({
29548
- "src/public-cli/countersign-run.ts"() {
29445
+ async function runPublicDiaristResume(request, env, io) {
29446
+ return await runPostAdmissionSeatResume({
29447
+ request,
29448
+ env,
29449
+ io,
29450
+ load: (effective) => loadResumableDiaristRun(env.home, effective.runId, env.principalAuthority),
29451
+ buildTurnRequest: async (admitted, effective) => {
29452
+ const summonsPrepared = await prepareSummonsResumeMaterials(
29453
+ admitted.runDirectory,
29454
+ effective.summons
29455
+ );
29456
+ const sourcesPath = await freezeDiaristSourceCatalog(admitted, env);
29457
+ return buildDiaristTurnRequest(
29458
+ admitted,
29459
+ resumeTurnRequestProjectionOptions(
29460
+ admitted,
29461
+ effective,
29462
+ env,
29463
+ summonsPrepared
29464
+ ),
29465
+ sourcesPath
29466
+ );
29467
+ },
29468
+ adapters: diaristAdapters(),
29469
+ ...env.engine === void 0 ? {} : { effectiveEngine: env.engine }
29470
+ });
29471
+ }
29472
+ var DIARIST_SOURCE_CATALOG_FILE;
29473
+ var init_diarist_run = __esm({
29474
+ "src/public-cli/diarist-run.ts"() {
29549
29475
  "use strict";
29550
29476
  init_diarist();
29551
- init_ticket_provenance();
29552
29477
  init_engine_material();
29553
29478
  init_cli_errors();
29554
29479
  init_invocation();
29555
29480
  init_seat_ticket_binding();
29556
- init_activation_ledger_topology();
29557
29481
  init_post_admission();
29558
29482
  init_run_lifecycle();
29559
29483
  init_settlement();
29560
29484
  init_turn_request();
29485
+ DIARIST_SOURCE_CATALOG_FILE = "diarist-sources.json";
29561
29486
  }
29562
29487
  });
29563
29488
 
@@ -30374,7 +30299,7 @@ var init_judge_run = __esm({
30374
30299
  });
30375
30300
 
30376
30301
  // src/public-cli/merger-run.ts
30377
- import { mkdir as mkdir5, writeFile as writeFile9 } from "node:fs/promises";
30302
+ import { mkdir as mkdir5, writeFile as writeFile10 } from "node:fs/promises";
30378
30303
  import { join as join29, resolve as resolve10 } from "node:path";
30379
30304
  function mergerMethods(packageRoot2) {
30380
30305
  return [
@@ -30443,7 +30368,7 @@ async function admitMergerShellForActivationFailure(options) {
30443
30368
  };
30444
30369
  const admittedRequestPath = join29(runDirectory, "admitted-request.json");
30445
30370
  const mergerInputPath = join29(runDirectory, "merger-input.json");
30446
- await writeFile9(
30371
+ await writeFile10(
30447
30372
  admittedRequestPath,
30448
30373
  `${JSON.stringify(
30449
30374
  {
@@ -30881,13 +30806,13 @@ var init_analyst_book_key = __esm({
30881
30806
 
30882
30807
  // src/atomic-write.ts
30883
30808
  import { randomUUID as randomUUID6 } from "node:crypto";
30884
- import { rename, rm as rm2, writeFile as writeFile10 } from "node:fs/promises";
30809
+ import { rename, rm as rm2, writeFile as writeFile11 } from "node:fs/promises";
30885
30810
  import { dirname as dirname12, join as join30 } from "node:path";
30886
30811
  async function writeFileAtomically(destination, contents) {
30887
30812
  const parent = dirname12(destination);
30888
30813
  const temporary = join30(parent, `.atomic-write-${randomUUID6()}.tmp`);
30889
30814
  try {
30890
- await writeFile10(temporary, contents);
30815
+ await writeFile11(temporary, contents);
30891
30816
  await rename(temporary, destination);
30892
30817
  } catch (error) {
30893
30818
  await rm2(temporary, { force: true }).catch(() => void 0);
@@ -31241,7 +31166,7 @@ function isMissingPathError5(error) {
31241
31166
  function errorText3(error) {
31242
31167
  return error instanceof Error ? error.message : String(error);
31243
31168
  }
31244
- function isRecord18(value) {
31169
+ function isRecord17(value) {
31245
31170
  return typeof value === "object" && value !== null && !Array.isArray(value);
31246
31171
  }
31247
31172
  async function readExistingRunLifecycleState(runDirectory) {
@@ -31249,7 +31174,7 @@ async function readExistingRunLifecycleState(runDirectory) {
31249
31174
  const raw = JSON.parse(
31250
31175
  await readFile18(join32(runDirectory, "run-state.json"), "utf8")
31251
31176
  );
31252
- if (!isRecord18(raw) || typeof raw.state !== "string") return void 0;
31177
+ if (!isRecord17(raw) || typeof raw.state !== "string") return void 0;
31253
31178
  return raw.state;
31254
31179
  } catch {
31255
31180
  return void 0;
@@ -31285,7 +31210,7 @@ async function readInvocationScopeFields(runDirectory) {
31285
31210
  throw error;
31286
31211
  }
31287
31212
  const parsed = JSON.parse(raw);
31288
- if (!isRecord18(parsed)) return void 0;
31213
+ if (!isRecord17(parsed)) return void 0;
31289
31214
  if (typeof parsed.projectRoot !== "string" || parsed.projectRoot.trim() === "") {
31290
31215
  return void 0;
31291
31216
  }
@@ -31313,7 +31238,7 @@ async function resolveSessionFile(runDirectory) {
31313
31238
  try {
31314
31239
  const raw = await readFile18(join32(runDirectory, "invocation.json"), "utf8");
31315
31240
  const parsed = JSON.parse(raw);
31316
- if (isRecord18(parsed) && typeof parsed.sessionFile === "string" && parsed.sessionFile.trim() !== "") {
31241
+ if (isRecord17(parsed) && typeof parsed.sessionFile === "string" && parsed.sessionFile.trim() !== "") {
31317
31242
  return parsed.sessionFile;
31318
31243
  }
31319
31244
  } catch (error) {
@@ -31618,7 +31543,7 @@ var init_analyst_ledger = __esm({
31618
31543
  });
31619
31544
 
31620
31545
  // src/analyst-metric-families/acceptance-success-rework.ts
31621
- function isRecord19(value) {
31546
+ function isRecord18(value) {
31622
31547
  return typeof value === "object" && value !== null && !Array.isArray(value);
31623
31548
  }
31624
31549
  function wallMsFromSpan(span) {
@@ -31627,21 +31552,21 @@ function wallMsFromSpan(span) {
31627
31552
  function findCollectorGroups(body) {
31628
31553
  if (Array.isArray(body.groups)) return body.groups;
31629
31554
  const receipt = body.receipt;
31630
- if (isRecord19(receipt) && Array.isArray(receipt.groups)) return receipt.groups;
31555
+ if (isRecord18(receipt) && Array.isArray(receipt.groups)) return receipt.groups;
31631
31556
  const outcome = body.outcome;
31632
- if (isRecord19(outcome)) {
31557
+ if (isRecord18(outcome)) {
31633
31558
  const facts = outcome.decisiveFacts;
31634
- if (isRecord19(facts) && Array.isArray(facts.groups)) return facts.groups;
31559
+ if (isRecord18(facts) && Array.isArray(facts.groups)) return facts.groups;
31635
31560
  }
31636
31561
  return void 0;
31637
31562
  }
31638
31563
  function extractStatus(body) {
31639
31564
  const outcome = body.outcome;
31640
- if (isRecord19(outcome) && typeof outcome.status === "string" && outcome.status.trim() !== "") {
31565
+ if (isRecord18(outcome) && typeof outcome.status === "string" && outcome.status.trim() !== "") {
31641
31566
  return outcome.status;
31642
31567
  }
31643
31568
  const receipt = body.receipt;
31644
- if (isRecord19(receipt) && typeof receipt.status === "string" && receipt.status.trim() !== "") {
31569
+ if (isRecord18(receipt) && typeof receipt.status === "string" && receipt.status.trim() !== "") {
31645
31570
  return receipt.status;
31646
31571
  }
31647
31572
  if (typeof body.status === "string" && body.status.trim() !== "") {
@@ -32266,21 +32191,21 @@ var init_leg_wall_clock = __esm({
32266
32191
  });
32267
32192
 
32268
32193
  // src/analyst-metric-families/round-timeline.ts
32269
- function isRecord20(value) {
32194
+ function isRecord19(value) {
32270
32195
  return typeof value === "object" && value !== null && !Array.isArray(value);
32271
32196
  }
32272
32197
  function wallMsFromSpan2(startedAt, endedAt) {
32273
32198
  return Date.parse(endedAt) - Date.parse(startedAt);
32274
32199
  }
32275
32200
  function readOutcomeStatus(body) {
32276
- if (!isRecord20(body.outcome)) return void 0;
32201
+ if (!isRecord19(body.outcome)) return void 0;
32277
32202
  const status = body.outcome.status;
32278
32203
  if (typeof status !== "string" || status.trim() === "") return void 0;
32279
32204
  return status;
32280
32205
  }
32281
32206
  function readClassCount(body) {
32282
- if (!isRecord20(body.outcome)) return void 0;
32283
- if (!isRecord20(body.outcome.decisiveFacts)) return void 0;
32207
+ if (!isRecord19(body.outcome)) return void 0;
32208
+ if (!isRecord19(body.outcome.decisiveFacts)) return void 0;
32284
32209
  const classCount = body.outcome.decisiveFacts.classCount;
32285
32210
  if (typeof classCount !== "number" || !Number.isFinite(classCount)) {
32286
32211
  return void 0;
@@ -33012,15 +32937,15 @@ function resolveRoleTurnHost(env, options) {
33012
32937
  });
33013
32938
  const adapters = env.hostAdapters ?? [
33014
32939
  { name: "pi", create: () => ({ ok: true, host: piHost }) },
33015
- {
33016
- name: "grok-build",
32940
+ ...packagedExternalHostNames().map((name) => ({
32941
+ name,
33017
32942
  create: () => {
33018
32943
  let hostPromise;
33019
32944
  return {
33020
32945
  ok: true,
33021
32946
  host: {
33022
32947
  executeTurn: async (request) => {
33023
- hostPromise ??= loadProductionGrokHostFactory(env.packageRoot).then(
32948
+ hostPromise ??= loadProductionAcpHostFactory(env.packageRoot, name).then(
33024
32949
  (create) => create({
33025
32950
  packageRoot: env.packageRoot,
33026
32951
  principalAuthority: options.principalAuthority
@@ -33031,7 +32956,7 @@ function resolveRoleTurnHost(env, options) {
33031
32956
  }
33032
32957
  };
33033
32958
  }
33034
- }
32959
+ }))
33035
32960
  ];
33036
32961
  const hostName = options.seat.host;
33037
32962
  const adapter = adapters.find((candidate) => candidate.name === hostName);
@@ -33722,6 +33647,28 @@ async function runAkRole(argv, env) {
33722
33647
  ...result2.terminal === void 0 ? {} : { terminal: result2.terminal }
33723
33648
  };
33724
33649
  }
33650
+ if (parsed.command === "diarist") {
33651
+ const agentDir = resolveAgentDir(env, home);
33652
+ const cwd = env.cwd ?? process.cwd();
33653
+ const config = await loadAndValidateConfig(home, env.packageRoot);
33654
+ const credentials = env.credentials ?? await loadCredentialProviders(agentDir);
33655
+ const seat = resolveEffectiveSeat(
33656
+ config,
33657
+ "diarist",
33658
+ credentials,
33659
+ invocationFromParsed(parsed)
33660
+ );
33661
+ const result2 = await runPublicDiarist(
33662
+ parsed.args,
33663
+ createRoleEnvironment(env, { role: "diarist", home, agentDir, cwd, credentials, seat, config }),
33664
+ io,
33665
+ PUBLIC_ROLE_ARGV.diarist.parse
33666
+ );
33667
+ return {
33668
+ exitCode: result2.exitCode,
33669
+ ...result2.terminal === void 0 ? {} : { terminal: result2.terminal }
33670
+ };
33671
+ }
33725
33672
  if (parsed.command === "coder") {
33726
33673
  const agentDir = resolveAgentDir(env, home);
33727
33674
  const cwd = env.cwd ?? process.cwd();
@@ -33961,7 +33908,8 @@ var init_cli = __esm({
33961
33908
  init_config2();
33962
33909
  init_registry2();
33963
33910
  init_cli_errors();
33964
- init_load_production_grok_host();
33911
+ init_host_descriptions();
33912
+ init_load_production_acp_host();
33965
33913
  init_role_turn_host();
33966
33914
  init_invocation();
33967
33915
  init_option_definitions();
@@ -33969,6 +33917,7 @@ var init_cli = __esm({
33969
33917
  init_instruction_seat_run();
33970
33918
  init_collector_run();
33971
33919
  init_countersign_run();
33920
+ init_diarist_run();
33972
33921
  init_gleaner_left_run();
33973
33922
  init_doctor_run();
33974
33923
  init_fixer_run();
@@ -33996,7 +33945,8 @@ var init_cli = __esm({
33996
33945
  notary: { seat: "notary", run: runPublicNotaryResume },
33997
33946
  inspector: { seat: "inspector", run: runPublicInspectorResume },
33998
33947
  gatekeeper: { seat: "gatekeeper", run: runPublicInstructionSeatResume },
33999
- navigator: { seat: "navigator", run: runPublicInstructionSeatResume }
33948
+ navigator: { seat: "navigator", run: runPublicInstructionSeatResume },
33949
+ diarist: { seat: "diarist", run: runPublicDiaristResume }
34000
33950
  };
34001
33951
  PUBLIC_ROLE_ARGV = {
34002
33952
  judge: { parse: parseJudgeArgv, options: optionsForOwner("judge") },
@@ -34012,6 +33962,7 @@ var init_cli = __esm({
34012
33962
  reviewer: { parse: parseReviewerArgv, options: optionsForOwner("reviewer") },
34013
33963
  gatekeeper: { parse: parseGatekeeperArgv, options: optionsForOwner("gatekeeper") },
34014
33964
  navigator: { parse: parseNavigatorArgv, options: optionsForOwner("navigator") },
33965
+ diarist: { parse: parseDiaristArgv, options: optionsForOwner("diarist") },
34015
33966
  /** Deterministic analysis seat (#336) — argv parse only; no LLM admission. */
34016
33967
  analyst: { parse: parseAnalystArgv, options: optionsForOwner("analyst") }
34017
33968
  };
@@ -34029,7 +33980,7 @@ var init_cli = __esm({
34029
33980
  // src/public-cli/main.ts
34030
33981
  import { existsSync as existsSync11 } from "node:fs";
34031
33982
  import { dirname as dirname15, join as join35 } from "node:path";
34032
- import { fileURLToPath as fileURLToPath4 } from "node:url";
33983
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
34033
33984
 
34034
33985
  // src/public-cli/host-pi-runtime.ts
34035
33986
  import { existsSync, lstatSync, mkdirSync, realpathSync, rmSync, symlinkSync } from "node:fs";
@@ -34115,7 +34066,7 @@ function linkPackage(packageRoot2, name, targetDir) {
34115
34066
  }
34116
34067
 
34117
34068
  // src/public-cli/main.ts
34118
- var here = dirname15(fileURLToPath4(import.meta.url));
34069
+ var here = dirname15(fileURLToPath3(import.meta.url));
34119
34070
  function resolvePackageRoot(binDir) {
34120
34071
  const canonical = join35(binDir, "..", "..");
34121
34072
  if (existsSync11(join35(canonical, "package.json"))) {