@akagilnc/pi-workflow-roles 0.1.5845 → 0.1.5853

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 (66) hide show
  1. package/README.md +4 -4
  2. package/README.zh-CN.md +4 -4
  3. package/dist/acp-host/production-host.js +348 -1254
  4. package/dist/acp-host/role-turn-host.js +4 -98
  5. package/dist/headless-host/production-host.js +15731 -16582
  6. package/dist/headless-host/role-turn-host.js +6 -31
  7. package/dist/migrate-book-topology.js +31 -16
  8. package/dist/navigator-attendance.js +54 -404
  9. package/dist/navigator-invocation-identity.js +0 -2
  10. package/dist/navigator-lookup-host.js +41 -0
  11. package/dist/navigator-lookup.js +68 -0
  12. package/dist/navigator-route-table.js +42 -0
  13. package/dist/package-contracts/navigator-output.js +3 -11
  14. package/dist/packaged-role-registry.js +3 -27
  15. package/dist/public-cli/instruction-seat-run.js +4 -1
  16. package/dist/public-cli/invocation.js +13 -26
  17. package/dist/public-cli/main.js +286 -114
  18. package/dist/public-cli/option-definitions.js +24 -4
  19. package/dist/public-cli/post-admission.js +0 -9
  20. package/dist/public-cli/role-seat-runtime.js +14 -0
  21. package/dist/public-cli/settlement.js +14 -40
  22. package/dist/public-cli/terminal.js +1 -8
  23. package/dist/public-cli/turn-request.js +0 -3
  24. package/dist/public-role-summons.js +0 -1
  25. package/dist/receipt-delivery-policy.js +0 -23
  26. package/dist/role-runtime-dependencies.js +4 -11
  27. package/dist/role-runtime.js +18 -194
  28. package/dist/submission-ledger.js +19 -15
  29. package/dist/ticket-progress.js +23 -5
  30. package/extensions/role-runtime.ts +0 -16
  31. package/package.json +1 -1
  32. package/scripts/build-package.mjs +3 -7
  33. package/src/acp-host/role-turn-host.ts +8 -97
  34. package/src/headless-host/description.ts +0 -2
  35. package/src/headless-host/role-turn-host.ts +7 -32
  36. package/src/host-contracts.ts +5 -7
  37. package/src/navigator-attendance.ts +86 -549
  38. package/src/navigator-invocation-identity.ts +0 -2
  39. package/src/navigator-lookup-host.ts +45 -0
  40. package/src/navigator-lookup.ts +98 -0
  41. package/src/navigator-route-table.ts +92 -0
  42. package/src/package-contracts/navigator-output.ts +4 -15
  43. package/src/packaged-role-registry.ts +3 -32
  44. package/src/public-cli/instruction-seat-run.ts +3 -0
  45. package/src/public-cli/invocation.ts +18 -30
  46. package/src/public-cli/option-definitions.ts +25 -4
  47. package/src/public-cli/post-admission.ts +0 -11
  48. package/src/public-cli/role-seat-runtime.ts +14 -0
  49. package/src/public-cli/settlement.ts +23 -51
  50. package/src/public-cli/terminal.ts +3 -18
  51. package/src/public-cli/turn-request.ts +0 -5
  52. package/src/public-role-summons.ts +0 -8
  53. package/src/receipt-delivery-policy.ts +0 -21
  54. package/src/role-runtime-dependencies.ts +4 -11
  55. package/src/role-runtime.ts +19 -210
  56. package/src/submission-ledger.ts +23 -16
  57. package/src/ticket-progress.ts +32 -5
  58. package/dist/navigator-public-session.js +0 -205
  59. package/dist/navigator-role.js +0 -6
  60. package/dist/navigator-session-contracts.js +0 -227
  61. package/dist/navigator-work-context.js +0 -72
  62. package/resources/navigator-route-playbook.md +0 -33
  63. package/src/navigator-public-session.ts +0 -305
  64. package/src/navigator-role.ts +0 -15
  65. package/src/navigator-session-contracts.ts +0 -320
  66. package/src/navigator-work-context.ts +0 -97
