@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
@@ -1238,9 +1238,8 @@ var init_in_process_session = __esm({
1238
1238
  }
1239
1239
  });
1240
1240
 
1241
- // src/grok/production-host.ts
1241
+ // src/acp-host/production-host.ts
1242
1242
  import { readFile as readFile15 } from "node:fs/promises";
1243
- import { join as join24 } from "node:path";
1244
1243
  import { fileURLToPath as fileURLToPath3 } from "node:url";
1245
1244
 
1246
1245
  // src/canonical-skill-binding.ts
@@ -2875,6 +2874,50 @@ function validateRecordedInspectorOutput(value) {
2875
2874
  throw new Error("Inspector output has no execution discriminator");
2876
2875
  }
2877
2876
 
2877
+ // src/diarist-contracts.ts
2878
+ var DIARIST_OUTPUT_TOOL_NAME = "ak_diarist_output";
2879
+ var DIARIST_ACCEPTED_TEXT = "\u8D77\u5C45\u90CE\u56DE\u6267\u5DF2\u63A5\u53D7";
2880
+ var DIARIST_SOURCES_FLAG = {
2881
+ name: "ak-diarist-sources",
2882
+ definition: {
2883
+ description: "Frozen per-ticket source catalog the diarist selects from",
2884
+ type: "string"
2885
+ }
2886
+ };
2887
+ function validateRecordedDiaristOutput(value) {
2888
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
2889
+ throw new Error("Diarist output has no execution discriminator");
2890
+ }
2891
+ let status;
2892
+ try {
2893
+ status = value.status;
2894
+ } catch {
2895
+ throw new Error("Diarist output has no execution discriminator");
2896
+ }
2897
+ if (status === "completed") {
2898
+ return value;
2899
+ }
2900
+ throw new Error("Diarist output has no execution discriminator");
2901
+ }
2902
+ function projectDiaristSelections(value) {
2903
+ const rows = value?.selections;
2904
+ if (!Array.isArray(rows)) return [];
2905
+ const out = [];
2906
+ for (const row of rows) {
2907
+ if (row === null || typeof row !== "object" || Array.isArray(row)) continue;
2908
+ const record4 = row;
2909
+ const index = record4.candidateIndex;
2910
+ if (typeof index !== "number" || !Number.isInteger(index) || index < 0) continue;
2911
+ const quotes = Array.isArray(record4.quotes) ? record4.quotes.filter((q) => typeof q === "string" && q.length > 0) : [];
2912
+ out.push({
2913
+ candidateIndex: index,
2914
+ quotes,
2915
+ ...typeof record4.note === "string" ? { note: record4.note } : {}
2916
+ });
2917
+ }
2918
+ return out;
2919
+ }
2920
+
2878
2921
  // src/packaged-role-registry.ts
2879
2922
  var NOTARY_SESSION_MATERIALS = [
2880
2923
  "CLAUDE.md",
@@ -3041,6 +3084,22 @@ var PUBLIC_ROLE_RECORDS = [
3041
3084
  phaseFlag: void 0,
3042
3085
  activationStage: "load-and-install",
3043
3086
  sessionMaterials: ["CLAUDE.md", "souls/navigator.md"]
3087
+ },
3088
+ // #708 / ADR 0075 `diarist-is-role`: 起居郎 is a seat like any other. The
3089
+ // frozen source catalog rides the shared input-flag seam; it is absent for a
3090
+ // true-unbound summons (no ticket → no diary).
3091
+ {
3092
+ role: "diarist",
3093
+ phases: [null],
3094
+ outputTool: DIARIST_OUTPUT_TOOL_NAME,
3095
+ inputFlag: DIARIST_SOURCES_FLAG.name,
3096
+ phaseFlag: void 0,
3097
+ activationStage: "load-and-install",
3098
+ sessionMaterials: [
3099
+ "CLAUDE.md",
3100
+ "souls/diarist.md",
3101
+ "resources/diarist-collect.md"
3102
+ ]
3044
3103
  }
3045
3104
  ];
3046
3105
  var PACKAGED_ROLE_REGISTRY = PUBLIC_ROLE_RECORDS.map(({ sessionMaterials: _omit, ...metadata }) => metadata);
@@ -3696,6 +3755,29 @@ function appendEngineSessionMaterial(lines, engineMaterial) {
3696
3755
  return out;
3697
3756
  }
3698
3757
 
3758
+ // src/host-descriptions.ts
3759
+ var PRIVATE_COMPAT_ENV = Object.fromEntries(
3760
+ ["CLAUDE", "CURSOR", "CODEX"].flatMap((vendor) => ["SKILLS", "RULES", "AGENTS", "MCPS", "HOOKS", "SESSIONS"].map((kind) => [`GROK_${vendor}_${kind}_ENABLED`, "false"]))
3761
+ );
3762
+ var HOST_DESCRIPTIONS = Object.freeze({
3763
+ /** Operator home `~/.grok`, native session/load resume, `agent [--model X] stdio`. */
3764
+ "grok-build": Object.freeze({
3765
+ binaryFromHome: Object.freeze([".grok", "bin", "grok"]),
3766
+ argv: Object.freeze({
3767
+ prefix: Object.freeze(["agent"]),
3768
+ suffix: Object.freeze(["stdio"]),
3769
+ modelFlag: "--model"
3770
+ }),
3771
+ boundResume: "session/load",
3772
+ sessionBindingFile: "grok-acp-session.json",
3773
+ childEnv: Object.freeze({
3774
+ ...PRIVATE_COMPAT_ENV,
3775
+ GROK_MEMORY: "0",
3776
+ GROK_SUBAGENTS: "0"
3777
+ })
3778
+ })
3779
+ });
3780
+
3699
3781
  // src/institutional-resolution.ts
3700
3782
  import { readFile as readFile4, writeFile as writeFile2 } from "node:fs/promises";
3701
3783
  import { join as join7 } from "node:path";
@@ -5166,7 +5248,8 @@ var TERMINATING_TOOL_NAMES = [
5166
5248
  GLEANER_LEFT_OUTPUT_TOOL_NAME,
5167
5249
  INSPECTOR_OUTPUT_TOOL_NAME,
5168
5250
  GATEKEEPER_OUTPUT_TOOL_NAME,
5169
- NAVIGATOR_OUTPUT_TOOL_NAME
5251
+ NAVIGATOR_OUTPUT_TOOL_NAME,
5252
+ DIARIST_OUTPUT_TOOL_NAME
5170
5253
  ];
