@akagilnc/pi-workflow-roles 0.1.5079 → 0.1.5096

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 (64) hide show
  1. package/dist/acp-host/production-host.js +348 -301
  2. package/dist/atomic-write.js +13 -19
  3. package/dist/auditor-soul.js +2 -1
  4. package/dist/doctor-contracts.js +1 -1
  5. package/dist/gatekeeper-role.js +2 -16
  6. package/dist/headless-host/production-host.js +380 -333
  7. package/dist/merger-contracts.js +1 -1
  8. package/dist/migrate-book-topology.js +18 -14
  9. package/dist/navigator-attendance.js +28 -143
  10. package/dist/navigator-invocation-identity.js +2 -0
  11. package/dist/navigator-public-session.js +13 -1
  12. package/dist/navigator-work-base.js +113 -0
  13. package/dist/notary-contracts.js +0 -2
  14. package/dist/package-contracts/fixer-output.js +1 -1
  15. package/dist/package-contracts/gatekeeper-output.js +1 -1
  16. package/dist/package-contracts/navigator-output.js +1 -1
  17. package/dist/package-contracts/terminating-infrastructure.js +3 -3
  18. package/dist/packaged-role-registry.js +9 -5
  19. package/dist/public-cli/countersign-run.js +1 -1
  20. package/dist/public-cli/invocation.js +6 -3
  21. package/dist/public-cli/main.js +46 -22
  22. package/dist/public-cli/settlement.js +20 -1
  23. package/dist/receipt-delivery-policy.js +9 -2
  24. package/dist/review-submission.js +3 -3
  25. package/docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md +9 -0
  26. package/extensions/role-runtime.ts +0 -27
  27. package/package.json +2 -1
  28. package/resources/836-deleted-machine-instruction-inventory.md +3 -3
  29. package/resources/collector-bot-handbook.md +4 -0
  30. package/resources/navigator-route-playbook.md +4 -6
  31. package/scripts/build-package.mjs +4 -0
  32. package/souls/coder-output-guide.md +1 -0
  33. package/src/auditor-soul.ts +2 -1
  34. package/src/collector-role.ts +6 -7
  35. package/src/collector-tool-schemas.ts +5 -5
  36. package/src/diarist-role.ts +2 -2
  37. package/src/doctor-contracts.ts +1 -1
  38. package/src/gatekeeper-role.ts +1 -18
  39. package/src/gleaner-left-role.ts +2 -2
  40. package/src/inspector-role.ts +1 -1
  41. package/src/judge-role.ts +1 -1
  42. package/src/merger-contracts.ts +1 -1
  43. package/src/navigator-attendance.ts +38 -164
  44. package/src/navigator-invocation-identity.ts +2 -0
  45. package/src/navigator-public-session.ts +17 -1
  46. package/src/navigator-role.ts +4 -0
  47. package/src/navigator-session-contracts.ts +2 -0
  48. package/src/navigator-work-base.ts +123 -0
  49. package/src/notary-contracts.ts +0 -4
  50. package/src/package-contracts/fixer-output.ts +1 -1
  51. package/src/package-contracts/gatekeeper-output.ts +3 -3
  52. package/src/package-contracts/navigator-output.ts +1 -1
  53. package/src/package-contracts/terminating-infrastructure.ts +3 -6
  54. package/src/packaged-role-registry.ts +5 -1
  55. package/src/public-cli/countersign-run.ts +1 -1
  56. package/src/public-cli/invocation.ts +6 -3
  57. package/src/public-cli/settlement.ts +21 -0
  58. package/src/receipt-delivery-policy.ts +9 -1
  59. package/src/review-submission.ts +3 -3
  60. package/src/reviewer-role.ts +3 -3
  61. package/src/role-runtime-dependencies.ts +1 -5
  62. package/src/role-runtime.ts +52 -38
  63. package/src/secretariat-role.ts +3 -3
  64. package/src/worker-role.ts +3 -3
@@ -13,7 +13,7 @@ const mergerInputSchema = Type.Object({
13
13
  resolutionScope: Type.Array(Type.String(), { description: "\u6750\u6599\uFF1A\u89E3\u6790\u8303\u56F4\u63D0\u793A\uFF1B\u53EF\u7A7A" }),
14
14
  authorizedChecks: Type.Array(checkSchema)
15
15
  }, { additionalProperties: false });