@@ -45,11 +45,9 @@ import {
45
45
  homeFromRunDirectory,
46
46
  type AdmittedRoleInvocation,
47
47
  } from "./invocation.ts";
48
+ import { findLatestDurablePackagedRoleTerminal } from "../navigator-invocation-identity.ts";
48
49
  import {
49
- findLatestDurablePackagedRoleTerminal,
50
- NAVIGATOR_ROUTE_PLAYBOOK_FAILURE_ENTRY,
51
- } from "../navigator-invocation-identity.ts";
52
- import {
50
+ isNavigatorSeat,
53
51
  packagedRoleAcceptedOutputTool,
54
52
  packagedRoleMetadata,
55
53
  type PackagedArtifactFace,
@@ -462,11 +460,13 @@ async function settleNoReceiptTerminal(
462
460
  }
463
461
  return attachEngineDetourToolUsage({
464
462
  roleOutcome,
465
- navigator: await extractNavigatorFactFromAdmittedSession(
466
- coordinates.sessionFile,
467
- admitted.runDirectory,
468
- scope,
469
- ),
463
+ navigator: isNavigatorSeat(admitted.role)
464
+ ? NAVIGATOR_SEAT_OWN_FACT
465
+ : await extractNavigatorFactFromAdmittedSession(
466
+ coordinates.sessionFile,
467
+ admitted.runDirectory,
468
+ scope,
469
+ ),
470
470
  artifacts: [],
471
471
  runId: admitted.runId,
472
472
  }, coordinates.sessionDirectory, detourUsageContext(admitted, scope));
@@ -1075,9 +1075,6 @@ function parseNavigatorAttendanceDetails(
1075
1075
  details: Record<string, unknown>,
1076
1076
  ): TerminalNavigatorFact {
1077
1077
  const disposition = details.disposition;
1078
- const advisoryDiagnostic = typeof details.routePlaybookReadFailure === "string"
1079
- ? { advisoryDiagnostic: details.routePlaybookReadFailure }
1080
- : {};
1081
1078
  // #959: advice prose is presented as-is. Legacy "recommendation" with next/reason/
1082
1079
  // command is projected into prose so historical sessions still render — never wash
1083
1080
  // a real recommendation into no-advice when any advice body is recoverable.
@@ -1108,20 +1105,13 @@ function parseNavigatorAttendanceDetails(
1108
1105
  }
1109
1106
  if (prose === undefined || prose.trim() === "") {
1110
1107
  // Attended but empty body is affirmative no-advice, not unavailable (#959).
1111
- return {
1112
- disposition: "no-advice",
1113
- ...advisoryDiagnostic,
1114
- };
1108
+ return { disposition: "no-advice" };
1115
1109
  }
1116
- return adviceNavigatorFact({
1117
- prose,
1118
- ...advisoryDiagnostic,
1119
- });
1110
+ return adviceNavigatorFact({ prose });
1120
1111
  }
1121
1112
  if (disposition === "unavailable") {
1122
1113
  return {
1123
1114
  disposition: "unavailable",
1124
- ...advisoryDiagnostic,
1125
1115
  source:
1126
1116
  typeof details.unavailableSource === "string"
1127
1117
  ? details.unavailableSource
@@ -1134,10 +1124,7 @@ function parseNavigatorAttendanceDetails(
1134
1124
  }
1135
1125
  // arrival and legacy silence both mean affirmative lawful no next-role advice.
1136
1126
  if (disposition === "no-advice" || disposition === "arrival" || disposition === "silence") {
1137
- return {
1138
- disposition: "no-advice",
1139
- ...advisoryDiagnostic,
1140
- };
1127
+ return { disposition: "no-advice" };
1141
1128
  }
1142
1129
  return {
1143
1130
  disposition: "unavailable",
@@ -1235,28 +1222,8 @@ function detourUsageContext(
1235
1222
  };
1236
1223
  }
1237
1224
 
1238
- function routePlaybookFailureMessage(entries: readonly SessionEntry[]): string | undefined {
1239
- for (let i = entries.length - 1; i >= 0; i -= 1) {
1240
- const entry = entries[i];
1241
- if (entry?.type !== "custom" || entry.customType !== NAVIGATOR_ROUTE_PLAYBOOK_FAILURE_ENTRY) continue;
1242
- const data = entry.data;
1243
- if (!isRecord(data) || typeof data.message !== "string" || data.message.trim() === "") return undefined;
1244
- return data.message;
1245
- }
1246
- return undefined;
1247
- }
1248
-
1249
1225
  export function extractNavigatorFact(
1250
1226
  entries: readonly SessionEntry[],
1251
- ): TerminalNavigatorFact {
1252
- const fact = extractNavigatorAttendanceFact(entries);
1253
- if (fact.advisoryDiagnostic !== undefined) return fact;
1254
- const message = routePlaybookFailureMessage(entries);
1255
- return message === undefined ? fact : { ...fact, advisoryDiagnostic: message };
1256
- }
1257
-
1258
- function extractNavigatorAttendanceFact(
1259
- entries: readonly SessionEntry[],
1260
1227
  ): TerminalNavigatorFact {
1261
1228
  // Affirmative attendance only. Missing / unparseable is never no-advice.
1262
1229
  // The shared lifecycle places the settled event on this submission's closure;
@@ -1290,6 +1257,9 @@ function extractNavigatorAttendanceFact(
1290
1257
  * Never infers no-advice from omission; session read failures stay typed unavailable
1291
1258
  * so the controlled-failure Terminal itself still settles.
1292
1259
  */
1260
+ /** The navigator run is the advice itself; it has no attendance of its own (#1192). */
1261
+ const NAVIGATOR_SEAT_OWN_FACT: TerminalNavigatorFact = { disposition: "no-advice" };
1262
+
1293
1263
  async function extractNavigatorFactFromAdmittedSession(
1294
1264
  sessionFile: string,
1295
1265
  runDirectory: string,
@@ -1495,7 +1465,7 @@ async function finishLawfulSeat(
1495
1465
  : await publishDeclaredSeatTerminal(admitted, roleOutcome, coordinates, entries, scope);
1496
1466
  const terminal = await attachEngineDetourToolUsage({
1497
1467
  roleOutcome,
1498
- navigator: extractNavigatorFact(entries),
1468
+ navigator: isNavigatorSeat(admitted.role) ? NAVIGATOR_SEAT_OWN_FACT : extractNavigatorFact(entries),
1499
1469
  artifacts,
1500
1470
  runId: admitted.runId,
1501
1471
  ...(submissionToolCallId === undefined || submissionToolCallId.length === 0
@@ -1698,11 +1668,13 @@ export async function settleFailureTerminalResult(
1698
1668
  const coordinates = coordinatesFromAdmitted(authority, admitted);
1699
1669
  const { sessionDirectory, sessionFile } = coordinates;
1700
1670
  // Exact-session attendance only — never infer no-advice from caller omission.
1701
- const navigator = await extractNavigatorFactFromAdmittedSession(
1702
- sessionFile,
1703
- admitted.runDirectory,
1704
- options,
1705
- );
1671
+ const navigator = isNavigatorSeat(admitted.role)
1672
+ ? NAVIGATOR_SEAT_OWN_FACT
1673
+ : await extractNavigatorFactFromAdmittedSession(
1674
+ sessionFile,
1675
+ admitted.runDirectory,
1676
+ options,
1677
+ );
1706
1678
  let artifacts: TerminalArtifactRef[] = [];
1707
1679
  if (options.previewOnly !== true) {
1708
1680
  try {
@@ -90,17 +90,12 @@ export type TerminalNavigatorFact =
90
90
  /** #959: navigator speaks prose; code does not parse or rank the advice. */
91
91
  disposition: "advice";
92
92
  prose: string;
93
- advisoryDiagnostic?: string;
94
- }
95
- | {
96
- disposition: "no-advice";
97
- advisoryDiagnostic?: string;
98
93
  }
94
+ | { disposition: "no-advice" }
99
95
  | {
100
96
  disposition: "unavailable";
101
97
  source: string;
102
98
  reason: string;
103
- advisoryDiagnostic?: string;
104
99
  };
105
100
 
106
101
  /**
@@ -163,15 +158,8 @@ export type TerminalResult = {
163
158
  * Build an advice navigator fact (#959). Prose is presented as submitted;
164
159
  * code does not parse route/next or judge usability.
165
160
  */
166
- export function adviceNavigatorFact(input: {
167
- prose: string;
168
- advisoryDiagnostic?: string;
169
- }): TerminalNavigatorFact {
170
- return {
171
- disposition: "advice",
172
- prose: input.prose,
173
- ...(input.advisoryDiagnostic === undefined ? {} : { advisoryDiagnostic: input.advisoryDiagnostic }),
174
- };
161
+ export function adviceNavigatorFact(input: { prose: string }): TerminalNavigatorFact {
162
+ return { disposition: "advice", prose: input.prose };
175
163
  }
176
164
 
177
165
  /**
@@ -221,9 +209,6 @@ export function formatTerminalResult(result: TerminalResult): string {
221
209
  }
222
210
  }
223
211
  lines.push(`navigator\t${result.navigator.disposition}`);
224
- if (result.navigator.advisoryDiagnostic !== undefined) {
225
- lines.push(`navigator-advisory\t${encodeTerminalField(result.navigator.advisoryDiagnostic)}`);
226
- }
227
212
  if (result.navigator.disposition === "advice") {
228
213
  // #959: present navigator prose as-is — no next/reason/command parsing.
229
214
  lines.push(`prose\t${encodeTerminalField(result.navigator.prose)}`);
@@ -70,8 +70,6 @@ export type RoleTurnRequestProjectionOptions = {
70
70
  invocationScopeId?: string;
71
71
  /** Station child role run (#840): omit automatic navigator attendance. */
72
72
  readonly stationChild?: boolean;
73
- /** #1160 attendance auto byStatus prepare (not direct navigator prose). */
74
- readonly navigatorByStatusPrepare?: boolean;
75
73
  /**
76
74
  * #1132: the one effective delivery-request ceiling (#422 single resolve by
77
75
  * the caller). Projected so the host adapter's own re-ask loop and the AK
@@ -125,9 +123,6 @@ export function projectRoleTurnRequest(
125
123
  ? {}
126
124
  : { invocationScopeId: options.invocationScopeId }),
127
125
  ...(options.stationChild === undefined ? {} : { stationChild: options.stationChild }),
128
- ...(options.navigatorByStatusPrepare === undefined
129
- ? {}
130
- : { navigatorByStatusPrepare: options.navigatorByStatusPrepare }),
131
126
  ...(options.deliveryRequestLimit === undefined
132
127
  ? {}
133
128
  : { deliveryRequestLimit: options.deliveryRequestLimit }),
@@ -122,11 +122,6 @@ export type PublicSummonRequest = {
122
122
  * (#946 / ADR 0082).
123
123
  */
124
124
  readonly stationChild?: boolean;
125
- /**
126
- * #1160 attendance auto byStatus prepare. Nested navigator only — never set
127
- * on direct `ak-role navigator` (keeps free-form prose exit).
128
- */
129
- readonly navigatorByStatusPrepare?: boolean;
130
125
  };
131
126
 
132
127
  const execFileAsync = promisify(execFile);
@@ -404,9 +399,6 @@ export async function summonPublicRole(
404
399
  // Nested court stations keep station-child semantics; dual-lens
405
400
  // ordinary Reviewer axes opt out (#946 / ADR 0082).
406
401
  ...(options.stationChild === false ? {} : { stationChild: true }),
407
- ...(options.navigatorByStatusPrepare === true
408
- ? { navigatorByStatusPrepare: true as const }
409
- : {}),
410
402
  // Forward composition-root adapters so nested stations (e.g.
411
403
  // secretariat → diarist) select the same faux/production table (#924).
412
404
  ...(options.hostAdapters === undefined
@@ -152,27 +152,6 @@ export function createReceiptDeliveryPolicy(limit?: number) {
152
152
  deliveryTurns += 1;
153
153
  spend();
154
154
  },
155
- /**
156
- * Stop asking. The issued count stays whatever was actually sent (#1132 —
157
- * do not fill the remainder up to the ceiling).
158
- */
159
- closeBudget() { closed = true; },
160
- /**
161
- * A nested session settled without an accepted receipt. Close so this layer
162
- * does not open another prompt on that session. The issued count stays the
163
- * larger of the two seams: a nested zero must not wipe prompts this layer
164
- * already sent, and adding the two counts would bill one send twice.
165
- */
166
- recordNestedNoReceipt(facts: Partial<NoReceiptLifecycleFacts>) {
167
- if (typeof facts.terminalToolCalled === "boolean") {
168
- terminalToolCalled = terminalToolCalled || facts.terminalToolCalled;
169
- }
170
- if (facts.rejectedReceipts !== undefined) {
171
- rejectedReceipts.push(...facts.rejectedReceipts);
172
- }
173
- if (facts.deliveryTurns !== undefined) deliveryTurns = Math.max(deliveryTurns, facts.deliveryTurns);
174
- closed = true;
175
- },
176
155
  nextAction(): "accepted" | "request-delivery" | "no-receipt" {
177
156
  if (accepted) return "accepted";
178
157
  if (closed) return "no-receipt";
@@ -2,8 +2,8 @@ import { readFile } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
3
 
4
4
  import { loadDoctorCase } from "./doctor-evidence.ts";
5
- import { createNativeNavigatorSessionFactory, createNavigatorAttendance } from "./navigator-attendance.ts";
6
- import { loadNavigatorWorkContext } from "./navigator-work-context.ts";
5
+ import { createNavigatorAttendance } from "./navigator-attendance.ts";
6
+ import { createNavigatorLookup } from "./navigator-lookup.ts";
7
7
  import { loadNotarySourceRunLocator } from "./notary-source-run.ts";
8
8
  import { type RoleRuntimeDependencies } from "./role-runtime.ts";
9
9
  import {
@@ -40,7 +40,7 @@ export function createRoleRuntimeDependencies(packageRoot: string): RoleRuntimeD
40
40
  // packageRoot is the install root (resources/ lives there). Never resolve via
41
41
  // import.meta.url — headless/acp production-host bundles live under dist/*/
42
42
  // and would otherwise look for dist/resources/ (#962).
43
- const navigatorSessionFactory = createNativeNavigatorSessionFactory();
43
+ const navigatorLookup = createNavigatorLookup();
44
44
  return {
45
45
  packageRoot,
46
46
  loadRoleReferenceMaterials: loadPackagedRoleReferenceMaterials,
@@ -48,20 +48,13 @@ export function createRoleRuntimeDependencies(packageRoot: string): RoleRuntimeD
48
48
  loadDoctorCase,
49
49
  loadNotarySourceRun: loadNotarySourceRunLocator,
50
50
  loadMergerInput: async (path) => JSON.parse(await readFile(path, "utf8")),
51
- loadNavigatorWorkContext: (options) => loadNavigatorWorkContext({
52
- context: options.context,
53
- role: options.role,
54
- ...(options.getFlag === undefined ? {} : { getFlag: options.getFlag }),
55
- }),
56
51
  createNavigatorAttendance: (options) => createNavigatorAttendance({
57
52
  context: options.context,
58
53
  role: options.role,
59
54
  phase: options.phase,
60
55
  subjectKey: options.subjectKey,
61
56
  invocationId: options.invocationId,
62
- createSession: navigatorSessionFactory,
63
- ...(options.deliveryRequestLimit === undefined ? {} : { deliveryRequestLimit: options.deliveryRequestLimit }),
64
- ...(options.contextError === undefined ? {} : { contextError: options.contextError }),
57
+ lookup: navigatorLookup,
65
58
  onEvent: options.onEvent,
66
59
  }),
67
60
  };