5171
5254
  function isTerminatingToolName(name) {
5172
5255
  return TERMINATING_TOOL_NAMES.includes(name);
@@ -5212,7 +5295,8 @@ function validateAcceptedDetails(toolName, details) {
5212
5295
  [GLEANER_LEFT_OUTPUT_TOOL_NAME]: ["completed"],
5213
5296
  [INSPECTOR_OUTPUT_TOOL_NAME]: ["pass", "bounce"],
5214
5297
  [GATEKEEPER_OUTPUT_TOOL_NAME]: ["dispatch", "pass"],
5215
- [NAVIGATOR_OUTPUT_TOOL_NAME]: ["advice"]
5298
+ [NAVIGATOR_OUTPUT_TOOL_NAME]: ["advice"],
5299
+ [DIARIST_OUTPUT_TOOL_NAME]: ["completed"]
5216
5300
  };
5217
5301
  const collectorDiscriminator = toolName === COLLECTOR_OUTPUT_TOOL && Array.isArray(candidate?.groups);
5218
5302
  const baseDiscriminator = discriminator;
@@ -5248,6 +5332,8 @@ function validateAcceptedDetails(toolName, details) {
5248
5332
  return validateRecordedGatekeeperOutput(details);
5249
5333
  case NAVIGATOR_OUTPUT_TOOL_NAME:
5250
5334
  return validateRecordedNavigatorOutput(details);
5335
+ case DIARIST_OUTPUT_TOOL_NAME:
5336
+ return validateRecordedDiaristOutput(details);
5251
5337
  }
5252
5338
  } catch (error) {
5253
5339
  if (error instanceof Error && error.constructor === Error) throw new AcceptedDetailsContractError(error.message, { cause: error });
@@ -5265,6 +5351,7 @@ function acceptedFacts(toolName, details) {
5265
5351
  case INSPECTOR_OUTPUT_TOOL_NAME:
5266
5352
  case GATEKEEPER_OUTPUT_TOOL_NAME:
5267
5353
  case NAVIGATOR_OUTPUT_TOOL_NAME:
5354
+ case DIARIST_OUTPUT_TOOL_NAME:
5268
5355
  return { status: details.status };
5269
5356
  case JUDGE_OUTPUT_TOOL_NAME:
5270
5357
  return { status: details.judgeStatus };
@@ -6571,6 +6658,10 @@ var COUNTERSIGN_OPTIONS = [
6571
6658
  bindOwner("countersign", SHARED_PROJECT_SEMANTICS),
6572
6659
  bindOwner("countersign", SHARED_ATTACH_SEMANTICS)
6573
6660
  ];
6661
+ var DIARIST_OPTIONS = [
6662
+ bindOwner("diarist", SHARED_PROJECT_SEMANTICS),
6663
+ bindOwner("diarist", SHARED_ATTACH_SEMANTICS)
6664
+ ];
6574
6665
  var CODER_OPTIONS = [
6575
6666
  {
6576
6667
  id: "phase",
@@ -6885,6 +6976,15 @@ var ROLE_COMMAND_HELP = {
6885
6976
  'ak-role navigator "\u521A\u5B8C\u6210 coder apply \u6536\u655B\uFF0C\u4E0B\u4E00\u6B65\uFF1F"'
6886
6977
  ]
6887
6978
  },
6979
+ diarist: {
6980
+ command: "diarist",
6981
+ summary: "Direct Diarist (\u8D77\u5C45\u90CE) pass: gather and organize this case's decision basis into its \u8D77\u5C45\u5F55.",
6982
+ usage: ["ak-role diarist [options] [instruction]"],
6983
+ examples: [
6984
+ 'ak-role diarist "\u6574\u7406 #708 \u7684\u672C\u6848\u4F9D\u636E\u3002"',
6985
+ 'ak-role diarist --attach ./design.md "\u8865\u5F55\u672C\u8F6E\u8BBE\u8BA1\u4FEE\u8BA2\u3002"'
6986
+ ]
6987
+ },
6888
6988
  notary: {
6889
6989
  command: "notary",
6890
6990
  summary: "Direct Notary document check (quote fidelity + ticket alignment); zero prompt/attachment.",
@@ -7053,7 +7153,7 @@ async function readRoleRunStateDisk(runDirectory) {
7053
7153
  if (typeof record4.runId !== "string" || record4.runId.trim() === "") {
7054
7154
  return void 0;
7055
7155
  }
7056
- 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") {
7156
+ 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") {
7057
7157
  return void 0;
7058
7158
  }
7059
7159
  if (record4.state !== "admitted" && record4.state !== "running" && record4.state !== "resumable" && record4.state !== "terminal") {
@@ -11275,6 +11375,561 @@ var INSPECTOR_TOOL_SPEC = {
11275
11375
  parameters: inspectorOutputSchema
11276
11376
  };
11277
11377
 
11378
+ // src/diarist-role.ts
11379
+ import { Type as Type23 } from "typebox";
11380
+ var diaristOutputSchema = withInfrastructureFailureDeclaration(
11381
+ openToolObject(
11382
+ Type23.Object({
11383
+ status: Type23.Unknown({
11384
+ description: "completed \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8"
11385
+ }),
11386
+ selections: Type23.Array(
11387
+ Type23.Object(
11388
+ {
11389
+ candidateIndex: Type23.Number({ description: "\u5019\u9009\u76EE\u5F55\u4E2D\u7684\u6574\u5757\u5E8F\u53F7" }),
11390
+ quotes: Type23.Array(Type23.String(), {
11391
+ description: "\u8BE5\u5757 transcript \u5185\u7684\u8FDE\u7EED\u539F\u6587\uFF1B\u673A\u68B0\u53CD\u9A8C"
11392
+ }),
11393
+ note: Type23.Optional(
11394
+ Type23.String({ description: "\u8BE5\u6750\u6599\u4E0E\u672C\u6848\u7684\u5173\u7CFB\uFF08\u4EBA\u8BFB\uFF09" })
11395
+ )
11396
+ },
11397
+ { additionalProperties: true, description: "\u4E00\u6761\u5165\u5F55\u9009\u62E9" }
11398
+ ),
11399
+ { description: "\u5165\u5F55\u9009\u62E9\uFF1B\u7A7A\u5217\u8868\u5408\u6CD5\u5B8C\u5C40" }
11400
+ )
11401
+ })
11402
+ )
11403
+ );
11404
+ var DIARIST_TOOL_SPEC = {
11405
+ name: DIARIST_OUTPUT_TOOL_NAME,
11406
+ label: "\u8D77\u5C45\u90CE\u8F93\u51FA",
11407
+ description: "\u8D77\u5C45\u90CE\u5165\u5F55\u9009\u62E9\u3002",
11408
+ promptSnippet: "\u8D77\u5C45\u90CE\u5165\u5F55\u9009\u62E9",
11409
+ parameters: diaristOutputSchema
11410
+ };
11411
+
11412
+ // src/diarist.ts
11413
+ import { readFileSync as readFileSync4 } from "node:fs";
11414
+
11415
+ // src/diarist-mechanical.ts
11416
+ init_activation_ledger_topology();
11417
+ var DEFAULT_QUOTE_MIN = 6;
11418
+ function extractCornerQuotes(text, minLength = DEFAULT_QUOTE_MIN) {
11419
+ const out = [];
11420
+ const re = /「([^」]+)」/g;
11421
+ let match;
11422
+ while ((match = re.exec(text)) !== null) {
11423
+ const q = match[1].trim();
11424
+ if (q.length >= minLength) out.push(q);
11425
+ }
11426
+ return out;
11427
+ }
11428
+ function buildDiaristAnchors(input) {
11429
+ const fromBody = input.ticketBody === void 0 ? [] : extractCornerQuotes(input.ticketBody);
11430
+ const quotes = [...fromBody, ...input.extraQuotes ?? []];
11431
+ const seen = /* @__PURE__ */ new Set();
11432
+ const uniqueQuotes = [];
11433
+ for (const q of quotes) {
11434
+ if (seen.has(q)) continue;
11435
+ seen.add(q);
11436
+ uniqueQuotes.push(q);
11437
+ }
11438
+ return {
11439
+ ticketNumber: input.ticketNumber,
11440
+ quotes: uniqueQuotes
11441
+ };
11442
+ }
11443
+ function verifyQuotesVerbatim(sourceText, quotes) {
11444
+ const failed2 = [];
11445
+ for (const q of quotes) {
11446
+ if (q.length === 0) continue;
11447
+ if (!sourceText.includes(q)) failed2.push(q);
11448
+ }
11449
+ if (failed2.length === 0) return { ok: true };
11450
+ return { ok: false, failedQuotes: failed2 };
11451
+ }
11452
+ function blockToLlmEntry(block, input) {
11453
+ const verify = verifyQuotesVerbatim(block.transcript, input.quotes);
11454
+ if (!verify.ok) {
11455
+ return {
11456
+ ok: false,
11457
+ failedQuotes: verify.failedQuotes,
11458
+ cause: `verbatim verify failed: ${verify.failedQuotes.join(" | ")}`
11459
+ };
11460
+ }
11461
+ const anchorNotes = [`#${input.anchors.ticketNumber}`];
11462
+ const seen = new Set(anchorNotes);
11463
+ for (const q of [...input.anchors.quotes, ...input.quotes]) {
11464
+ if (seen.has(q)) continue;
11465
+ seen.add(q);
11466
+ anchorNotes.push(q);
11467
+ if (anchorNotes.length >= 12) break;
11468
+ }
11469
+ return {
11470
+ ok: true,
11471
+ entry: {
11472
+ basis: {
11473
+ method: "llm-semantic",
11474
+ anchors: anchorNotes,
11475
+ ...input.note === void 0 ? {} : { note: input.note }
11476
+ },
11477
+ sourceKind: block.sourceKind,
11478
+ sourceRef: block.sourceRef,
11479
+ transcript: block.transcript,
11480
+ timestamp: block.timestamp
11481
+ }
11482
+ };
11483
+ }
11484
+
11485
+ // src/ticket-provenance.ts
11486
+ import { createHash as createHash9 } from "node:crypto";
11487
+ import { appendFileSync as appendFileSync2, existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync6 } from "node:fs";
11488
+ import { join as join22 } from "node:path";
11489
+
11490
+ // src/ticket-provenance-contracts.ts
11491
+ var TICKET_PROVENANCE_KIND = "ticket-provenance";
11492
+ var TICKET_PROVENANCE_HUMAN_VIEW = "\u8D77\u5C45\u5F55.md";
11493
+ var TICKET_PROVENANCE_OFFERED_WATERMARK = "offered-identities.jsonl";
11494
+ var TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC = "diagnostic";
11495
+ function isRecord13(value) {
11496
+ return typeof value === "object" && value !== null && !Array.isArray(value);
11497
+ }
11498
+ var SOURCE_KINDS = /* @__PURE__ */ new Set([
11499
+ "cc-session",
11500
+ "issue-body-comment",
11501
+ "adr-decision-key",
11502
+ "ticket-decree-block"
11503
+ ]);
11504
+ var BASIS_METHODS = /* @__PURE__ */ new Set(["llm-semantic"]);
11505
+ var DIAGNOSTIC_KINDS = /* @__PURE__ */ new Set([
11506
+ "collector-failed",
11507
+ "issue-source-failed",
11508
+ "quote-verify-failed"
11509
+ ]);
11510
+ function projectTicketProvenanceDiagnostic(value) {
11511
+ if (!isRecord13(value)) return void 0;
11512
+ if (value.recordClass !== TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC) {
11513
+ return void 0;
11514
+ }
11515
+ if (typeof value.diagnosticKind !== "string" || !DIAGNOSTIC_KINDS.has(value.diagnosticKind)) {
11516
+ return void 0;
11517
+ }
11518
+ if (typeof value.cause !== "string" || value.cause.length === 0) {
11519
+ return void 0;
11520
+ }
11521
+ if (typeof value.recordedAt !== "string" || value.recordedAt.length === 0) {
11522
+ return void 0;
11523
+ }
11524
+ return {
11525
+ recordClass: TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC,
11526
+ diagnosticKind: value.diagnosticKind,
11527
+ cause: value.cause,
11528
+ recordedAt: value.recordedAt,
11529
+ ...typeof value.reason === "string" ? { reason: value.reason } : {}
11530
+ };
11531
+ }
11532
+ function projectTicketProvenanceEntry(value) {
11533
+ if (!isRecord13(value)) return void 0;
11534
+ if (value.recordClass === TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC) {
11535
+ return void 0;
11536
+ }
11537
+ if (!isRecord13(value.basis)) return void 0;
11538
+ if (typeof value.basis.method !== "string" || !BASIS_METHODS.has(value.basis.method)) {
11539
+ return void 0;
11540
+ }
11541
+ if (typeof value.sourceKind !== "string" || !SOURCE_KINDS.has(value.sourceKind)) {
11542
+ return void 0;
11543
+ }
11544
+ if (!isRecord13(value.sourceRef)) return void 0;
11545
+ if (typeof value.transcript !== "string" || value.transcript.length === 0) {
11546
+ return void 0;
11547
+ }
11548
+ if (typeof value.timestamp !== "string" || value.timestamp.length === 0) {
11549
+ return void 0;
11550
+ }
11551
+ const basis = {
11552
+ method: value.basis.method,
11553
+ ...Array.isArray(value.basis.anchors) ? {
11554
+ anchors: value.basis.anchors.filter(
11555
+ (item) => typeof item === "string"
11556
+ )
11557
+ } : {},
11558
+ ...typeof value.basis.note === "string" ? { note: value.basis.note } : {}
11559
+ };
11560
+ const sourceRef = {
11561
+ ...typeof value.sourceRef.sessionFile === "string" ? { sessionFile: value.sourceRef.sessionFile } : {},
11562
+ ...typeof value.sourceRef.entryId === "string" || typeof value.sourceRef.entryId === "number" ? { entryId: value.sourceRef.entryId } : {},
11563
+ ...typeof value.sourceRef.path === "string" ? { path: value.sourceRef.path } : {},
11564
+ ...typeof value.sourceRef.url === "string" ? { url: value.sourceRef.url } : {}
11565
+ };
11566
+ return {
11567
+ basis,
11568
+ sourceKind: value.sourceKind,
11569
+ sourceRef,
11570
+ transcript: value.transcript,
11571
+ timestamp: value.timestamp
11572
+ };
11573
+ }
11574
+
11575
+ // src/ticket-provenance.ts
11576
+ function ticketProvenanceSubject(ticketNumber) {
11577
+ if (!Number.isSafeInteger(ticketNumber) || ticketNumber < 1) {
11578
+ throw new Error(`ticket-provenance subject requires a positive ticket number, got ${String(ticketNumber)}`);
11579
+ }
11580
+ return String(ticketNumber);
11581
+ }
11582
+ function ticketProvenanceEntryIdentity(input) {
11583
+ const ref = input.sourceRef;
11584
+ const refKey = [
11585
+ ref.sessionFile ?? "",
11586
+ ref.entryId === void 0 ? "" : String(ref.entryId),
11587
+ ref.path ?? "",
11588
+ ref.url ?? ""
11589
+ ].join("");
11590
+ const material = [
11591
+ String(input.ticketNumber),
11592
+ input.sourceKind,
11593
+ refKey,
11594
+ input.transcript
11595
+ ].join("\0");
11596
+ return createHash9("sha256").update(material, "utf8").digest("hex");
11597
+ }
11598
+ function appendTicketProvenanceEntry(input) {
11599
+ const subject = ticketProvenanceSubject(input.ticketNumber);
11600
+ const identity = ticketProvenanceEntryIdentity({
11601
+ ticketNumber: input.ticketNumber,
11602
+ sourceKind: input.entry.sourceKind,
11603
+ sourceRef: input.entry.sourceRef,
11604
+ transcript: input.entry.transcript
11605
+ });
11606
+ return sitianReport({
11607
+ level: "event",
11608
+ kind: TICKET_PROVENANCE_KIND,
11609
+ identity,
11610
+ subject,
11611
+ cwd: input.cwd,
11612
+ ...input.home === void 0 ? {} : { home: input.home },
11613
+ host: input.host ?? "diarist",
11614
+ source: input.source ?? "diarist",
11615
+ payload: input.entry,
11616
+ raw: input.entry.sourceRef.sessionFile !== void 0 && input.entry.sourceRef.entryId !== void 0 ? {
11617
+ sessionFile: input.entry.sourceRef.sessionFile,
11618
+ entryId: input.entry.sourceRef.entryId
11619
+ } : void 0
11620
+ });
11621
+ }
11622
+ function resolveTicketProvenanceVolume(ticketNumber, cwd, home) {
11623
+ const path = resolveSitianRecordPath({
11624
+ level: "event",
11625
+ kind: TICKET_PROVENANCE_KIND,
11626
+ subject: ticketProvenanceSubject(ticketNumber),
11627
+ cwd,
11628
+ ...home === void 0 ? {} : { home }
11629
+ });
11630
+ return {
11631
+ recordFile: path.recordFile,
11632
+ volumeDir: path.sessionDir,
11633
+ humanViewFile: join22(path.sessionDir, TICKET_PROVENANCE_HUMAN_VIEW),
11634
+ offeredWatermarkFile: join22(path.sessionDir, TICKET_PROVENANCE_OFFERED_WATERMARK)
11635
+ };
11636
+ }
11637
+ var TicketProvenanceWatermarkError = class extends Error {
11638
+ code = "ticket-provenance-watermark";
11639
+ reason;
11640
+ constructor(reason, message, options) {
11641
+ super(message, options);
11642
+ this.name = "TicketProvenanceWatermarkError";
11643
+ this.reason = reason;
11644
+ }
11645
+ };
11646
+ function readOfferedIdentities(ticketNumber, cwd, home) {
11647
+ const { offeredWatermarkFile } = resolveTicketProvenanceVolume(ticketNumber, cwd, home);
11648
+ if (!existsSync7(offeredWatermarkFile)) return /* @__PURE__ */ new Set();
11649
+ let text;
11650
+ try {
11651
+ text = readFileSync3(offeredWatermarkFile, "utf8");
11652
+ } catch (error) {
11653
+ throw new TicketProvenanceWatermarkError(
11654
+ "unreadable",
11655
+ `ticket-provenance offered watermark unreadable (${offeredWatermarkFile})`,
11656
+ { cause: error }
11657
+ );
11658
+ }
11659
+ const seen = /* @__PURE__ */ new Set();
11660
+ const lines = text.split("\n");
11661
+ for (let index = 0; index < lines.length; index += 1) {
11662
+ const trimmed = lines[index].trim();
11663
+ if (!trimmed) continue;
11664
+ let parsed;
11665
+ try {
11666
+ parsed = JSON.parse(trimmed);
11667
+ } catch (error) {
11668
+ throw new TicketProvenanceWatermarkError(
11669
+ "malformed-json",
11670
+ `ticket-provenance offered watermark malformed JSON at line ${index + 1} (${offeredWatermarkFile})`,
11671
+ { cause: error }
11672
+ );
11673
+ }
11674
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed) || typeof parsed.identity !== "string" || parsed.identity.length === 0) {
11675
+ throw new TicketProvenanceWatermarkError(
11676
+ "bad-shape",
11677
+ `ticket-provenance offered watermark bad shape at line ${index + 1} (${offeredWatermarkFile})`
11678
+ );
11679
+ }
11680
+ seen.add(parsed.identity);
11681
+ }
11682
+ return seen;
11683
+ }
11684
+ function recordOfferedIdentities(input) {
11685
+ if (input.identities.length === 0) return;
11686
+ const { volumeDir, offeredWatermarkFile } = resolveTicketProvenanceVolume(
11687
+ input.ticketNumber,
11688
+ input.cwd,
11689
+ input.home
11690
+ );
11691
+ const already = new Set(readOfferedIdentities(input.ticketNumber, input.cwd, input.home));
11692
+ const rows = [];
11693
+ for (const identity of input.identities) {
11694
+ if (identity.length === 0 || already.has(identity)) continue;
11695
+ rows.push(`${JSON.stringify({ identity })}
11696
+ `);
11697
+ already.add(identity);
11698
+ }
11699
+ if (rows.length === 0) return;
11700
+ mkdirSync3(volumeDir, { recursive: true });
11701
+ appendFileSync2(offeredWatermarkFile, rows.join(""), "utf8");
11702
+ }
11703
+ async function readTicketProvenance(ticketNumber, cwd, home) {
11704
+ const { recordFile } = resolveTicketProvenanceVolume(ticketNumber, cwd, home);
11705
+ const { records: records2 } = await readSitianRecords(recordFile);
11706
+ const entries = [];
11707
+ const diagnostics = [];
11708
+ let skipped = 0;
11709
+ for (const record4 of records2) {
11710
+ if (record4.kind !== TICKET_PROVENANCE_KIND) {
11711
+ skipped += 1;
11712
+ continue;
11713
+ }
11714
+ const diagnostic = projectTicketProvenanceDiagnostic(record4.payload);
11715
+ if (diagnostic !== void 0) {
11716
+ diagnostics.push(diagnostic);
11717
+ continue;
11718
+ }
11719
+ const entry = projectTicketProvenanceEntry(record4.payload);
11720
+ if (entry === void 0) {
11721
+ skipped += 1;
11722
+ continue;
11723
+ }
11724
+ entries.push(entry);
11725
+ }
11726
+ return { entries, diagnostics, records: records2, recordFile, skipped };
11727
+ }
11728
+ function markdownFenceFor(text) {
11729
+ let longest = 0;
11730
+ const runs = text.match(/`+/g);
11731
+ if (runs !== null) {
11732
+ for (const run of runs) {
11733
+ if (run.length > longest) longest = run.length;
11734
+ }
11735
+ }
11736
+ return "`".repeat(Math.max(3, longest + 1));
11737
+ }
11738
+ function renderTicketProvenanceMarkdown(input) {
11739
+ const lines = [
11740
+ `# \u8D77\u5C45\u5F55 \xB7 #${input.ticketNumber}`,
11741
+ "",
11742
+ `\u6761\u76EE\u6570\uFF1A${input.entries.length}`,
11743
+ ""
11744
+ ];
11745
+ let index = 0;
11746
+ for (const entry of input.entries) {
11747
+ index += 1;
11748
+ lines.push(`## ${index}. ${entry.sourceKind} \xB7 ${entry.timestamp}`);
11749
+ lines.push("");
11750
+ lines.push(`- basis.method: \`${entry.basis.method}\``);
11751
+ if (entry.basis.anchors !== void 0 && entry.basis.anchors.length > 0) {
11752
+ lines.push(`- anchors: ${entry.basis.anchors.map((a) => `\`${a}\``).join(", ")}`);
11753
+ }
11754
+ if (entry.basis.note !== void 0) {
11755
+ lines.push(`- note: ${entry.basis.note}`);
11756
+ }
11757
+ const refParts = [];
11758
+ if (entry.sourceRef.sessionFile !== void 0) {
11759
+ refParts.push(`sessionFile=${entry.sourceRef.sessionFile}`);
11760
+ }
11761
+ if (entry.sourceRef.entryId !== void 0) {
11762
+ refParts.push(`entryId=${String(entry.sourceRef.entryId)}`);
11763
+ }
11764
+ if (entry.sourceRef.path !== void 0) {
11765
+ refParts.push(`path=${entry.sourceRef.path}`);
11766
+ }
11767
+ if (entry.sourceRef.url !== void 0) {
11768
+ refParts.push(`url=${entry.sourceRef.url}`);
11769
+ }
11770
+ if (refParts.length > 0) {
11771
+ lines.push(`- sourceRef: ${refParts.join(" \xB7 ")}`);
11772
+ }
11773
+ lines.push("");
11774
+ const fence = markdownFenceFor(entry.transcript);
11775
+ lines.push(fence);
11776
+ lines.push(entry.transcript);
11777
+ lines.push(fence);
11778
+ lines.push("");
11779
+ }
11780
+ return lines.join("\n");
11781
+ }
11782
+ function ensureTicketProvenanceVolume(ticketNumber, cwd, home) {
11783
+ const volume = resolveTicketProvenanceVolume(ticketNumber, cwd, home);
11784
+ mkdirSync3(volume.volumeDir, { recursive: true });
11785
+ appendFileSync2(volume.recordFile, "", "utf8");
11786
+ return volume;
11787
+ }
11788
+ function appendTicketProvenanceDiagnostic(input) {
11789
+ const subject = ticketProvenanceSubject(input.ticketNumber);
11790
+ const identityParts = input.diagnostic.diagnosticKind === "quote-verify-failed" ? [
11791
+ subject,
11792
+ input.diagnostic.recordClass,
11793
+ input.diagnostic.diagnosticKind,
11794
+ input.diagnostic.cause,
11795
+ input.diagnostic.reason ?? ""
11796
+ ] : [
11797
+ subject,
11798
+ input.diagnostic.recordClass,
11799
+ input.diagnostic.diagnosticKind,
11800
+ input.diagnostic.recordedAt,
11801
+ input.diagnostic.cause,
11802
+ input.diagnostic.reason ?? ""
11803
+ ];
11804
+ const identity = createHash9("sha256").update(identityParts.join("\0"), "utf8").digest("hex");
11805
+ return sitianReport({
11806
+ level: "event",
11807
+ kind: TICKET_PROVENANCE_KIND,
11808
+ identity,
11809
+ subject,
11810
+ cwd: input.cwd,
11811
+ ...input.home === void 0 ? {} : { home: input.home },
11812
+ host: input.host ?? "diarist",
11813
+ source: input.source ?? "diarist-diagnostic",
11814
+ payload: input.diagnostic
11815
+ });
11816
+ }
11817
+ function appendQuoteVerifyFailureDiagnostic(input) {
11818
+ const recordedAt = input.recordedAt ?? (/* @__PURE__ */ new Date()).toISOString();
11819
+ return appendTicketProvenanceDiagnostic({
11820
+ ticketNumber: input.ticketNumber,
11821
+ cwd: input.cwd,
11822
+ ...input.home === void 0 ? {} : { home: input.home },
11823
+ source: "diarist-quote-verify",
11824
+ diagnostic: {
11825
+ recordClass: TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC,
11826
+ diagnosticKind: "quote-verify-failed",
11827
+ cause: input.cause,
11828
+ recordedAt
11829
+ }
11830
+ });
11831
+ }
11832
+ function writeTicketProvenanceHumanView(input) {
11833
+ const volume = ensureTicketProvenanceVolume(input.ticketNumber, input.cwd, input.home);
11834
+ const md = renderTicketProvenanceMarkdown({
11835
+ ticketNumber: input.ticketNumber,
11836
+ entries: input.entries
11837
+ });
11838
+ writeFileSync6(volume.humanViewFile, md, "utf8");
11839
+ return volume.humanViewFile;
11840
+ }
11841
+
11842
+ // src/diarist.ts
11843
+ function blockEntryIdentity(ticketNumber, block) {
11844
+ return ticketProvenanceEntryIdentity({
11845
+ ticketNumber,
11846
+ sourceKind: block.sourceKind,
11847
+ sourceRef: block.sourceRef,
11848
+ transcript: block.transcript
11849
+ });
11850
+ }
11851
+ function loadDiaristSourceCatalog(path) {
11852
+ const parsed = JSON.parse(readFileSync4(path, "utf8"));
11853
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
11854
+ throw new Error(`diarist source catalog is not an object (${path})`);
11855
+ }
11856
+ const record4 = parsed;
11857
+ if (typeof record4.ticketNumber !== "number" || typeof record4.cwd !== "string") {
11858
+ throw new Error(`diarist source catalog is missing ticket coordinates (${path})`);
11859
+ }
11860
+ if (!Array.isArray(record4.candidates)) {
11861
+ throw new Error(`diarist source catalog is missing candidates (${path})`);
11862
+ }
11863
+ return parsed;
11864
+ }
11865
+ async function commitDiaristSelections(input) {
11866
+ const { ticketNumber, cwd } = input.catalog;
11867
+ const homeOpt = input.catalog.home === void 0 ? {} : { home: input.catalog.home };
11868
+ const volumePaths = ensureTicketProvenanceVolume(ticketNumber, cwd, input.catalog.home);
11869
+ const anchors = buildDiaristAnchors({ ticketNumber });
11870
+ const before = await readTicketProvenance(ticketNumber, cwd, input.catalog.home);
11871
+ let acceptedRows = 0;
11872
+ let rejectedQuotes = 0;
11873
+ let unknownCandidate = false;
11874
+ for (const selection of input.selections) {
11875
+ const block = input.catalog.candidates[selection.candidateIndex];
11876
+ if (block === void 0) {
11877
+ unknownCandidate = true;
11878
+ continue;
11879
+ }
11880
+ const projected = blockToLlmEntry(block, {
11881
+ anchors,
11882
+ quotes: selection.quotes,
11883
+ ...selection.note === void 0 ? {} : { note: selection.note }
11884
+ });
11885
+ if (!projected.ok) {
11886
+ rejectedQuotes += 1;
11887
+ appendQuoteVerifyFailureDiagnostic({
11888
+ ticketNumber,
11889
+ cwd,
11890
+ ...homeOpt,
11891
+ cause: projected.cause
11892
+ });
11893
+ continue;
11894
+ }
11895
+ appendTicketProvenanceEntry({
11896
+ ticketNumber,
11897
+ cwd,
11898
+ ...homeOpt,
11899
+ entry: projected.entry,
11900
+ source: "diarist"
11901
+ });
11902
+ acceptedRows += 1;
11903
+ }
11904
+ const identities = input.catalog.candidates.map(
11905
+ (block) => blockEntryIdentity(ticketNumber, block)
11906
+ );
11907
+ const alreadyWatermarked = readOfferedIdentities(ticketNumber, cwd, input.catalog.home);
11908
+ const watermarked = identities.filter((identity) => !alreadyWatermarked.has(identity)).length;
11909
+ recordOfferedIdentities({ ticketNumber, cwd, ...homeOpt, identities });
11910
+ const volume = await readTicketProvenance(ticketNumber, cwd, input.catalog.home);
11911
+ const humanViewFile = writeTicketProvenanceHumanView({
11912
+ ticketNumber,
11913
+ cwd,
11914
+ ...homeOpt,
11915
+ entries: volume.entries
11916
+ });
11917
+ return {
11918
+ ticketNumber,
11919
+ offered: input.catalog.candidates.length,
11920
+ appended: volume.entries.length - before.entries.length,
11921
+ rejectedQuotes,
11922
+ watermarked,
11923
+ volumeRecordFile: volumePaths.recordFile,
11924
+ humanViewFile,
11925
+ collectorStatus: input.catalog.candidates.length === 0 ? "skipped-no-fresh" : acceptedRows > 0 ? "ok" : input.selections.length === 0 ? "empty-selection" : "nothing-appended",
11926
+ failureCauses: [
11927
+ ...unknownCandidate ? ["unknown-candidate"] : [],
11928
+ ...rejectedQuotes > 0 ? ["quote-verify-rejected"] : []
11929
+ ]
11930
+ };
11931
+ }
11932
+
11278
11933
  // src/navigator-role.ts
11279
11934
  var NAVIGATOR_TOOL_SPEC = {
11280
11935
  name: NAVIGATOR_OUTPUT_TOOL_NAME,
@@ -11326,30 +11981,30 @@ function raceNavigatorGrace(work, graceMs = NAVIGATOR_POST_ROLE_GRACE_MS, sleep
11326
11981
  }
11327
11982
 
11328
11983
  // src/judge-role.ts
11329
- import { Type as Type23 } from "typebox";
11984
+ import { Type as Type24 } from "typebox";
11330
11985
  var judgeVerdictSchema = withInfrastructureFailureDeclaration(
11331
- Type23.Object(
11986
+ Type24.Object(
11332
11987
  {
11333
11988
  judgeStatus: stringEnum(["converged", "continue", "escalate"], { description: "converged | continue | escalate \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8" }),
11334
- fix: Type23.Optional(
11335
- Type23.Object(
11336
- { summary: Type23.String({ minLength: 1, description: "continue \u65F6\u7684\u8865\u6551\u6458\u8981" }) },
11989
+ fix: Type24.Optional(
11990
+ Type24.Object(
11991
+ { summary: Type24.String({ minLength: 1, description: "continue \u65F6\u7684\u8865\u6551\u6458\u8981" }) },
11337
11992
  { additionalProperties: false, description: "continue \u65F6\u7684\u8865\u6551\u8BF4\u660E" }
11338
11993
  )
11339
11994
  ),
11340
- classes: Type23.Optional(Type23.Array(Type23.Object({
11341
- name: Type23.String({ minLength: 1 }),
11342
- owner: Type23.String({ minLength: 1 }),
11343
- boundary: Type23.String({ minLength: 1 }),
11344
- disposition: Type23.String({ minLength: 1 })
11995
+ classes: Type24.Optional(Type24.Array(Type24.Object({
11996
+ name: Type24.String({ minLength: 1 }),
11997
+ owner: Type24.String({ minLength: 1 }),
11998
+ boundary: Type24.String({ minLength: 1 }),
11999
+ disposition: Type24.String({ minLength: 1 })
11345
12000
  }, { additionalProperties: false }), { minItems: 1, description: "\u5DF2\u88C1\u51B3 finding \u7C7B\u53CA\u5176 owner \u4E0E\u4FEE\u7406\u8FB9\u754C" })),
11346
- note: Type23.Optional(Type23.String({ minLength: 1, description: "\u53EF\u9009\u88C1\u51B3\u9644\u6CE8" })),
11347
- evidence: Type23.Optional(Type23.Unknown({ description: "\u7559\u5B58\u7684\u88C1\u51B3\u8BC1\u636E" })),
11348
- decisionGate: Type23.Optional(
11349
- Type23.Object(
12001
+ note: Type24.Optional(Type24.String({ minLength: 1, description: "\u53EF\u9009\u88C1\u51B3\u9644\u6CE8" })),
12002
+ evidence: Type24.Optional(Type24.Unknown({ description: "\u7559\u5B58\u7684\u88C1\u51B3\u8BC1\u636E" })),
12003
+ decisionGate: Type24.Optional(
12004
+ Type24.Object(
11350
12005
  {
11351
- question: Type23.String({ minLength: 1 }),
11352
- options: Type23.Array(Type23.String({ minLength: 1 }), { minItems: 1 })
12006
+ question: Type24.String({ minLength: 1 }),
12007
+ options: Type24.Array(Type24.String({ minLength: 1 }), { minItems: 1 })
11353
12008
  },
11354
12009
  { additionalProperties: false, description: "\u9700\u4EBA\u6743\u5A01\u5904\u7F6E\u7684\u95EE\u9898\u4E0E\u9009\u9879" }
11355
12010
  )
@@ -11439,7 +12094,7 @@ ${soul}
11439
12094
  }
11440
12095
 
11441
12096
  // src/reviewer-role.ts
11442
- import { Type as Type24 } from "typebox";
12097
+ import { Type as Type25 } from "typebox";
11443
12098
 
11444
12099
  // src/reviewer-execution-ledger.ts
11445
12100
  function projectAcceptedDispatch(dispatch) {
@@ -11645,19 +12300,19 @@ function assembleRuntimeReviewerReceipt(input) {
11645
12300
  }
11646
12301
 
11647
12302
  // src/reviewer-role.ts
11648
- var reviewerAmendmentsSchema = Type24.Object({
11649
- standards: Type24.Optional(Type24.String({ description: "\u76F8\u5BF9 Standards \u5B50\u62A5\u544A\u7684\u589E\u91CF\uFF1A\u589E finding\u3001\u64A4\u56DE\u6216\u4E8B\u5B9E\u66F4\u6B63" })),
11650
- spec: Type24.Optional(Type24.String({ description: "\u76F8\u5BF9 Spec \u5B50\u62A5\u544A\u7684\u589E\u91CF\uFF1A\u589E finding\u3001\u64A4\u56DE\u6216\u4E8B\u5B9E\u66F4\u6B63" }))
12303
+ var reviewerAmendmentsSchema = Type25.Object({
12304
+ standards: Type25.Optional(Type25.String({ description: "\u76F8\u5BF9 Standards \u5B50\u62A5\u544A\u7684\u589E\u91CF\uFF1A\u589E finding\u3001\u64A4\u56DE\u6216\u4E8B\u5B9E\u66F4\u6B63" })),
12305
+ spec: Type25.Optional(Type25.String({ description: "\u76F8\u5BF9 Spec \u5B50\u62A5\u544A\u7684\u589E\u91CF\uFF1A\u589E finding\u3001\u64A4\u56DE\u6216\u4E8B\u5B9E\u66F4\u6B63" }))
11651
12306
  }, { additionalProperties: true, description: "\u76F8\u5BF9\u5B50\u62A5\u544A\u7684\u53EF\u9009\u8F74\u589E\u91CF\uFF1B\u975E\u66FF\u4EE3\u62A5\u544A\u3002\u65E0\u589E\u91CF\u7684\u8F74\u53EF\u7701\u7565\u3002" });
11652
- var reviewerOutputVariants = Type24.Union([
11653
- Type24.Object({
11654
- status: Type24.Literal("completed", { description: "completed \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8" }),
11655
- amendments: Type24.Optional(reviewerAmendmentsSchema)
12307
+ var reviewerOutputVariants = Type25.Union([
12308
+ Type25.Object({
12309
+ status: Type25.Literal("completed", { description: "completed \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8" }),
12310
+ amendments: Type25.Optional(reviewerAmendmentsSchema)
11656
12311
  }, { additionalProperties: false }),
11657
- Type24.Object({
11658
- status: Type24.Literal("refused", { description: "refused \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8" }),
11659
- diagnostic: Type24.String({ minLength: 1, description: "\u62D2\u7EDD\u8BCA\u65AD\u8BF4\u660E" }),
11660
- amendments: Type24.Optional(reviewerAmendmentsSchema)
12312
+ Type25.Object({
12313
+ status: Type25.Literal("refused", { description: "refused \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8" }),
12314
+ diagnostic: Type25.String({ minLength: 1, description: "\u62D2\u7EDD\u8BCA\u65AD\u8BF4\u660E" }),
12315
+ amendments: Type25.Optional(reviewerAmendmentsSchema)
11661
12316
  }, { additionalProperties: false })
11662
12317
  ]);
11663
12318
  var reviewerOutputSchema = withInfrastructureFailureDeclaration(
@@ -11785,12 +12440,12 @@ function createReviewerRoleRuntime(pi, dependencies, hostActions) {
11785
12440
  }
11786
12441
 
11787
12442
  // src/worker-role.ts
11788
- import { Type as Type25 } from "typebox";
12443
+ import { Type as Type26 } from "typebox";
11789
12444
 
11790
12445
  // src/worker-submission-gates.ts
11791
12446
  init_archivist_record_entry();
11792
12447
  import { execFileSync as execFileSync2 } from "node:child_process";
11793
- import { existsSync as existsSync7, lstatSync as lstatSync3, readdirSync as readdirSync2, readFileSync as readFileSync3, rmdirSync, rmSync } from "node:fs";
12448
+ import { existsSync as existsSync8, lstatSync as lstatSync3, readdirSync as readdirSync2, readFileSync as readFileSync5, rmdirSync, rmSync } from "node:fs";
11794
12449
  import { resolve as resolve16 } from "node:path";
11795
12450
  var WORKER_SUBMISSION_GATE_RECORD_KIND = WORKER_SUBMISSION_GATE_KIND;
11796
12451
  var WORKER_COMMIT_BASELINE_ENTRY_TYPE = "commit-baseline";
@@ -11821,7 +12476,7 @@ function statusOf(error) {
11821
12476
  return typeof error === "object" && error !== null && "status" in error ? error.status : void 0;
11822
12477
  }
11823
12478
  function tryGetAll(file, key) {
11824
- if (!existsSync7(file)) return [];
12479
+ if (!existsSync8(file)) return [];
11825
12480
  try {
11826
12481
  const out = gitFile(file, ["--get-all", key]);
11827
12482
  return out.length === 0 ? [] : out.split("\n");
@@ -11831,8 +12486,8 @@ function tryGetAll(file, key) {
11831
12486
  }
11832
12487
  }
11833
12488
  function ownedHook(path) {
11834
- if (!existsSync7(path)) return false;
11835
- return readFileSync3(path, "utf8").includes(HOOK_MARKER);
12489
+ if (!existsSync8(path)) return false;
12490
+ return readFileSync5(path, "utf8").includes(HOOK_MARKER);
11836
12491
  }
11837
12492
  function escapeGitConfigValueRegex(value) {
11838
12493
  return value.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&");
@@ -11858,11 +12513,11 @@ function rmOwnedDir(dir) {
11858
12513
  const hookPath = resolve16(dir, HOOK_FILE);
11859
12514
  if (!ownedHook(hookPath)) return;
11860
12515
  rmSync(hookPath, { force: true });
11861
- if (existsSync7(dir) && readdirSync2(dir).length === 0) rmdirSync(dir);
12516
+ if (existsSync8(dir) && readdirSync2(dir).length === 0) rmdirSync(dir);
11862
12517
  }
11863
12518
  function linkedGitDirs(commonDir) {
11864
12519
  const root = resolve16(commonDir, "worktrees");
11865
- if (!existsSync7(root)) return [];
12520
+ if (!existsSync8(root)) return [];
11866
12521
  return readdirSync2(root).map((name) => resolve16(root, name)).filter((dir) => lstatSync3(dir).isDirectory());
11867
12522
  }
11868
12523
  function uninstallPackageWorkerHooks(cwd) {
@@ -11887,7 +12542,7 @@ function uninstallPackageWorkerHooks(cwd) {
11887
12542
  rmOwnedDir(resolve16(gitDir, HOOKS_DIR));
11888
12543
  }
11889
12544
  }
11890
- function isRecord13(value) {
12545
+ function isRecord14(value) {
11891
12546
  return typeof value === "object" && value !== null && !Array.isArray(value);
11892
12547
  }
11893
12548
  function unfinishedReasonPresent(details) {
@@ -11903,7 +12558,7 @@ function readGateState(session) {
11903
12558
  if (entry.type !== "custom") continue;
11904
12559
  if (entry.customType === WORKER_COMMIT_BASELINE_ENTRY_TYPE) {
11905
12560
  const data = entry.data;
11906
- if (isRecord13(data) && (data.head === null || typeof data.head === "string")) {
12561
+ if (isRecord14(data) && (data.head === null || typeof data.head === "string")) {
11907
12562
  baseline = data.head;
11908
12563
  }
11909
12564
  } else if (entry.customType === WORKER_COMMIT_REMINDER_BOUNCE_ENTRY_TYPE) {
@@ -12046,24 +12701,24 @@ function fixerBashSeatbeltDenyReason(matched) {
12046
12701
  }
12047
12702
 
12048
12703
  // src/worker-role.ts
12049
- var coderOutputVariants = Type25.Union([
12050
- Type25.Object({
12704
+ var coderOutputVariants = Type26.Union([
12705
+ Type26.Object({
12051
12706
  status: stringEnum(["planned"], { description: "planned \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8" }),
12052
- report: Type25.String({ minLength: 1, description: "\u5982\u5B9E\u7ED3\u679C\u62A5\u544A" })
12707
+ report: Type26.String({ minLength: 1, description: "\u5982\u5B9E\u7ED3\u679C\u62A5\u544A" })
12053
12708
  }, { additionalProperties: false }),
12054
- Type25.Object({
12709
+ Type26.Object({
12055
12710
  status: stringEnum(["completed", "refused"], {
12056
12711
  description: "completed | refused \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8\uFF1Bcompleted \u56DE\u6267\u542B TDD\u3001\u540C\u6A21\u5F0F\u3001\u5F15\u5165\u56DE\u5F52\u3001\u884C\u4E3A\u4E8B\u5B9E\u56DB\u9879\u8BC1\u636E"
12057
12712
  }),
12058
- report: Type25.String({ minLength: 1, description: "\u5982\u5B9E\u7ED3\u679C\u62A5\u544A" })
12713
+ report: Type26.String({ minLength: 1, description: "\u5982\u5B9E\u7ED3\u679C\u62A5\u544A" })
12059
12714
  }, { additionalProperties: false }),
12060
- Type25.Object({
12715
+ Type26.Object({
12061
12716
  status: stringEnum(["unfinished"], {
12062
12717
  description: "unfinished \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8\uFF1B\u7F3A\u524D\u7F6E\u6216\u8FDD\u5BAA\u7EA6\u675F\u81F4\u672C\u5C40\u672A\u5B8C\u6210\u65F6\u53EF\u7528\u3002\u7F3A\u5F85\u51B3 owner \u51B3\u5B9A\u6216\u7B54\u590D\u5C5E\u7F3A\u524D\u7F6E\u3002"
12063
12718
  }),
12064
- report: Type25.String({ minLength: 1, description: "\u5982\u5B9E\u7ED3\u679C\u62A5\u544A" }),
12065
- remainingScope: Type25.String({ minLength: 1, description: "\u672C\u5C40\u540E\u5269\u4F59\u5DE5\u4F5C" }),
12066
- reason: Type25.Optional(Type25.String({
12719
+ report: Type26.String({ minLength: 1, description: "\u5982\u5B9E\u7ED3\u679C\u62A5\u544A" }),
12720
+ remainingScope: Type26.String({ minLength: 1, description: "\u672C\u5C40\u540E\u5269\u4F59\u5DE5\u4F5C" }),
12721
+ reason: Type26.Optional(Type26.String({
12067
12722
  minLength: 1,
12068
12723
  description: "\u963B\u65AD\u539F\u56E0\uFF1A\u7F3A\u524D\u7F6E\u6216\u8FDD\u5BAA\u7EA6\u675F\u3002\u7F3A\u5F85\u51B3 owner \u51B3\u5B9A\u6216\u7B54\u590D\u5C5E\u7F3A\u524D\u7F6E\u3002"
12069
12724
  }))
@@ -12534,6 +13189,12 @@ var GLEANER_LEFT_TRANSPORT_FLAGS = Object.freeze([
12534
13189
  definition: GLEANER_LEFT_BASE_FLAG.definition
12535
13190
  })
12536
13191
  ]);
13192
+ var DIARIST_TRANSPORT_FLAGS = Object.freeze([
13193
+ Object.freeze({
13194
+ name: DIARIST_SOURCES_FLAG.name,
13195
+ definition: DIARIST_SOURCES_FLAG.definition
13196
+ })
13197
+ ]);
12537
13198
  function decodeReviewerAdmittedInputs(getFlag) {
12538
13199
  let reviewScopeKeys;
12539
13200
  const rawScopeKeys = getFlag("ak-review-scope-keys");
@@ -12651,6 +13312,8 @@ function activationStage(role, runtime) {
12651
13312
  return { id: "load-and-install", run: async () => runtime.gatekeeper.activate() };
12652
13313
  case "navigator":
12653
13314
  return { id: "load-and-install", run: async () => runtime.navigator.activate() };
13315
+ case "diarist":
13316
+ return { id: "load-and-install", run: async () => runtime.diarist.activate() };
12654
13317
  case "merger":
12655
13318
  return { id: "prepare-git-and-install", run: async () => runtime.merger() };
12656
13319
  }
@@ -12788,12 +13451,10 @@ function createFiledOfficerRuntime(roleHost, spec, dependencies) {
12788
13451
  parameters: spec.tool.parameters,
12789
13452
  async execute(toolCallId, parameters, signal, _onUpdate, ctx) {
12790
13453
  if (soul === void 0) throw new Error(`${spec.role} \u804C\u5206\u672A\u88C5\u8F7D`);
12791
- if (spec.beforeAccept !== void 0) {
12792
- await spec.beforeAccept({ toolCallId, parameters, signal, ctx });
12793
- }
13454
+ const projected = spec.beforeAccept === void 0 ? void 0 : await spec.beforeAccept({ toolCallId, parameters, signal, ctx });
12794
13455
  return {
12795
13456
  content: [{ type: "text", text: spec.acceptedText }],
12796
- details: parameters,
13457
+ details: projected === void 0 ? parameters : projected,
12797
13458
  terminate: true
12798
13459
  };
12799
13460
  }
@@ -12870,6 +13531,47 @@ function createNavigatorRoleRuntime(roleHost, dependencies) {
12870
13531
  dependencies
12871
13532
  );
12872
13533
  }
13534
+ function createDiaristRoleRuntime(roleHost, dependencies, getSourcesFlag) {
13535
+ let catalog;
13536
+ const runtime = createFiledOfficerRuntime(
13537
+ roleHost,
13538
+ {
13539
+ role: "diarist",
13540
+ tool: DIARIST_TOOL_SPEC,
13541
+ acceptedText: DIARIST_ACCEPTED_TEXT,
13542
+ soulTag: "diarist",
13543
+ beforeAccept: async ({ parameters }) => {
13544
+ const submitted = parameters !== null && typeof parameters === "object" && !Array.isArray(parameters) ? parameters : void 0;
13545
+ if (catalog === void 0) {
13546
+ if (submitted === void 0 || !("sitian" in submitted)) return void 0;
13547
+ const stripped = { ...submitted };
13548
+ delete stripped.sitian;
13549
+ return stripped;
13550
+ }
13551
+ const facts = await commitDiaristSelections({
13552
+ catalog,
13553
+ selections: projectDiaristSelections(parameters)
13554
+ });
13555
+ return { ...submitted ?? { receipt: parameters }, sitian: facts };
13556
+ }
13557
+ },
13558
+ dependencies
13559
+ );
13560
+ return {
13561
+ async activate() {
13562
+ catalog = loadFrozenDiaristCatalog(getSourcesFlag);
13563
+ return runtime.activate();
13564
+ }
13565
+ };
13566
+ }
13567
+ function loadFrozenDiaristCatalog(getFlag) {
13568
+ const raw = getFlag();
13569
+ if (raw === void 0) return void 0;
13570
+ if (typeof raw !== "string" || raw.trim() === "") {
13571
+ throw new Error("Diarist source catalog flag must be a nonempty path");
13572
+ }
13573
+ return loadDiaristSourceCatalog(raw);
13574
+ }
12873
13575
  function createCountersignRoleRuntime(roleHost, dependencies, hostActions) {
12874
13576
  const beforeAccept = hostActions !== void 0 && roleHost.requireGatekeeperPass !== void 0 ? async ({ toolCallId, signal, ctx }) => {
12875
13577
  await roleHost.requireGatekeeperPass({
@@ -12913,6 +13615,9 @@ function createRoleRuntimeExtension(dependencies) {
12913
13615
  for (const flag of GLEANER_LEFT_TRANSPORT_FLAGS) {
12914
13616
  roleHost.registerFlag(flag.name, flag.definition);
12915
13617
  }
13618
+ for (const flag of DIARIST_TRANSPORT_FLAGS) {
13619
+ roleHost.registerFlag(flag.name, flag.definition);
13620
+ }
12916
13621
  let admitted = false;
12917
13622
  let selectedRole;
12918
13623
  let activeReviewerParent;
@@ -13303,6 +14008,16 @@ function createRoleRuntimeExtension(dependencies) {
13303
14008
  return dependencies.loadNavigatorSoul();
13304
14009
  }
13305
14010
  });
14011
+ const diarist = createDiaristRoleRuntime(
14012
+ roleHost,
14013
+ {
14014
+ async loadSoul() {
14015
+ if (!dependencies.loadDiaristSoul) throw new Error("Diarist runtime dependencies are not configured");
14016
+ return dependencies.loadDiaristSoul();
14017
+ }
14018
+ },
14019
+ () => envelopeHost.host.getFlag(DIARIST_SOURCES_FLAG.name)
14020
+ );
13306
14021
  let sessionMergerGitState = dependencies.mergerGitState;
13307
14022
  const merger = createMergerRoleRuntime(roleHost, {
13308
14023
  async loadSoul() {
@@ -13455,6 +14170,7 @@ function createRoleRuntimeExtension(dependencies) {
13455
14170
  inspector,
13456
14171
  gatekeeper,
13457
14172
  navigator,
14173
+ diarist,
13458
14174
  merger: async () => {
13459
14175
  if (dependencies.mergerGitState === void 0) {
13460
14176
  sessionMergerGitState = dependencies.createMergerGitState?.(ctx.cwd);
@@ -13564,14 +14280,30 @@ function createRoleRuntimeExtension(dependencies) {
13564
14280
  };
13565
14281
  }
13566
14282
 
13567
- // src/grok/role-envelope.ts
14283
+ // src/acp-host/description.ts
14284
+ import { join as join23 } from "node:path";
14285
+ function resolveAcpBinary(description, operatorHome) {
14286
+ return join23(operatorHome, ...description.binaryFromHome);
14287
+ }
14288
+ function acpStdioArgs(description, model) {
14289
+ const { prefix, suffix, modelFlag, thinkingFlag } = description.argv;
14290
+ const pair = (flag, value) => flag === void 0 || value === void 0 ? [] : [flag, value];
14291
+ return [
14292
+ ...prefix,
14293
+ ...pair(modelFlag, model?.model),
14294
+ ...pair(thinkingFlag, model?.thinking),
14295
+ ...suffix
14296
+ ];
14297
+ }
14298
+
14299
+ // src/acp-host/role-envelope.ts
13568
14300
  import { randomUUID as randomUUID2 } from "node:crypto";
13569
14301
  import { mkdir as mkdir3, readFile as readFile13, writeFile as writeFile7 } from "node:fs/promises";
13570
14302
  import { createServer } from "node:net";
13571
- import { basename as basename7, dirname as dirname15, join as join22 } from "node:path";
14303
+ import { basename as basename7, dirname as dirname15, join as join24 } from "node:path";
13572
14304
  import { fileURLToPath as fileURLToPath2 } from "node:url";
13573
14305
 
13574
- // src/grok/role-turn-host.ts
14306
+ // src/acp-host/role-turn-host.ts
13575
14307
  import { spawn as spawn4 } from "node:child_process";
13576
14308
  import { createInterface } from "node:readline";
13577
14309
 
@@ -13581,8 +14313,8 @@ function renderAgentStartMaterials(body, materials) {
13581
14313
  return [body, ...materials.map((material) => JSON.stringify(material))].join("\n\n");
13582
14314
  }
13583
14315
 
13584
- // src/grok/role-turn-host.ts
13585
- function renderGrokSystemPromptOverride(authority) {
14316
+ // src/acp-host/role-turn-host.ts
14317
+ function renderAcpSystemPromptOverride(authority) {
13586
14318
  return renderAgentStartMaterials(authority.body, authority.materials);
13587
14319
  }
13588
14320
  function failure(cause, name, code, details) {
@@ -13598,19 +14330,13 @@ function failure(cause, name, code, details) {
13598
14330
  };
13599
14331
  }
13600
14332
  function hostAbortedError() {
13601
- return Object.assign(new Error("Grok host aborted"), { code: "host-aborted" });
14333
+ return Object.assign(new Error("ACP host aborted"), { code: "host-aborted" });
13602
14334
  }
13603
14335
  function acpError(code, message, cause) {
13604
14336
  return Object.assign(new Error(message, cause === void 0 ? void 0 : { cause }), { code });
13605
14337
  }
13606
- function connectGrokAcpStdio(options) {
13607
- const args = [
13608
- "agent",
13609
- ...options.model === void 0 ? [] : ["--model", options.model],
13610
- "stdio"
13611
- ];
13612
- const env = options.toolset === void 0 ? options.env : { ...options.env, GROK_CONFIG: JSON.stringify({ toolset: options.toolset }) };
13613
- const child = spawn4(options.binary, args, { cwd: options.cwd, env, stdio: ["pipe", "pipe", "pipe"] });
14338
+ function connectAcpStdio(options) {
14339
+ const child = spawn4(options.binary, [...options.args], { cwd: options.cwd, env: options.env, stdio: ["pipe", "pipe", "pipe"] });
13614
14340
  const pending = /* @__PURE__ */ new Map();
13615
14341
  const notificationHandlers = [];
13616
14342
  if (options.onNotification !== void 0) notificationHandlers.push(options.onNotification);
@@ -13633,13 +14359,13 @@ function connectGrokAcpStdio(options) {
13633
14359
  child.stderr.setEncoding("utf8").on("data", (chunk) => {
13634
14360
  stderr += chunk;
13635
14361
  });
13636
- child.on("error", (error) => settleClosed(acpError("acp-process-error", `Grok ACP process error: ${error.message}`, error)));
14362
+ child.on("error", (error) => settleClosed(acpError("acp-process-error", `ACP process error: ${error.message}`, error)));
13637
14363
  createInterface({ input: child.stdout }).on("line", (line2) => {
13638
14364
  let message;
13639
14365
  try {
13640
14366
  message = JSON.parse(line2);
13641
14367
  } catch (error) {
13642
- terminate(acpError("acp-invalid-json", `Invalid Grok ACP JSON: ${String(error)}`, error));
14368
+ terminate(acpError("acp-invalid-json", `Invalid ACP JSON: ${String(error)}`, error));
13643
14369
  return;
13644
14370
  }
13645
14371
  if (typeof message.method === "string") {
@@ -13647,13 +14373,13 @@ function connectGrokAcpStdio(options) {
13647
14373
  for (const handler of notificationHandlers) handler(message.method, params);
13648
14374
  if (typeof message.id === "number") {
13649
14375
  if (message.method !== "session/request_permission") {
13650
- terminate(acpError("acp-unsupported-client-request", `Unsupported Grok ACP client request: ${message.method}`));
14376
+ terminate(acpError("acp-unsupported-client-request", `Unsupported ACP client request: ${message.method}`));
13651
14377
  return;
13652
14378
  }
13653
14379
  const choices = Array.isArray(params.options) ? params.options : [];
13654
14380
  const selected = choices.find((value) => typeof value === "object" && value !== null && value.kind === "allow_once");
13655
14381
  if (typeof selected?.optionId !== "string") {
13656
- terminate(acpError("acp-permission-missing-allow-once", "Grok ACP permission request omitted allow_once"));
14382
+ terminate(acpError("acp-permission-missing-allow-once", "ACP permission request omitted allow_once"));
13657
14383
  return;
13658
14384
  }
13659
14385
  child.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", id: message.id, result: { outcome: { outcome: "selected", optionId: selected.optionId } } })}
@@ -13665,13 +14391,13 @@ function connectGrokAcpStdio(options) {
13665
14391
  const waiter = pending.get(message.id);
13666
14392
  if (waiter === void 0) return;
13667
14393
  pending.delete(message.id);
13668
- if (message.error !== void 0) waiter.reject(acpError("acp-upstream-error", `Grok ACP error: ${JSON.stringify(message.error)}`));
14394
+ if (message.error !== void 0) waiter.reject(acpError("acp-upstream-error", `ACP error: ${JSON.stringify(message.error)}`));
13669
14395
  else waiter.resolve(message.result ?? {});
13670
14396
  });
13671
- child.on("close", (code) => settleClosed(acpError("acp-closed", `Grok ACP closed (${String(code)}): ${stderr}`)));
14397
+ child.on("close", (code) => settleClosed(acpError("acp-closed", `ACP closed (${String(code)}): ${stderr}`)));
13672
14398
  return Promise.resolve({
13673
14399
  request(method, params) {
13674
- if (closed) return Promise.reject(terminalError ?? acpError("acp-connection-closed", "Grok ACP connection is closed"));
14400
+ if (closed) return Promise.reject(terminalError ?? acpError("acp-connection-closed", "ACP connection is closed"));
13675
14401
  const id = ++nextId;
13676
14402
  return new Promise((resolve17, reject) => {
13677
14403
  pending.set(id, { resolve: resolve17, reject });
@@ -13681,12 +14407,12 @@ function connectGrokAcpStdio(options) {
13681
14407
  const waiter = pending.get(id);
13682
14408
  if (waiter === void 0) return;
13683
14409
  pending.delete(id);
13684
- waiter.reject(acpError("acp-write-failed", `Grok ACP write failed: ${error.message}`, error));
14410
+ waiter.reject(acpError("acp-write-failed", `ACP write failed: ${error.message}`, error));
13685
14411
  });
13686
14412
  });
13687
14413
  },
13688
14414
  notify(method, params) {
13689
- if (closed) throw terminalError ?? acpError("acp-connection-closed", "Grok ACP connection is closed");
14415
+ if (closed) throw terminalError ?? acpError("acp-connection-closed", "ACP connection is closed");
13690
14416
  child.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", method, params })}
13691
14417
  `);
13692
14418
  },
@@ -13695,14 +14421,14 @@ function connectGrokAcpStdio(options) {
13695
14421
  },
13696
14422
  async close() {
13697
14423
  if (closed) return;
13698
- settleClosed(acpError("acp-connection-closed", "Grok ACP connection is closed"));
14424
+ settleClosed(acpError("acp-connection-closed", "ACP connection is closed"));
13699
14425
  child.stdin.end();
13700
14426
  child.kill("SIGTERM");
13701
14427
  await new Promise((resolve17) => child.once("close", () => resolve17()));
13702
14428
  }
13703
14429
  });
13704
14430
  }
13705
- function createGrokRoleTurnHost(config) {
14431
+ function createAcpRoleTurnHost(config) {
13706
14432
  let serial = Promise.resolve();
13707
14433
  return {
13708
14434
  executeTurn(request) {
@@ -13714,7 +14440,7 @@ function createGrokRoleTurnHost(config) {
13714
14440
  let accepted = false;
13715
14441
  try {
13716
14442
  if (prepared.mcpServers.length === 0) {
13717
- return failure("activation", "UncontrolledGrokSession", "ak-config-missing");
14443
+ return failure("activation", "UncontrolledAcpSession", "ak-config-missing");
13718
14444
  }
13719
14445
  connection = await config.connect(request);
13720
14446
  const initialized = await connection.request("initialize", {
@@ -13725,49 +14451,36 @@ function createGrokRoleTurnHost(config) {
13725
14451
  const modelState = initializeMeta?.modelState;
13726
14452
  const availableModels = Array.isArray(modelState?.availableModels) ? modelState.availableModels : void 0;
13727
14453
  if (request.model !== void 0 && availableModels !== void 0 && !availableModels.some((entry) => typeof entry === "object" && entry !== null && entry.modelId === request.model?.model)) {
13728
- return failure("activation", "GrokHostModelMismatch", "host-model-mismatch", {
14454
+ return failure("activation", "AcpHostModelMismatch", "host-model-mismatch", {
13729
14455
  provider: request.model.provider,
13730
14456
  model: request.model.model
13731
14457
  });
13732
14458
  }
13733
- const priorNativePaths = continuation.kind === "resume" && request.hostTransition?.previousHost === "pi" ? request.hostTransition.priorNativePaths : void 0;
13734
- if (continuation.kind === "resume") {
14459
+ const priorNativePaths = continuation.kind === "resume" ? request.hostTransition?.priorNativePaths : void 0;
14460
+ if (continuation.kind === "resume" && config.boundResume === "session/load") {
13735
14461
  const boundSessionId = await config.sessionIdentity.load(request.principal);
13736
14462
  if (boundSessionId !== void 0 && boundSessionId !== "") {
13737
14463
  const loaded = await connection.request("session/load", {
13738
14464
  sessionId: boundSessionId,
13739
14465
  cwd: request.cwd,
13740
14466
  mcpServers: prepared.mcpServers,
13741
- _meta: { systemPromptOverride: renderGrokSystemPromptOverride(prepared.systemPrompt), yoloMode: false }
14467
+ _meta: { systemPromptOverride: renderAcpSystemPromptOverride(prepared.systemPrompt), yoloMode: false }
13742
14468
  });
13743
14469
  sessionId = typeof loaded.sessionId === "string" && loaded.sessionId !== "" ? loaded.sessionId : boundSessionId;
13744
- } else {
13745
- const session = await connection.request(
13746
- "session/new",
13747
- {
13748
- cwd: request.cwd,
13749
- mcpServers: prepared.mcpServers,
13750
- _meta: { systemPromptOverride: renderGrokSystemPromptOverride(prepared.systemPrompt), yoloMode: false }
13751
- }
13752
- );
13753
- sessionId = typeof session.sessionId === "string" ? session.sessionId : void 0;
13754
- if (sessionId === void 0 || sessionId === "") {
13755
- return failure("session", "GrokAcpSessionFailure", "session-id-missing");
13756
- }
13757
- await config.sessionIdentity.bind(request.principal, sessionId);
13758
14470
  }
13759
- } else {
14471
+ }
14472
+ if (sessionId === void 0) {
13760
14473
  const session = await connection.request(
13761
14474
  "session/new",
13762
14475
  {
13763
14476
  cwd: request.cwd,
13764
14477
  mcpServers: prepared.mcpServers,
13765
- _meta: { systemPromptOverride: renderGrokSystemPromptOverride(prepared.systemPrompt), yoloMode: false }
14478
+ _meta: { systemPromptOverride: renderAcpSystemPromptOverride(prepared.systemPrompt), yoloMode: false }
13766
14479
  }
13767
14480
  );
13768
14481
  sessionId = typeof session.sessionId === "string" ? session.sessionId : void 0;
13769
14482
  if (sessionId === void 0 || sessionId === "") {
13770
- return failure("session", "GrokAcpSessionFailure", "session-id-missing");
14483
+ return failure("session", "AcpSessionFailure", "session-id-missing");
13771
14484
  }
13772
14485
  await config.sessionIdentity.bind(request.principal, sessionId);
13773
14486
  }
@@ -13828,7 +14541,7 @@ ${priorNativePaths.join("\n")}` : prepared.prompt;
13828
14541
  throw error;
13829
14542
  }
13830
14543
  if (result2.stopReason === "refusal") {
13831
- return failure("output", "GrokAcpRefusal", "refusal", { sessionId });
14544
+ return failure("output", "AcpRefusal", "refusal", { sessionId });
13832
14545
  }
13833
14546
  const closure = await prepared.closeRound();
13834
14547
  if (closure.accepted) {
@@ -13841,7 +14554,7 @@ ${priorNativePaths.join("\n")}` : prepared.prompt;
13841
14554
  }
13842
14555
  prompt = `The prior terminal submission was rejected (${closure.retry.code}). Resubmit it as the sole terminal tool call. Rejected call ids: ${closure.retry.toolCallIds.join(", ") || "none"}.`;
13843
14556
  }
13844
- return failure("output", "GrokAcpRoundLimit", "round-retry-limit", { sessionId });
14557
+ return failure("output", "AcpRoundLimit", "round-retry-limit", { sessionId });
13845
14558
  } finally {
13846
14559
  if (connection !== void 0) {
13847
14560
  if (sessionId !== void 0 && !accepted) {
@@ -13866,25 +14579,14 @@ ${priorNativePaths.join("\n")}` : prepared.prompt;
13866
14579
  }
13867
14580
  };
13868
14581
  }
13869
- var PRIVATE_COMPAT_ENV = Object.fromEntries(
13870
- ["CLAUDE", "CURSOR", "CODEX"].flatMap((vendor) => ["SKILLS", "RULES", "AGENTS", "MCPS", "HOOKS", "SESSIONS"].map((kind) => [`GROK_${vendor}_${kind}_ENABLED`, "false"]))
13871
- );
13872
- function controlledGrokChildEnv(base) {
13873
- return {
13874
- ...base,
13875
- ...PRIVATE_COMPAT_ENV,
13876
- GROK_MEMORY: "0",
13877
- GROK_SUBAGENTS: "0"
13878
- };
13879
- }
13880
14582
 
13881
- // src/grok/role-envelope.ts
14583
+ // src/acp-host/role-envelope.ts
13882
14584
  function parseCanonicalSkillInvocation(prompt) {
13883
14585
  const match = /^\/skill:([A-Za-z0-9_-]+)(?:\s+([\s\S]*))?$/s.exec(prompt.trim());
13884
14586
  if (match === null) return void 0;
13885
14587
  return { name: match[1], userMessage: (match[2] ?? "").trim() };
13886
14588
  }
13887
- function buildGrokSkillExpansion(methodSkills, prompt) {
14589
+ function buildAcpSkillExpansion(methodSkills, prompt) {
13888
14590
  const parsed = parseCanonicalSkillInvocation(prompt);
13889
14591
  if (parsed === void 0) return void 0;
13890
14592
  const method = methodSkills.get(parsed.name);
@@ -13898,14 +14600,14 @@ ${method.body}`,
13898
14600
  userMessage: parsed.userMessage
13899
14601
  });
13900
14602
  }
13901
- function projectGrokActivationFlags(request) {
14603
+ function projectAcpActivationFlags(request) {
13902
14604
  const activation = request.activation;
13903
14605
  const flags = /* @__PURE__ */ new Map([["ak-role", activation.role]]);
13904
14606
  const inputFlag = packagedRoleInputFlag(activation.role);
13905
14607
  const phaseFlag = packagedRolePhaseFlag(activation.role);
13906
14608
  if ("phase" in activation && phaseFlag !== void 0) flags.set(phaseFlag, activation.phase);
13907
14609
  if (inputFlag !== void 0) {
13908
- const path = "taskPath" in activation ? activation.taskPath : "packetPath" in activation ? activation.packetPath : "casePath" in activation ? activation.casePath : "inputPath" in activation ? activation.inputPath : "sourceRun" in activation ? activation.sourceRun : void 0;
14610
+ const path = "taskPath" in activation ? activation.taskPath : "packetPath" in activation ? activation.packetPath : "casePath" in activation ? activation.casePath : "inputPath" in activation ? activation.inputPath : "sourceRun" in activation ? activation.sourceRun : "sourcesPath" in activation ? activation.sourcesPath : void 0;
13909
14611
  if (path !== void 0) flags.set(inputFlag, path);
13910
14612
  }
13911
14613
  if (activation.role === "fixer" && activation.prerequisitesPath !== void 0) flags.set("ak-fixer-prerequisites", activation.prerequisitesPath);
@@ -13936,21 +14638,21 @@ async function listen(server, path) {
13936
14638
  });
13937
14639
  });
13938
14640
  }
13939
- function createComposedGrokRoleTurnHost(config) {
13940
- return createGrokRoleTurnHost({
14641
+ function createComposedAcpRoleTurnHost(config) {
14642
+ return createAcpRoleTurnHost({
13941
14643
  ...config,
13942
- prepare: (request) => prepareGrokRoleEnvelope({
14644
+ prepare: (request) => prepareAcpRoleEnvelope({
13943
14645
  request,
13944
14646
  dependencies: config.roleRuntimeDependencies,
13945
14647
  // Same durable-principal path settlement uses for isAvailable (#617 DK-4 layout).
13946
14648
  sessionFile: config.sessionIdentity.resolveSessionFile(request.principal),
13947
- socketPath: config.socketPath?.(request) ?? `/tmp/ak-grok-mcp-${randomUUID2()}.sock`
14649
+ socketPath: config.socketPath?.(request) ?? `/tmp/ak-acp-mcp-${randomUUID2()}.sock`
13948
14650
  })
13949
14651
  });
13950
14652
  }
13951
- async function prepareGrokRoleEnvelope(options) {
14653
+ async function prepareAcpRoleEnvelope(options) {
13952
14654
  const { request } = options;
13953
- const flags = projectGrokActivationFlags(request);
14655
+ const flags = projectAcpActivationFlags(request);
13954
14656
  const tools = /* @__PURE__ */ new Map();
13955
14657
  const handlers = /* @__PURE__ */ new Map();
13956
14658
  const calls = [];
@@ -13969,7 +14671,7 @@ async function prepareGrokRoleEnvelope(options) {
13969
14671
  const raw = await readFile13(method.path, "utf8");
13970
14672
  methodSkills.set(name, { path: method.path, body: stripSkillFrontmatter(raw).trim() });
13971
14673
  }
13972
- let sessionFile = options.sessionFile ?? join22(request.runDirectory, "session", "session.jsonl");
14674
+ let sessionFile = options.sessionFile ?? join24(request.runDirectory, "session", "session.jsonl");
13973
14675
  await mkdir3(dirname15(sessionFile), { recursive: true });
13974
14676
  if (request.continuation.kind !== "resume") {
13975
14677
  try {
@@ -14034,7 +14736,7 @@ async function prepareGrokRoleEnvelope(options) {
14034
14736
  },
14035
14737
  capabilities: {
14036
14738
  skillExpansion(prompt) {
14037
- return buildGrokSkillExpansion(methodSkills, prompt);
14739
+ return buildAcpSkillExpansion(methodSkills, prompt);
14038
14740
  }
14039
14741
  },
14040
14742
  registerFlag(name, definition) {
@@ -14046,12 +14748,12 @@ async function prepareGrokRoleEnvelope(options) {
14046
14748
  registerTool(tool2) {
14047
14749
  tools.set(tool2.name, tool2);
14048
14750
  },
14049
- // The real AK-owned surface only; Grok's builtin surface is host-side and
14751
+ // The real AK-owned surface only; the host builtin surface is host-side and
14050
14752
  // observable after session/new, never echoed back into role-requested names.
14051
14753
  getAllTools() {
14052
14754
  return [...tools.keys()].map((name) => ({ name }));
14053
14755
  },
14054
- // Grok receives tool choice as role guidance; every tool registered for the
14756
+ // The host receives tool choice as role guidance; every tool registered for the
14055
14757
  // seat remains reachable through MCP.
14056
14758
  setActiveTools(names) {
14057
14759
  preferredTools = [...names];
@@ -14333,7 +15035,7 @@ async function prepareGrokRoleEnvelope(options) {
14333
15035
  }
14334
15036
  if (cleanupFailures.length === 1) throw cleanupFailures[0];
14335
15037
  if (cleanupFailures.length > 1) {
14336
- throw new AggregateError(cleanupFailures, "Grok envelope dispose cleanup failures", {
15038
+ throw new AggregateError(cleanupFailures, "ACP envelope dispose cleanup failures", {
14337
15039
  cause: cleanupFailures[0]
14338
15040
  });
14339
15041
  }
@@ -14410,8 +15112,8 @@ async function prepareGrokRoleEnvelope(options) {
14410
15112
  command: process.execPath,
14411
15113
  args: [relay],
14412
15114
  env: [
14413
- { name: "AK_GROK_MCP_SOCKET", value: options.socketPath },
14414
- { name: "AK_GROK_MCP_TOKEN", value: token }
15115
+ { name: "AK_ACP_MCP_SOCKET", value: options.socketPath },
15116
+ { name: "AK_ACP_MCP_TOKEN", value: token }
14415
15117
  ]
14416
15118
  }],
14417
15119
  systemPrompt: { body: systemPromptBody, materials: readingMaterials },
@@ -14426,7 +15128,7 @@ async function prepareGrokRoleEnvelope(options) {
14426
15128
  } catch (cleanupFailure) {
14427
15129
  throw new AggregateError(
14428
15130
  [error, cleanupFailure],
14429
- "prepareGrokRoleEnvelope activation failed and its dispose cleanup also failed",
15131
+ "prepareAcpRoleEnvelope activation failed and its dispose cleanup also failed",
14430
15132
  { cause: error }
14431
15133
  );
14432
15134
  }
@@ -14434,12 +15136,11 @@ async function prepareGrokRoleEnvelope(options) {
14434
15136
  }
14435
15137
  }
14436
15138
 
14437
- // src/grok/session-identity.ts
15139
+ // src/acp-host/session-identity.ts
14438
15140
  import { mkdir as mkdir4, readFile as readFile14, rename, writeFile as writeFile8 } from "node:fs/promises";
14439
- import { dirname as dirname16, join as join23 } from "node:path";
14440
- var GROK_ACP_SESSION_BINDING = "grok-acp-session.json";
14441
- function createGrokSessionIdentityAuthority(authority) {
14442
- const bindingPath = (principal) => join23(authority.decode(principal).sessionDirectory, GROK_ACP_SESSION_BINDING);
15141
+ import { dirname as dirname16, join as join25 } from "node:path";
15142
+ function createAcpSessionIdentityAuthority(authority, sessionBindingFile) {
15143
+ const bindingPath = (principal) => join25(authority.decode(principal).sessionDirectory, sessionBindingFile);
14443
15144
  return {
14444
15145
  resolveSessionFile(principal) {
14445
15146
  return authority.decode(principal).sessionFile;
@@ -14448,7 +15149,7 @@ function createGrokSessionIdentityAuthority(authority) {
14448
15149
  try {
14449
15150
  const value = JSON.parse(await readFile14(bindingPath(principal), "utf8"));
14450
15151
  if (typeof value !== "object" || value === null || typeof value.sessionId !== "string") {
14451
- throw new Error("durable Grok ACP session binding is invalid");
15152
+ throw new Error("durable ACP session binding is invalid");
14452
15153
  }
14453
15154
  return value.sessionId;
14454
15155
  } catch (error) {
@@ -14467,20 +15168,11 @@ function createGrokSessionIdentityAuthority(authority) {
14467
15168
  };
14468
15169
  }
14469
15170
 
14470
- // src/grok/production-host.ts
14471
- function resolveGrokBinary(operatorHome) {
14472
- return join24(operatorHome, ".grok", "bin", "grok");
14473
- }
14474
- function childEnv(packageRoot) {
14475
- return {
14476
- ...controlledGrokChildEnv(process.env),
14477
- AK_PACKAGE_ROOT: packageRoot
14478
- };
14479
- }
15171
+ // src/acp-host/production-host.ts
14480
15172
  var navigatorRoutePlaybookPath = fileURLToPath3(
14481
15173
  new URL("../../resources/navigator-route-playbook.md", import.meta.url)
14482
15174
  );
14483
- function createGrokRoleRuntimeDependencies(packageRoot) {
15175
+ function createAcpRoleRuntimeDependencies(packageRoot) {
14484
15176
  const judgeAuditor = createPiJudgeAuditor();
14485
15177
  const doctorAuditor = createPiDoctorAuditor();
14486
15178
  const reviewerAgent = createPerDispatchReviewerAgent({ packageRoot });
@@ -14504,6 +15196,7 @@ function createGrokRoleRuntimeDependencies(packageRoot) {
14504
15196
  loadNotarySoul: () => loadMainRoleSessionMaterials("notary"),
14505
15197
  loadCountersignSoul: () => loadMainRoleSessionMaterials("countersign"),
14506
15198
  loadGleanerLeftSoul: () => loadMainRoleSessionMaterials("gleaner-left"),
15199
+ loadDiaristSoul: () => loadMainRoleSessionMaterials("diarist"),
14507
15200
  loadNotarySourceRun: loadNotarySourceRunLocator,
14508
15201
  loadMergerSoul: () => loadMainRoleSessionMaterials("merger"),
14509
15202
  loadMergerInput: async (path) => JSON.parse(await readFile15(path, "utf8")),
@@ -14544,23 +15237,28 @@ function createGrokRoleRuntimeDependencies(packageRoot) {
14544
15237
  })
14545
15238
  };
14546
15239
  }
14547
- function createProductionGrokRoleTurnHost(options) {
14548
- const { packageRoot, principalAuthority } = options;
14549
- const env = childEnv(packageRoot);
14550
- return createComposedGrokRoleTurnHost({
14551
- sessionIdentity: createGrokSessionIdentityAuthority(principalAuthority),
14552
- roleRuntimeDependencies: createGrokRoleRuntimeDependencies(packageRoot),
15240
+ function createProductionAcpRoleTurnHost(options) {
15241
+ const { packageRoot, principalAuthority, description } = options;
15242
+ const env = {
15243
+ ...process.env,
15244
+ ...description.childEnv,
15245
+ AK_PACKAGE_ROOT: packageRoot
15246
+ };
15247
+ return createComposedAcpRoleTurnHost({
15248
+ sessionIdentity: createAcpSessionIdentityAuthority(principalAuthority, description.sessionBindingFile),
15249
+ boundResume: description.boundResume,
15250
+ roleRuntimeDependencies: createAcpRoleRuntimeDependencies(packageRoot),
14553
15251
  async connect(request) {
14554
- return connectGrokAcpStdio({
14555
- binary: resolveGrokBinary(request.home),
15252
+ return connectAcpStdio({
15253
+ binary: resolveAcpBinary(description, request.home),
15254
+ args: acpStdioArgs(description, request.model),
14556
15255
  cwd: request.cwd,
14557
- env,
14558
- ...request.model === void 0 ? {} : { model: request.model.model }
15256
+ env
14559
15257
  });
14560
15258
  }
14561
15259
  });
14562
15260
  }
14563
15261
  export {
14564
- createGrokRoleRuntimeDependencies,
14565
- createProductionGrokRoleTurnHost
15262
+ createAcpRoleRuntimeDependencies,
15263
+ createProductionAcpRoleTurnHost
14566
15264
  };