16
- const MERGER_STATUS_DESCRIPTION = "completed | escalate \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8";
16
+ const MERGER_STATUS_DESCRIPTION = "completed | escalate";
17
17
  const mergerOutputVariants = Type.Union([
18
18
  Type.Object({ status: Type.Unknown({ description: MERGER_STATUS_DESCRIPTION }), attemptId: Type.String({ description: "\u5DF2\u53D7\u7406\u5408\u5E76 attempt \u8EAB\u4EFD" }), report: Type.String({ description: "\u5982\u5B9E\u7ED3\u679C\u62A5\u544A" }), mergeCommitId: Type.String({ description: "\u5B8C\u6210\u5408\u5E76 commit object ID" }) }, { additionalProperties: false }),
19
19
  Type.Object({ status: Type.Unknown({ description: MERGER_STATUS_DESCRIPTION }), attemptId: Type.String({ description: "\u5DF2\u53D7\u7406\u5408\u5E76 attempt \u8EAB\u4EFD" }), diagnosis: Type.String({ description: "\u5408\u5E76\u65E0\u6CD5\u6216\u4E0D\u5E94\u7531\u672C\u5E2D\u5B8C\u6210\u7684\u539F\u56E0\uFF08\u542B\u65E0\u8FDB\u884C\u4E2D\u5408\u5E76\u3001\u65E0\u6D3B\u53EF\u5E72\u3001\u9700\u65B0\u7684\u4EA7\u54C1/\u6743\u529B\u51B3\u5B9A\uFF09" }), report: Type.String({ description: "\u5982\u5B9E\u7ED3\u679C\u62A5\u544A" }) }, { additionalProperties: false })
@@ -8199,7 +8199,7 @@ function withTerminatingOutputDeclarations(schema) {
8199
8199
  ...baseProperties ?? {},
8200
8200
  ...baseProperties?.ticketNumber === void 0 ? {
8201
8201
  ticketNumber: typebox_exports.Unknown({
8202
- description: "\u53EF\u9009\u672C\u7968\u53F7\uFF1A\u5C1A\u672A\u7ED1\u5B9A\u65F6\u7531\u89D2\u8272\u5728\u65E2\u6709\u56DE\u6267\u4E2D\u7533\u62A5\uFF1B\u673A\u68B0\u5C42\u53EA\u8BB0\u5F55\u5408\u6CD5\u6B63\u6574\u6570\uFF0C\u4E0D\u4ECE\u6563\u6587\u63A8\u5BFC\u3001\u4E0D\u9A8C\u771F\u3002\u7F3A\u5931\u6216\u9519\u5F62\u4E0D\u62D2\u6536\u3002"
8202
+ description: "\u53EF\u9009\u672C\u7968\u53F7\u3002\u5C1A\u672A\u7ED1\u5B9A\u65F6\u7531\u89D2\u8272\u5728\u65E2\u6709\u56DE\u6267\u4E2D\u7533\u62A5\u3002"
8203
8203
  })
8204
8204
  } : {},
8205
8205
  [INFRASTRUCTURE_FAILURE_DECLARATION_KEY]: infrastructureFailureDeclarationSchema.properties[INFRASTRUCTURE_FAILURE_DECLARATION_KEY]
@@ -8220,12 +8220,12 @@ var init_terminating_infrastructure = __esm({
8220
8220
  infrastructureFailureNested = typebox_exports.Object(
8221
8221
  {
8222
8222
  [INFRASTRUCTURE_FAILURE_DIAGNOSTIC_KEY]: typebox_exports.Unknown({
8223
- description: "\u975E\u7A7A\u57FA\u7840\u8BBE\u65BD\u5931\u8D25\u8BCA\u65AD\u5B57\u7B26\u4E32\u3002\u65E0\u5931\u8D25\u65F6\u5FC5\u987B\u7701\u7565\u6574\u4E2A infrastructureFailure\u3002\u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8\u3002"
8223
+ description: "\u57FA\u7840\u8BBE\u65BD\u5931\u8D25\u8BCA\u65AD\u5B57\u7B26\u4E32\u3002"
8224
8224
  })
8225
8225
  },
8226
8226
  {
8227
8227
  additionalProperties: true,
8228
- description: "\u57FA\u7840\u8BBE\u65BD\u771F\u5B9E\u5931\u8D25\u58F0\u660E\uFF08\u5982\u9700\uFF09\u3002\u89C4\u8303\u5F62\uFF1A{ diagnostic: \u975E\u7A7A\u8BCA\u65AD\u5B57\u7B26\u4E32 }\uFF1B\u65E0\u5931\u8D25\u65F6\u5FC5\u987B\u7701\u7565\u3002\u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8\u3002"
8228
+ description: "\u4EC5\u57FA\u7840\u8BBE\u65BD\u771F\u5B9E\u5931\u8D25\u65F6\u51FA\u73B0\u3002"
8229
8229
  }
8230
8230
  );
8231
8231
  infrastructureFailureNested.required = [];
@@ -8250,7 +8250,7 @@ var init_gatekeeper_output = __esm({
8250
8250
  gatekeeperDecisionSchema = openToolObject(
8251
8251
  typebox_exports.Object({
8252
8252
  status: typebox_exports.Unknown({
8253
- description: "dispatch | pass \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8"
8253
+ description: "dispatch | pass"
8254
8254
  }),
8255
8255
  officer: typebox_exports.Unknown({
8256
8256
  description: "status \u4E3A dispatch \u65F6\u4E3A inspector | notary"
@@ -8279,7 +8279,7 @@ var init_navigator_output = __esm({
8279
8279
  openToolObject(
8280
8280
  typebox_exports.Object({
8281
8281
  prose: typebox_exports.Unknown({
8282
- description: "\u6E38\u5955\u4F7F\u6563\u6587\u5EFA\u8BAE\uFF0C\u539F\u6837\u5448\u73B0\u3002\u4E0D\u8981\u6C42 candidates/next \u7B49\u7ED3\u6784\u5316\u5B57\u6BB5\u3002\u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8"
8282
+ description: "\u6E38\u5955\u4F7F\u6563\u6587\u5EFA\u8BAE\uFF0C\u539F\u6837\u5448\u73B0\u3002\u4E0D\u8981\u6C42 candidates/next \u7B49\u7ED3\u6784\u5316\u5B57\u6BB5\u3002"
8283
8283
  })
8284
8284
  })
8285
8285
  )
@@ -8306,7 +8306,7 @@ var init_review_submission = __esm({
8306
8306
  typebox_exports.Literal(REVIEW_QUEUE_WORDS[2])
8307
8307
  ],
8308
8308
  {
8309
- description: "\u5BA1\u6838\u961F\u5217\u4E09\u6001\u679A\u4E3E\uFF0C\u5FC5\u586B\u3002\u5BA1\u6838\u5E2D\u4ECD\u80FD\u4EA4\u5377\u800C\u5B8C\u6210\u5BA1\u6838\u6240\u9700\u7684\u5916\u90E8\u4F9D\u8D56\u53D1\u751F\u771F\u5B9E\u57FA\u7840\u8BBE\u65BD\u5931\u8D25\u65F6\uFF0Cstatus \u53D6 escalate\uFF0C\u7EC6\u8282\u5199\u5165 infrastructureFailure\u3002\u4E0D\u5F97\u7701\u7565 status\uFF0C\u4E0D\u5F97\u7528\u53E6\u4E24\u4E2A\u679A\u4E3E\u503C\u5145\u5F53\u653E\u884C\u6216\u5C01\u9A73\u3002\u5305\u4FA7\u4E0D\u56E0\u683C\u5F0F\u62D2\u6536\u3002"
8309
+ description: "\u5BA1\u6838\u5E2D\u672C\u8F6E\u88C1\u51B3\u7684\u5224\u522B\u72B6\u6001\u3002"
8310
8310
  }
8311
8311
  ),
8312
8312
  findings: typebox_exports.Optional(typebox_exports.Unknown({ description: "\u5BA1\u6838\u53D1\u73B0\uFF0C\u539F\u6837\u7559\u5B58" })),
@@ -8376,7 +8376,7 @@ var init_fixer_output = __esm({
8376
8376
  });
8377
8377
  classResultSchema = typebox_exports.Union([completedClassResultSchema, refusedClassResultSchema]);
8378
8378
  completedClassResultsSchema = typebox_exports.Array(completedClassResultSchema);
8379
- FIXER_STATUS_DESCRIPTION = "planned | completed | refused | unfinished | partially_completed \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8\uFF1Bunfinished \u7F3A\u524D\u7F6E\u6216\u8FDD\u5BAA\u7EA6\u675F\u81F4\u672C\u5C40\u672A\u5B8C\u6210\u65F6\u53EF\u7528\uFF0C\u7F3A\u5F85\u51B3 owner \u51B3\u5B9A\u6216\u7B54\u590D\u5C5E\u7F3A\u524D\u7F6E\u3002";
8379
+ FIXER_STATUS_DESCRIPTION = "planned | completed | refused | unfinished | partially_completed\u3002unfinished \u7F3A\u524D\u7F6E\u6216\u8FDD\u5BAA\u7EA6\u675F\u81F4\u672C\u5C40\u672A\u5B8C\u6210\u65F6\u53EF\u7528\uFF0C\u7F3A\u5F85\u51B3 owner \u51B3\u5B9A\u6216\u7B54\u590D\u5C5E\u7F3A\u524D\u7F6E\u3002";
8380
8380
  fixerOutputVariants = typebox_exports.Union([
8381
8381
  typebox_exports.Object({ status: typebox_exports.Unknown({ description: FIXER_STATUS_DESCRIPTION }), report: typebox_exports.String({ description: "\u5982\u5B9E\u7ED3\u679C\u62A5\u544A" }) }),
8382
8382
  typebox_exports.Object({ status: typebox_exports.Unknown({ description: FIXER_STATUS_DESCRIPTION }), report: typebox_exports.String({ description: "\u5982\u5B9E\u7ED3\u679C\u62A5\u544A" }), remainingScope: typebox_exports.String({ description: "\u4F9D\u6CD5\u4E0D\u80FD\u5B8C\u6210\u7684\u5DE5\u4F5C\u8303\u56F4" }), blocker: typebox_exports.Unsafe({ ...blockerSchema, description: "\u5408\u6CD5\u963B\u65AD\u5B8C\u6210\u7684 blocker" }) }),
@@ -13836,7 +13836,7 @@ var init_doctor_contracts = __esm({
13836
13836
  typebox_exports.Object({ targetKey: nonblank, targetKind: typebox_exports.Optional(typebox_exports.Union(assetKinds.map((kind) => typebox_exports.Literal(kind)))), assetEvidence: typebox_exports.Optional(typebox_exports.Object({ targetKey: nonblank, targetKind: typebox_exports.Optional(typebox_exports.Union(assetKinds.map((kind) => typebox_exports.Literal(kind)))), evidenceId: nonblank }, { additionalProperties: true })), ...findingBody }, { additionalProperties: true })
13837
13837
  ]);
13838
13838
  caseIdentity = typebox_exports.Object({ issueNumber: typebox_exports.Optional(typebox_exports.Integer()), runsPath: nonblank }, { additionalProperties: true });
13839
- DOCTOR_STATUS_DESCRIPTION = "completed | refused \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8\uFF1Bcompleted \u5141\u8BB8\u7A7A findings\uFF1Brefused \u4EC5\u5F53\u8BC1\u636E\u4E0D\u8DB3\u4EE5\u652F\u6491\u5982\u5B9E\u6848\u8BC1\u8BCD";
13839
+ DOCTOR_STATUS_DESCRIPTION = "completed | refused\u3002completed \u5141\u8BB8\u7A7A findings\uFF1Brefused \u4EC5\u5F53\u8BC1\u636E\u4E0D\u8DB3\u4EE5\u652F\u6491\u5982\u5B9E\u6848\u8BC1\u8BCD";
13840
13840
  doctorSubmissionVariants = typebox_exports.Union([
13841
13841
  typebox_exports.Object({
13842
13842
  status: typebox_exports.Unknown({ description: DOCTOR_STATUS_DESCRIPTION }),
@@ -13885,7 +13885,7 @@ var init_merger_contracts = __esm({
13885
13885
  resolutionScope: typebox_exports.Array(typebox_exports.String(), { description: "\u6750\u6599\uFF1A\u89E3\u6790\u8303\u56F4\u63D0\u793A\uFF1B\u53EF\u7A7A" }),
13886
13886
  authorizedChecks: typebox_exports.Array(checkSchema)
13887
13887
  }, { additionalProperties: false });
13888
- MERGER_STATUS_DESCRIPTION = "completed | escalate \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8";
13888
+ MERGER_STATUS_DESCRIPTION = "completed | escalate";
13889
13889
  mergerOutputVariants = typebox_exports.Union([
13890
13890
  typebox_exports.Object({ status: typebox_exports.Unknown({ description: MERGER_STATUS_DESCRIPTION }), attemptId: typebox_exports.String({ description: "\u5DF2\u53D7\u7406\u5408\u5E76 attempt \u8EAB\u4EFD" }), report: typebox_exports.String({ description: "\u5982\u5B9E\u7ED3\u679C\u62A5\u544A" }), mergeCommitId: typebox_exports.String({ description: "\u5B8C\u6210\u5408\u5E76 commit object ID" }) }, { additionalProperties: false }),
13891
13891
  typebox_exports.Object({ status: typebox_exports.Unknown({ description: MERGER_STATUS_DESCRIPTION }), attemptId: typebox_exports.String({ description: "\u5DF2\u53D7\u7406\u5408\u5E76 attempt \u8EAB\u4EFD" }), diagnosis: typebox_exports.String({ description: "\u5408\u5E76\u65E0\u6CD5\u6216\u4E0D\u5E94\u7531\u672C\u5E2D\u5B8C\u6210\u7684\u539F\u56E0\uFF08\u542B\u65E0\u8FDB\u884C\u4E2D\u5408\u5E76\u3001\u65E0\u6D3B\u53EF\u5E72\u3001\u9700\u65B0\u7684\u4EA7\u54C1/\u6743\u529B\u51B3\u5B9A\uFF09" }), report: typebox_exports.String({ description: "\u5982\u5B9E\u7ED3\u679C\u62A5\u544A" }) }, { additionalProperties: false })
@@ -13996,21 +13996,24 @@ var init_packaged_role_registry = __esm({
13996
13996
  "souls/notary.md",
13997
13997
  "souls/audit-law.md",
13998
13998
  "souls/ticket-law.md",
13999
- "souls/gate-output-guide.md"
13999
+ "souls/gate-output-guide.md",
14000
+ "docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md"
14000
14001
  ];
14001
14002
  INSPECTOR_SESSION_MATERIALS = [
14002
14003
  "CLAUDE.md",
14003
14004
  "souls/inspector.md",
14004
14005
  "souls/audit-law.md",
14005
14006
  "souls/quality-law.md",
14006
- "souls/gate-output-guide.md"
14007
+ "souls/gate-output-guide.md",
14008
+ "docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md"
14007
14009
  ];
14008
14010
  AUDITOR_PUBLIC_SESSION_MATERIALS = [
14009
14011
  "CLAUDE.md",
14010
14012
  "souls/judge-auditor.md",
14011
14013
  "souls/doctor-auditor.md",
14012
14014
  "souls/audit-law.md",
14013
- "souls/quality-law.md"
14015
+ "souls/quality-law.md",
14016
+ "docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md"
14014
14017
  ];
14015
14018
  PUBLIC_ROLE_RECORDS = [
14016
14019
  {
@@ -14038,7 +14041,8 @@ var init_packaged_role_registry = __esm({
14038
14041
  "souls/judge.md",
14039
14042
  "souls/audit-law.md",
14040
14043
  "souls/quality-law.md",
14041
- "souls/judge-output-guide.md"
14044
+ "souls/judge-output-guide.md",
14045
+ "docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md"
14042
14046
  ]
14043
14047
  },
14044
14048
  {
@@ -14316,7 +14320,7 @@ var init_packaged_role_registry = __esm({
14316
14320
  activationStage: "load-and-install",
14317
14321
  receiptStatusKey: "status",
14318
14322
  // #924: 公用《票面法》三席同装
14319
- sessionMaterials: ["CLAUDE.md", "souls/countersign.md", "souls/ticket-law.md", "resources/countersign-ticket-issue.md"]
14323
+ sessionMaterials: ["CLAUDE.md", "souls/countersign.md", "souls/ticket-law.md", "resources/countersign-ticket-issue.md", "docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md"]
14320
14324
  },
14321
14325
  {
14322
14326
  role: "secretariat",
@@ -6,6 +6,7 @@ import {} from "@earendil-works/pi-coding-agent";
6
6
  import { Type } from "typebox";
7
7
  import {
8
8
  NAVIGATOR_INVOCATION_ENTRY,
9
+ NAVIGATOR_ROUTE_PLAYBOOK_FAILURE_ENTRY,
9
10
  mintNavigatorInvocationId
10
11
  } from "./navigator-invocation-identity.js";
11
12
  import { PACKAGED_ROLE_REGISTRY } from "./packaged-role-registry.js";
@@ -31,10 +32,10 @@ import {
31
32
  } from "./navigator-session-contracts.js";
32
33
  import { sitianReport } from "./sitian-facade.js";
33
34
  import { issueRoot, subjectPath } from "./work-subject-identity.js";
34
- import { createReceiptDeliveryPolicy, NO_RECEIPT_LIFECYCLE_ENTRY_TYPE, RECEIPT_DELIVERY_PROMPT } from "./receipt-delivery-policy.js";
35
+ import { createReceiptDeliveryPolicy, NO_RECEIPT_LIFECYCLE_ENTRY_TYPE } from "./receipt-delivery-policy.js";
35
36
  import { navigatorProseFromUnknown } from "./package-contracts/navigator-output.js";
37
+ import { persistNavigatorWorkBase } from "./navigator-work-base.js";
36
38
  const NAVIGATOR_EVENT_TYPE = "ak-navigator-attendance";
37
- const NAVIGATOR_PREPARE_ACCEPTED_TEXT = "\u6E38\u5955\u4F7F\u51C6\u5907\u5DF2\u63A5\u53D7";
38
39
  function resolveNavigatorAuthorityMaterial(roleInput, fileAuthority) {
39
40
  if (roleInput !== void 0 && roleInput.trim() !== "") return roleInput;
40
41
  if (fileAuthority !== void 0 && fileAuthority.trim() !== "") return fileAuthority;
@@ -43,10 +44,9 @@ function resolveNavigatorAuthorityMaterial(roleInput, fileAuthority) {
43
44
  const NAVIGATOR_TARGETS = PACKAGED_ROLE_REGISTRY.map(({ role, phases }) => ({ role, phases }));
44
45
  const prepareSchema = Type.Object({
45
46
  prose: Type.Optional(Type.Unknown({
46
- description: "\u6E38\u5955\u4F7F\u6563\u6587\u5EFA\u8BAE\uFF0C\u539F\u6837\u5448\u73B0\u3002\u4E0D\u8981\u6C42 candidates/next \u7ED3\u6784\u3002\u975E\u53D7\u7406\u95F8"
47
+ description: "\u6E38\u5955\u4F7F\u6563\u6587\u5EFA\u8BAE\uFF0C\u539F\u6837\u5448\u73B0\u3002\u4E0D\u8981\u6C42 candidates/next \u7ED3\u6784\u3002"
47
48
  }))
48
49
  }, { additionalProperties: true });
49
- const CONTEXT_ENTRY = "ak-navigator-context";
50
50
  const INVOCATION_ENTRY = NAVIGATOR_INVOCATION_ENTRY;
51
51
  const SETTLEMENT_ENTRY = "ak-navigator-settlement";
52
52
  const unavailableKeys = /* @__PURE__ */ new Set(["context", "session", "model", "thinking", "auth", "quota", "transport", "unknown"]);
@@ -105,12 +105,12 @@ function createNavigatorPrepareTool(onOutput) {
105
105
  parameters: prepareSchema,
106
106
  async execute(_id, value) {
107
107
  onOutput(value);
108
- return { content: [{ type: "text", text: NAVIGATOR_PREPARE_ACCEPTED_TEXT }], details: value, terminate: true };
108
+ return { content: [], details: value, terminate: true };
109
109
  }
110
110
  };
111
111
  }
112
112
  function formatNavigatorReport(report) {
113
- const playbookFailure = report.routePlaybookReadFailure === void 0 ? [] : [`\u8DEF\u4E66\u8BFB\u53D6\u5931\u8D25\uFF1A${report.routePlaybookReadFailure}`];
113
+ const playbookFailure = report.routePlaybookReadFailure === void 0 ? [] : [report.routePlaybookReadFailure];
114
114
  if (report.disposition === "no-advice") return playbookFailure.join("\n");
115
115
  if (report.disposition === "unavailable") {
116
116
  return [...playbookFailure, ...report.unavailableReason ? [report.unavailableReason] : []].join("\n");
@@ -136,28 +136,15 @@ function createNavigatorAttendance(options) {
136
136
  let settlementTail = Promise.resolve();
137
137
  let settlementFailure;
138
138
  let preparationFailure;
139
- let routePlaybookReadFailure;
139
+ let observedRoutePlaybookFailure;
140
140
  let disposed = false;
141
141
  let closing;
142
142
  const nestCancel = new AbortController();
143
- let warmedHelp;
144
143
  const sessionHostContext = () => {
145
144
  const parentSignal = options.context.signal;
146
145
  const signal = parentSignal === void 0 ? nestCancel.signal : AbortSignal.any([nestCancel.signal, parentSignal]);
147
146
  return { ...options.context, signal };
148
147
  };
149
- const loadLiveHelp = async () => {
150
- try {
151
- return await Promise.all(
152
- NAVIGATOR_TARGETS.map(async ({ role }) => ({
153
- role,
154
- help: await options.loadRoleHelp(role)
155
- }))
156
- );
157
- } catch (error) {
158
- throw navigatorUnavailableError("transport", error);
159
- }
160
- };
161
148
  const unavailable = (invocationId, reason) => {
162
149
  const failure = reason instanceof NavigatorUnavailableError ? reason : navigatorUnavailableError("unknown", reason);
163
150
  return {
@@ -167,7 +154,6 @@ function createNavigatorAttendance(options) {
167
154
  unavailableCause: failure.unavailableCause
168
155
  };
169
156
  };
170
- let routePlaybookSettlement;
171
157
  let prepareBoundSettlement;
172
158
  const loadMaterialsAndSession = async (invocationId) => {
173
159
  if (contextError !== void 0) throw navigatorUnavailableError("context", contextError);
@@ -177,30 +163,6 @@ function createNavigatorAttendance(options) {
177
163
  new Error("controlling authority content was not supplied as typed work context")
178
164
  );
179
165
  }
180
- let soul;
181
- let modelSetting;
182
- let help;
183
- let routePlaybook = "";
184
- routePlaybookReadFailure = void 0;
185
- const soulPromise = (async () => {
186
- try {
187
- const text = (await options.loadSoul()).trim();
188
- if (!text) throw new Error("Navigator soul is empty");
189
- return text;
190
- } catch (error) {
191
- throw navigatorUnavailableError("context", error);
192
- }
193
- })();
194
- const routePlaybookPromise = (async () => {
195
- if (options.loadRoutePlaybook === void 0) return "";
196
- try {
197
- return await options.loadRoutePlaybook();
198
- } catch (error) {
199
- routePlaybookReadFailure = error instanceof Error ? error.message : String(error);
200
- return "";
201
- }
202
- })();
203
- routePlaybookSettlement = routePlaybookPromise.then(() => void 0);
204
166
  const modelPromise = (async () => {
205
167
  try {
206
168
  const resolved = await resolveNavigatorSeatSelection(options.context);
@@ -210,23 +172,13 @@ function createNavigatorAttendance(options) {
210
172
  throw navigatorUnavailableError("model", error);
211
173
  }
212
174
  })();
213
- const helpPromise = warmedHelp ?? loadLiveHelp();
214
- warmedHelp = void 0;
215
- [soul, routePlaybook, modelSetting, help] = await Promise.all([
216
- soulPromise,
217
- routePlaybookPromise,
218
- modelPromise,
219
- helpPromise
220
- ]);
175
+ const modelSetting = await modelPromise;
221
176
  let model;
222
177
  try {
223
178
  model = parseNavigatorModelSetting(modelSetting);
224
179
  } catch (error) {
225
180
  throw navigatorUnavailableError("model", error);
226
181
  }
227
- const helpContext = help.map(({ role, help: text }) => `<role_help role="${role}">
228
- ${text}
229
- </role_help>`).join("\n");
230
182
  const tool = createNavigatorPrepareTool((value) => {
231
183
  outputSink?.(value);
232
184
  });
@@ -271,9 +223,9 @@ ${text}
271
223
  }
272
224
  if (disposed) throw navigatorUnavailableError("session", new Error("Navigator attendance was disposed"));
273
225
  if (session === void 0) throw new Error("Navigator session was not created");
274
- return { soul, routePlaybook, helpContext, modelSetting, model, help, activeSession: session };
226
+ return session;
275
227
  };
276
- const prepare = async (materialsBundle) => {
228
+ const prepare = async (existingSession) => {
277
229
  const boundSettlement = prepareBoundSettlement;
278
230
  prepareBoundSettlement = void 0;
279
231
  const invocationId = invocationPrincipal;
@@ -290,73 +242,19 @@ ${text}
290
242
  const merged = [prior, next].filter((part) => part.trim() !== "").join("\n\n");
291
243
  output = { prose: merged };
292
244
  };
293
- const { soul, routePlaybook, helpContext, help, activeSession } = materialsBundle ?? await loadMaterialsAndSession(invocationId);
294
- const publicSettlementHistory = activeSession.entries().filter((entry) => exactRecord(entry) && entry.type === "custom" && entry.customType === SETTLEMENT_ENTRY && exactRecord(entry.data)).map((entry) => entry.data);
295
- const projection = {
296
- subjectKey,
297
- subject,
298
- authority,
299
- currentRole: { role: options.role, phase: options.phase },
300
- ...boundSettlement === void 0 ? {} : { currentSettlement: boundSettlement },
301
- publicSettlementHistory,
302
- liveRoleHelp: help
303
- };
304
- activeSession.appendEntry(CONTEXT_ENTRY, projection);
305
- const request = boundSettlement === void 0 ? [
306
- "\u672C\u8F6E\u4E3A\u5F85\u547D\u8F6E\u3002",
307
- `<navigator_soul>
308
- ${soul}
309
- </navigator_soul>`,
310
- ...routePlaybookReadFailure === void 0 ? [`<route_playbook>
311
- ${routePlaybook}
312
- </route_playbook>`] : ["\u53EF\u9009\u8DEF\u7EBF\u624B\u518C\u672A\u80FD\u8BFB\u53D6\u3002"],
313
- `<work_subject>
314
- ${subject}
315
- </work_subject>`,
316
- `<controlling_authority>
317
- ${authority}
318
- </controlling_authority>`,
319
- `<current_role>
320
- ${JSON.stringify({ role: options.role, phase: options.phase })}
321
- </current_role>`,
322
- `<public_settlement_history>
323
- ${JSON.stringify(projection.publicSettlementHistory)}
324
- </public_settlement_history>`,
325
- `<live_role_help>
326
- ${helpContext}
327
- </live_role_help>`
328
- ].join("\n\n") : [
329
- "\u672C\u8F6E\u4E3A\u7ED3\u7B97\u6295\u5582\u8F6E\u3002",
330
- `<navigator_soul>
331
- ${soul}
332
- </navigator_soul>`,
333
- ...routePlaybookReadFailure === void 0 ? [`<route_playbook>
334
- ${routePlaybook}
335
- </route_playbook>`] : ["\u53EF\u9009\u8DEF\u7EBF\u624B\u518C\u672A\u80FD\u8BFB\u53D6\u3002"],
336
- `<work_subject>
337
- ${subject}
338
- </work_subject>`,
339
- `<controlling_authority>
340
- ${authority}
341
- </controlling_authority>`,
342
- `<current_role>
343
- ${JSON.stringify({ role: options.role, phase: options.phase })}
344
- </current_role>`,
345
- `<current_settlement>
346
- ${JSON.stringify(boundSettlement)}
347
- </current_settlement>`,
348
- `<public_settlement_history>
349
- ${JSON.stringify(projection.publicSettlementHistory)}
350
- </public_settlement_history>`,
351
- `<live_role_help>
352
- ${helpContext}
353
- </live_role_help>`
354
- ].join("\n\n");
245
+ const activeSession = existingSession ?? await loadMaterialsAndSession(invocationId);
246
+ if (boundSettlement === void 0) return void 0;
247
+ const request = JSON.stringify({
248
+ ...boundSettlement,
249
+ invocationId,
250
+ subjectKey
251
+ });
355
252
  try {
356
253
  try {
357
254
  if (disposed) throw navigatorUnavailableError("session", new Error("Navigator attendance was disposed"));
358
255
  const delivery = createReceiptDeliveryPolicy();
359
256
  const promptAllowingRejectedPrepare = async (text, deliveryRequest) => {
257
+ await persistNavigatorWorkBase(activeSession.recordPointer(), { subject, authority });
360
258
  const entryStart = activeSession.entries().length;
361
259
  prepareBatchRejected = false;
362
260
  let promptFailure;
@@ -387,7 +285,7 @@ ${helpContext}
387
285
  await promptAllowingRejectedPrepare(request, false);
388
286
  if (boundSettlement !== void 0) {
389
287
  while (output === void 0 && prepareBatchRejected && delivery.nextAction() === "request-delivery") {
390
- await promptAllowingRejectedPrepare(RECEIPT_DELIVERY_PROMPT, true);
288
+ await promptAllowingRejectedPrepare(JSON.stringify(delivery.deliveryState()), true);
391
289
  }
392
290
  if (output === void 0 && delivery.nextAction() === "request-delivery") {
393
291
  while (delivery.nextAction() === "request-delivery") {
@@ -427,6 +325,8 @@ ${helpContext}
427
325
  preparedProse = normalizePrepareProse(output);
428
326
  return preparedProse;
429
327
  } finally {
328
+ const playbookFailure = activeSession.routePlaybookReadFailure?.();
329
+ observedRoutePlaybookFailure = typeof playbookFailure === "string" && playbookFailure.trim() !== "" ? playbookFailure : void 0;
430
330
  outputSink = void 0;
431
331
  }
432
332
  };
@@ -444,16 +344,6 @@ ${helpContext}
444
344
  contextError = next.contextError;
445
345
  return closing2;
446
346
  },
447
- /**
448
- * Start live-help subprocesses during activation without beginning full
449
- * preparation. Next prepare() consumes the warm result; a later prepare
450
- * reloads so live help edits remain visible.
451
- */
452
- warmHelp() {
453
- if (disposed || warmedHelp !== void 0 || preparation !== void 0) return;
454
- warmedHelp = loadLiveHelp();
455
- void warmedHelp.catch(() => void 0);
456
- },
457
347
  prepare() {
458
348
  if (disposed || preparation !== void 0) return;
459
349
  preparationFailure = void 0;
@@ -468,9 +358,6 @@ ${helpContext}
468
358
  isPreparing() {
469
359
  return preparationInFlight;
470
360
  },
471
- knownRoutePlaybookReadFailure() {
472
- return routePlaybookReadFailure;
473
- },
474
361
  settle(settlement) {
475
362
  const next = settlementTail.then(() => settleOnce(settlement));
476
363
  settlementTail = next.catch((error) => {
@@ -497,6 +384,7 @@ ${helpContext}
497
384
  };
498
385
  async function settleOnce(settlement) {
499
386
  if (disposed) return;
387
+ observedRoutePlaybookFailure = void 0;
500
388
  const invocationId = activeInvocationId ?? invocationPrincipal;
501
389
  let report;
502
390
  if (sessionReady !== void 0) {
@@ -535,10 +423,10 @@ ${helpContext}
535
423
  }
536
424
  } else {
537
425
  if (session !== void 0) preparationFailure = void 0;
538
- let coldMaterials;
426
+ let coldSession;
539
427
  if (session === void 0 && preparationFailure === void 0) {
540
428
  try {
541
- coldMaterials = await loadMaterialsAndSession(invocationId);
429
+ coldSession = await loadMaterialsAndSession(invocationId);
542
430
  } catch (error) {
543
431
  preparationFailure = error;
544
432
  }
@@ -546,7 +434,7 @@ ${helpContext}
546
434
  session?.appendEntry(SETTLEMENT_ENTRY, settlementFact);
547
435
  if (preparationFailure === void 0) {
548
436
  prepareBoundSettlement = settlement;
549
- preparation = prepare(coldMaterials);
437
+ preparation = prepare(coldSession);
550
438
  void preparation.catch((error) => {
551
439
  preparationFailure = error;
552
440
  });
@@ -565,9 +453,8 @@ ${helpContext}
565
453
  report = { disposition: "no-advice" };
566
454
  }
567
455
  }
568
- await routePlaybookSettlement;
569
- if (routePlaybookReadFailure !== void 0) {
570
- report = { ...report, routePlaybookReadFailure };
456
+ if (observedRoutePlaybookFailure !== void 0) {
457
+ report = { ...report, routePlaybookReadFailure: observedRoutePlaybookFailure };
571
458
  }
572
459
  const event = {
573
460
  version: 1,
@@ -594,8 +481,6 @@ ${helpContext}
594
481
  sessionReady = void 0;
595
482
  preparedProse = void 0;
596
483
  preparationFailure = void 0;
597
- routePlaybookSettlement = void 0;
598
- routePlaybookReadFailure = void 0;
599
484
  }
600
485
  }
601
486
  function registerNavigatorModelCommand(pi, path = navigatorModelSettingPath()) {
@@ -608,8 +493,8 @@ function registerNavigatorModelCommand(pi, path = navigatorModelSettingPath()) {
608
493
  }
609
494
  export {
610
495
  NAVIGATOR_EVENT_TYPE,
611
- NAVIGATOR_PREPARE_ACCEPTED_TEXT,
612
496
  NAVIGATOR_PREPARE_TOOL_NAME,
497
+ NAVIGATOR_ROUTE_PLAYBOOK_FAILURE_ENTRY,
613
498
  NAVIGATOR_TARGETS,
614
499
  NavigatorUnavailableError,
615
500
  createNativeNavigatorSessionFactory,
@@ -2,6 +2,7 @@ import { LEGACY_REVIEW_OUTPUT_ROLES, PACKAGED_ROLE_REGISTRY } from "./packaged-r
2
2
  import { isUuidV7, uuidv7 } from "./uuidv7.js";
3
3
  import { workSubjectKeysEqual } from "./work-subject-identity.js";
4
4
  const NAVIGATOR_INVOCATION_ENTRY = "ak-navigator-invocation";
5
+ const NAVIGATOR_ROUTE_PLAYBOOK_FAILURE_ENTRY = "ak-navigator-route-playbook-failure";
5
6
  const NAVIGATOR_INFRASTRUCTURE_FAILURE_KIND = "role_infrastructure_failure";
6
7
  const NAVIGATOR_INFRASTRUCTURE_FAILURE_KEYS = [
7
8
  "kind",
@@ -221,6 +222,7 @@ export {
221
222
  NAVIGATOR_INFRASTRUCTURE_FAILURE_EVIDENCE_KEYS,
222
223
  NAVIGATOR_INFRASTRUCTURE_FAILURE_KIND,
223
224
  NAVIGATOR_INVOCATION_ENTRY,
225
+ NAVIGATOR_ROUTE_PLAYBOOK_FAILURE_ENTRY,
224
226
  bindCurrentDurableTerminalToMarker,
225
227
  buildNavigatorInfrastructureFailureFact,
226
228
  classifyPackagedRoleTerminalResult,
@@ -1,3 +1,4 @@
1
+ import { existsSync } from "node:fs";
1
2
  import { basename } from "node:path";
2
3
  import { sitianReport } from "./sitian-facade.js";
3
4
  import {
@@ -10,6 +11,10 @@ import {
10
11
  import { runDirectoryFromHostContext } from "./host-contracts.js";
11
12
  import { CliUsageError } from "./public-cli/cli-errors.js";
12
13
  import { isNavigatorSeat } from "./packaged-role-registry.js";
14
+ import {
15
+ attachWorkContextPointer,
16
+ navigatorWorkContextFile
17
+ } from "./navigator-work-base.js";
13
18
  async function resolveNavigatorLedgerHome(context) {
14
19
  const { tryHomeFromAkRolesPath } = await import("./activation-ledger-topology.js");
15
20
  const runDirectory = runDirectoryFromHostContext(context);
@@ -73,6 +78,7 @@ function createNativeNavigatorSessionFactory(deps) {
73
78
  });
74
79
  let providerFailure;
75
80
  let noReceipt;
81
+ let routePlaybookReadFailure;
76
82
  let disposed = false;
77
83
  let hostRunId = readNavigatorHostRunPointer(sessionManager.getEntries());
78
84
  const summon = deps?.summonPublicRole ?? (async (options) => {
@@ -86,13 +92,16 @@ function createNativeNavigatorSessionFactory(deps) {
86
92
  }
87
93
  providerFailure = void 0;
88
94
  noReceipt = void 0;
95
+ routePlaybookReadFailure = void 0;
89
96
  try {
90
97
  const summonHome = await resolveNavigatorLedgerHome(context);
91
98
  if (disposed) return;
92
99
  const resumeRunId = hostRunId;
100
+ const workContextPath = navigatorWorkContextFile(sessionManager.getSessionDir());
101
+ const argvText = existsSync(workContextPath) ? attachWorkContextPointer(text, workContextPath) : text;
93
102
  const baseSummon = {
94
103
  role: "navigator",
95
- argv: [text],
104
+ argv: [argvText],
96
105
  cwd: context.cwd,
97
106
  ...summonHome === void 0 ? {} : { home: summonHome },
98
107
  ...context.signal === void 0 ? {} : { signal: context.signal }
@@ -113,6 +122,8 @@ function createNativeNavigatorSessionFactory(deps) {
113
122
  }
114
123
  }
115
124
  if (disposed) return;
125
+ const playbookFailure = summoned.terminal?.navigator?.advisoryDiagnostic;
126
+ routePlaybookReadFailure = typeof playbookFailure === "string" && playbookFailure.trim() !== "" ? playbookFailure : void 0;
116
127
  const outcome = summoned.terminal?.roleOutcome;
117
128
  if (outcome === void 0) {
118
129
  const detail = summoned.stderr?.trim() || `exit ${summoned.exitCode}`;
@@ -171,6 +182,7 @@ function createNativeNavigatorSessionFactory(deps) {
171
182
  },
172
183
  providerFailure: () => providerFailure,
173
184
  noReceipt: () => noReceipt,
185
+ routePlaybookReadFailure: () => routePlaybookReadFailure,
174
186
  appendEntry: (customType, data) => {
175
187
  sessionManager.appendCustomEntry(customType, data);
176
188
  try {
@@ -0,0 +1,113 @@
1
+ import { existsSync, realpathSync } from "node:fs";
2
+ import { readFile } from "node:fs/promises";
3
+ import { basename, dirname, join, resolve } from "node:path";
4
+ import { writeFileAtomically } from "./atomic-write.js";
5
+ const NAVIGATOR_WORK_CONTEXT_BASENAME = "work-context.json";
6
+ function navigatorWorkContextFile(sessionDir) {
7
+ return join(sessionDir, NAVIGATOR_WORK_CONTEXT_BASENAME);
8
+ }
9
+ function isNavigatorWorkContextFile(path) {
10
+ const resolved = resolve(path);
11
+ if (basename(resolved) !== NAVIGATOR_WORK_CONTEXT_BASENAME) return false;
12
+ const nest = dirname(resolved);
13
+ if (!/^[0-9a-f]{32}$/.test(basename(nest))) return false;
14
+ return basename(dirname(nest)) === "navigator";
15
+ }
16
+ function canonicalNavigatorWorkContextFile(path) {
17
+ if (!isNavigatorWorkContextFile(path)) return void 0;
18
+ try {
19
+ const real = realpathSync(path);
20
+ return isNavigatorWorkContextFile(real) ? real : void 0;
21
+ } catch {
22
+ return void 0;
23
+ }
24
+ }
25
+ async function persistNavigatorWorkBase(sessionDir, body) {
26
+ if (sessionDir.trim() === "" || !existsSync(sessionDir)) return void 0;
27
+ if (body.authority.trim() === "") return void 0;
28
+ const path = navigatorWorkContextFile(sessionDir);
29
+ const next = `${JSON.stringify({ subject: body.subject, authority: body.authority })}
30
+ `;
31
+ try {
32
+ const current = await readFile(path, "utf8");
33
+ if (current === next) return path;
34
+ } catch (error) {
35
+ if (!(error instanceof Error && "code" in error && error.code === "ENOENT")) {
36
+ throw error;
37
+ }
38
+ }
39
+ await writeFileAtomically(path, next);
40
+ return path;
41
+ }
42
+ async function readNavigatorWorkBase(path) {
43
+ const canonical = canonicalNavigatorWorkContextFile(path);
44
+ if (canonical === void 0) return void 0;
45
+ let text;
46
+ try {
47
+ text = await readFile(canonical, "utf8");
48
+ } catch (error) {
49
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") {
50
+ return void 0;
51
+ }
52
+ throw error;
53
+ }
54
+ let parsed;
55
+ try {
56
+ parsed = JSON.parse(text);
57
+ } catch {
58
+ return void 0;
59
+ }
60
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return void 0;
61
+ const record = parsed;
62
+ if (typeof record.subject !== "string" || typeof record.authority !== "string") return void 0;
63
+ if (record.authority.trim() === "") return void 0;
64
+ return { subject: record.subject, authority: record.authority };
65
+ }
66
+ function jsonObjectFromPrompt(prompt) {
67
+ const head = prompt.trimStart().split("\n\n", 1)[0] ?? "";
68
+ if (!head.startsWith("{")) return void 0;
69
+ try {
70
+ const parsed = JSON.parse(head);
71
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return void 0;
72
+ return parsed;
73
+ } catch {
74
+ return void 0;
75
+ }
76
+ }
77
+ function workContextPathFromPrompt(prompt) {
78
+ const record = jsonObjectFromPrompt(prompt);
79
+ const path = record?.workContextPath;
80
+ if (typeof path !== "string" || path.trim() === "") return void 0;
81
+ return isNavigatorWorkContextFile(path) ? path : void 0;
82
+ }
83
+ function attachWorkContextPointer(text, workContextPath) {
84
+ const record = jsonObjectFromPrompt(text);
85
+ if (record === void 0) return text;
86
+ if (typeof record.workContextPath === "string" && record.workContextPath.trim() !== "") return text;
87
+ const head = text.trimStart().split("\n\n", 1)[0] ?? "";
88
+ const rest = text.trimStart().slice(head.length);
89
+ return `${JSON.stringify({ ...record, workContextPath })}${rest}`;
90
+ }
91
+ async function loadNavigatorWorkBaseSuffix(prompt) {
92
+ const path = workContextPathFromPrompt(prompt);
93
+ if (path === void 0) return void 0;
94
+ const body = await readNavigatorWorkBase(path);
95
+ if (body === void 0) return void 0;
96
+ return `<work_subject>
97
+ ${body.subject}
98
+ </work_subject>
99
+
100
+ <controlling_authority>
101
+ ${body.authority}
102
+ </controlling_authority>`;
103
+ }
104
+ export {
105
+ NAVIGATOR_WORK_CONTEXT_BASENAME,
106
+ attachWorkContextPointer,
107
+ isNavigatorWorkContextFile,
108
+ loadNavigatorWorkBaseSuffix,
109
+ navigatorWorkContextFile,
110
+ persistNavigatorWorkBase,
111
+ readNavigatorWorkBase,
112
+ workContextPathFromPrompt
113
+ };