@akagilnc/pi-workflow-roles 0.1.3262 → 0.1.3280

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 (35) hide show
  1. package/README.md +8 -122
  2. package/README.zh-CN.md +9 -123
  3. package/dist/gatekeeper-role.js +22 -16
  4. package/dist/grok/production-host.js +745 -571
  5. package/dist/package-contracts/gatekeeper-output.js +71 -0
  6. package/dist/package-contracts/navigator-output.js +48 -0
  7. package/dist/package-contracts/terminating-tools.js +18 -2
  8. package/dist/packaged-role-registry.js +24 -0
  9. package/dist/public-cli/config.js +7 -21
  10. package/dist/public-cli/main.js +689 -365
  11. package/dist/public-cli/registry.js +2 -14
  12. package/dist/session-opening-materials.js +6 -11
  13. package/extensions/role-runtime.ts +3 -1
  14. package/package.json +1 -1
  15. package/resources/navigator-route-playbook.md +1 -1
  16. package/src/gatekeeper-role.ts +32 -17
  17. package/src/grok/production-host.ts +3 -1
  18. package/src/host-contracts.ts +3 -1
  19. package/src/navigator-role.ts +17 -0
  20. package/src/package-contracts/gatekeeper-output.ts +89 -0
  21. package/src/package-contracts/navigator-output.ts +59 -0
  22. package/src/package-contracts/terminating-tools.ts +24 -2
  23. package/src/packaged-role-registry.ts +25 -2
  24. package/src/pi/role-turn-host.ts +4 -0
  25. package/src/public-cli/cli.ts +37 -10
  26. package/src/public-cli/config.ts +6 -30
  27. package/src/public-cli/instruction-seat-run.ts +147 -0
  28. package/src/public-cli/invocation.ts +47 -3
  29. package/src/public-cli/option-definitions.ts +36 -3
  30. package/src/public-cli/registry.ts +3 -26
  31. package/src/public-cli/run-lifecycle.ts +8 -2
  32. package/src/public-cli/settlement.ts +115 -3
  33. package/src/public-cli/terminal.ts +3 -1
  34. package/src/role-runtime.ts +64 -1
  35. package/src/session-opening-materials.ts +6 -11
@@ -102,6 +102,16 @@ import {
102
102
  inspectorDecisiveFacts,
103
103
  validateRecordedInspectorOutput,
104
104
  } from "../inspector-contracts.ts";
105
+ import {
106
+ GATEKEEPER_OUTPUT_TOOL_NAME,
107
+ gatekeeperDecisiveFacts,
108
+ validateRecordedGatekeeperOutput,
109
+ } from "../package-contracts/gatekeeper-output.ts";
110
+ import {
111
+ NAVIGATOR_OUTPUT_TOOL_NAME,
112
+ navigatorDecisiveFacts,
113
+ validateRecordedNavigatorOutput,
114
+ } from "../package-contracts/navigator-output.ts";
105
115
  import {
106
116
  observePackagedMethodSkillInvocation,
107
117
  type ObservedPackagedMethodSkillInvocation,
@@ -136,6 +146,8 @@ import {
136
146
  type AdmittedCountersignInvocation,
137
147
  type AdmittedGleanerLeftInvocation,
138
148
  type AdmittedInspectorInvocation,
149
+ type AdmittedGatekeeperInvocation,
150
+ type AdmittedNavigatorInvocation,
139
151
  type AdmittedNotaryInvocation,
140
152
  type AdmittedReviewerInvocation,
141
153
  type AdmittedRoleInvocation,
@@ -3116,7 +3128,13 @@ export async function trySettleDoctorTerminalResult(
3116
3128
  * Role-specific validator / decisiveFacts / diagnostics stay on the seat.
3117
3129
  */
3118
3130
  type OneShotAcceptedSettlementSpec = {
3119
- readonly role: "notary" | "countersign" | "gleaner-left" | "inspector";
3131
+ readonly role:
3132
+ | "notary"
3133
+ | "countersign"
3134
+ | "gleaner-left"
3135
+ | "inspector"
3136
+ | "gatekeeper"
3137
+ | "navigator";
3120
3138
  readonly toolName: string;
3121
3139
  readonly nonUsableDiagnostic: string;
3122
3140
  readonly projectAccepted: (
@@ -3144,7 +3162,13 @@ function currentAttemptStartIndex(entries: readonly SessionEntry[]): number {
3144
3162
  }
3145
3163
 
3146
3164
  async function settleLawfulOneShotAcceptedTerminalResult(
3147
- admitted: AdmittedNotaryInvocation | AdmittedCountersignInvocation | AdmittedGleanerLeftInvocation | AdmittedInspectorInvocation,
3165
+ admitted:
3166
+ | AdmittedNotaryInvocation
3167
+ | AdmittedCountersignInvocation
3168
+ | AdmittedGleanerLeftInvocation
3169
+ | AdmittedInspectorInvocation
3170
+ | AdmittedGatekeeperInvocation
3171
+ | AdmittedNavigatorInvocation,
3148
3172
  authority: DurablePrincipalAuthority,
3149
3173
  spec: OneShotAcceptedSettlementSpec,
3150
3174
  ): Promise<TerminalResult | undefined> {
@@ -3197,10 +3221,22 @@ async function settleLawfulOneShotAcceptedTerminalResult(
3197
3221
  }
3198
3222
  return undefined;
3199
3223
  }
3224
+ if (!spec.tryAcceptDetails(roleOutcome.decisiveFacts)) {
3225
+ return settleFailureTerminalResult(
3226
+ admitted,
3227
+ {
3228
+ cause: "output",
3229
+ diagnostic: spec.nonUsableDiagnostic,
3230
+ details: { candidate: roleOutcome.decisiveFacts, acceptedReceipt: false },
3231
+ },
3232
+ authority,
3233
+ );
3234
+ }
3235
+ const acceptedOutcome = spec.projectAccepted(roleOutcome);
3200
3236
  const navigator = extractNavigatorFact(entries);
3201
3237
  return withOptionalGateProjection(
3202
3238
  {
3203
- roleOutcome: spec.projectAccepted(roleOutcome),
3239
+ roleOutcome: acceptedOutcome,
3204
3240
  navigator,
3205
3241
  artifacts: [],
3206
3242
  runId: admitted.runId,
@@ -3415,6 +3451,82 @@ export async function trySettleInspectorTerminalResult(
3415
3451
  return settleLawfulInspectorTerminalResult(admitted, authority);
3416
3452
  }
3417
3453
 
3454
+ /** Lawful Gatekeeper accepted outcome (dispatch | pass, #639). */
3455
+ export type LawfulGatekeeperRoleOutcome = {
3456
+ kind: "accepted";
3457
+ role: "gatekeeper";
3458
+ status: string;
3459
+ decisiveFacts: Readonly<Record<string, unknown>>;
3460
+ };
3461
+
3462
+ async function settleLawfulGatekeeperTerminalResult(
3463
+ admitted: AdmittedGatekeeperInvocation,
3464
+ authority: DurablePrincipalAuthority,
3465
+ ): Promise<TerminalResult | undefined> {
3466
+ return settleLawfulOneShotAcceptedTerminalResult(admitted, authority, {
3467
+ role: "gatekeeper",
3468
+ toolName: GATEKEEPER_OUTPUT_TOOL_NAME,
3469
+ nonUsableDiagnostic: "门下省决议无显式 dispatch/pass",
3470
+ tryAcceptDetails: tryAcceptWithValidator(validateRecordedGatekeeperOutput),
3471
+ projectAccepted: (sealed) => {
3472
+ const output = validateRecordedGatekeeperOutput(sealed.decisiveFacts);
3473
+ const accepted: LawfulGatekeeperRoleOutcome = {
3474
+ kind: "accepted",
3475
+ role: "gatekeeper",
3476
+ status: output.status,
3477
+ decisiveFacts: gatekeeperDecisiveFacts(output),
3478
+ };
3479
+ return accepted;
3480
+ },
3481
+ });
3482
+ }
3483
+
3484
+ /** Try to settle a lawful Gatekeeper Terminal; undefined only for genuine absence. */
3485
+ export async function trySettleGatekeeperTerminalResult(
3486
+ admitted: AdmittedGatekeeperInvocation,
3487
+ authority: DurablePrincipalAuthority,
3488
+ ): Promise<TerminalResult | undefined> {
3489
+ return settleLawfulGatekeeperTerminalResult(admitted, authority);
3490
+ }
3491
+
3492
+ /** Lawful Navigator accepted outcome (route advice, #639). */
3493
+ export type LawfulNavigatorRoleOutcome = {
3494
+ kind: "accepted";
3495
+ role: "navigator";
3496
+ status: string;
3497
+ decisiveFacts: Readonly<Record<string, unknown>>;
3498
+ };
3499
+
3500
+ async function settleLawfulNavigatorTerminalResult(
3501
+ admitted: AdmittedNavigatorInvocation,
3502
+ authority: DurablePrincipalAuthority,
3503
+ ): Promise<TerminalResult | undefined> {
3504
+ return settleLawfulOneShotAcceptedTerminalResult(admitted, authority, {
3505
+ role: "navigator",
3506
+ toolName: NAVIGATOR_OUTPUT_TOOL_NAME,
3507
+ nonUsableDiagnostic: "游奕使回执无显式路线建议",
3508
+ tryAcceptDetails: tryAcceptWithValidator(validateRecordedNavigatorOutput),
3509
+ projectAccepted: (sealed) => {
3510
+ const output = validateRecordedNavigatorOutput(sealed.decisiveFacts);
3511
+ const accepted: LawfulNavigatorRoleOutcome = {
3512
+ kind: "accepted",
3513
+ role: "navigator",
3514
+ status: "advice",
3515
+ decisiveFacts: navigatorDecisiveFacts(output),
3516
+ };
3517
+ return accepted;
3518
+ },
3519
+ });
3520
+ }
3521
+
3522
+ /** Try to settle a lawful Navigator Terminal; undefined only for genuine absence. */
3523
+ export async function trySettleNavigatorTerminalResult(
3524
+ admitted: AdmittedNavigatorInvocation,
3525
+ authority: DurablePrincipalAuthority,
3526
+ ): Promise<TerminalResult | undefined> {
3527
+ return settleLawfulNavigatorTerminalResult(admitted, authority);
3528
+ }
3529
+
3418
3530
  /** Try to settle a lawful Coder Terminal; undefined only for genuine absence. */
3419
3531
  export async function trySettleCoderTerminalResult(
3420
3532
  admitted: AdmittedCoderInvocation,
@@ -38,7 +38,9 @@ export type TerminalRoleName =
38
38
  | "notary"
39
39
  | "countersign"
40
40
  | "gleaner-left"
41
- | "inspector";
41
+ | "inspector"
42
+ | "gatekeeper"
43
+ | "navigator";
42
44
 
43
45
  /** Merger/Collector residual only — Notary/audit residual abolished (#475). */
44
46
  export type ResidualIncompleteTerminalOutcome = {
@@ -74,6 +74,16 @@ import {
74
74
  type InspectorRuntimeDependencies,
75
75
  } from "./inspector-role.ts";
76
76
  import { INSPECTOR_ACCEPTED_TEXT } from "./inspector-contracts.ts";
77
+ import {
78
+ GATEKEEPER_TOOL_SPEC,
79
+ type GatekeeperRuntimeDependencies,
80
+ } from "./gatekeeper-role.ts";
81
+ import {
82
+ NAVIGATOR_TOOL_SPEC,
83
+ type NavigatorRuntimeDependencies,
84
+ } from "./navigator-role.ts";
85
+ import { GATEKEEPER_ACCEPTED_TEXT } from "./package-contracts/gatekeeper-output.ts";
86
+ import { NAVIGATOR_ACCEPTED_TEXT } from "./package-contracts/navigator-output.ts";
77
87
  import { decorateSettlementWithNavigation, formatNavigatorReport, NAVIGATOR_EVENT_TYPE, navigatorSubjectKey, navigatorUnavailableError, subjectPath, type NavigatorAttendance, type NavigatorAttendanceOptions, type NavigatorEvent, type NavigatorPhase, type NavigatorReport, type NavigatorSettlement, type NavigatorSubjectProvenance, type NavigatorTargetRole, type NavigatorWorkContext } from "./navigator-attendance.ts";
78
88
  import {
79
89
  buildNavigatorInfrastructureFailureFact,
@@ -337,7 +347,6 @@ export type { AuditorDecisionTool } from "./evidence-child-executor.ts";
337
347
  export {
338
348
  NOTARY_OUTPUT_TOOL,
339
349
  INSPECTOR_OUTPUT_TOOL,
340
- GATEKEEPER_OUTPUT_TOOL,
341
350
  GatekeeperDecisionError,
342
351
  createGatekeeperOutputTool,
343
352
  createOfficerDecisionTool,
@@ -443,6 +452,8 @@ type ActivationRuntime = {
443
452
  countersign: { activate(): Promise<void> };
444
453
  gleanerLeft: { activate(): Promise<void> };
445
454
  inspector: { activate(): Promise<void> };
455
+ gatekeeper: { activate(): Promise<void> };
456
+ navigator: { activate(): Promise<void> };
446
457
  merger(): Promise<void>;
447
458
  };
448
459
 
@@ -489,6 +500,8 @@ function activationStage(role: PackagedRole, runtime: ActivationRuntime): { id:
489
500
  case "countersign": return { id: "load-and-install", run: async () => runtime.countersign.activate() };
490
501
  case "gleaner-left": return { id: "load-and-install", run: async () => runtime.gleanerLeft.activate() };
491
502
  case "inspector": return { id: "load-and-install", run: async () => runtime.inspector.activate() };
503
+ case "gatekeeper": return { id: "load-and-install", run: async () => runtime.gatekeeper.activate() };
504
+ case "navigator": return { id: "load-and-install", run: async () => runtime.navigator.activate() };
492
505
  case "merger": return { id: "prepare-git-and-install", run: async () => runtime.merger() };
493
506
  }
494
507
  }
@@ -594,6 +607,8 @@ export type RoleRuntimeDependencies = {
594
607
  loadCountersignSoul?(): Promise<string>;
595
608
  loadGleanerLeftSoul?(): Promise<string>;
596
609
  loadInspectorSoul?(): Promise<string>;
610
+ loadGatekeeperSoul?(): Promise<string>;
611
+ loadNavigatorSoul?(): Promise<string>;
597
612
  loadDoctorCase?(path: string): Promise<import("./doctor-contracts.ts").DoctorCase>;
598
613
  loadMergerSoul?(): Promise<string>;
599
614
  loadMergerInput?(path: string): Promise<unknown>;
@@ -930,6 +945,40 @@ export function createInspectorRoleRuntime(
930
945
  );
931
946
  }
932
947
 
948
+ /** #639: direct Gatekeeper public seat on the shared filed-officer envelope. */
949
+ export function createGatekeeperRoleRuntime(
950
+ roleHost: RoleHost,
951
+ dependencies: GatekeeperRuntimeDependencies,
952
+ ) {
953
+ return createFiledOfficerRuntime(
954
+ roleHost,
955
+ {
956
+ role: "gatekeeper",
957
+ tool: GATEKEEPER_TOOL_SPEC,
958
+ acceptedText: GATEKEEPER_ACCEPTED_TEXT,
959
+ soulTag: "gatekeeper",
960
+ },
961
+ dependencies,
962
+ );
963
+ }
964
+
965
+ /** #639: direct Navigator public seat on the shared filed-officer envelope. */
966
+ export function createNavigatorRoleRuntime(
967
+ roleHost: RoleHost,
968
+ dependencies: NavigatorRuntimeDependencies,
969
+ ) {
970
+ return createFiledOfficerRuntime(
971
+ roleHost,
972
+ {
973
+ role: "navigator",
974
+ tool: NAVIGATOR_TOOL_SPEC,
975
+ acceptedText: NAVIGATOR_ACCEPTED_TEXT,
976
+ soulTag: "navigator",
977
+ },
978
+ dependencies,
979
+ );
980
+ }
981
+
933
982
  export function createCountersignRoleRuntime(
934
983
  roleHost: RoleHost,
935
984
  dependencies: CountersignRuntimeDependencies,
@@ -1435,6 +1484,18 @@ export function createRoleRuntimeExtension(
1435
1484
  return dependencies.loadInspectorSoul();
1436
1485
  },
1437
1486
  });
1487
+ const gatekeeper = createGatekeeperRoleRuntime(roleHost, {
1488
+ async loadSoul() {
1489
+ if (!dependencies.loadGatekeeperSoul) throw new Error("Gatekeeper runtime dependencies are not configured");
1490
+ return dependencies.loadGatekeeperSoul();
1491
+ },
1492
+ });
1493
+ const navigator = createNavigatorRoleRuntime(roleHost, {
1494
+ async loadSoul() {
1495
+ if (!dependencies.loadNavigatorSoul) throw new Error("Navigator runtime dependencies are not configured");
1496
+ return dependencies.loadNavigatorSoul();
1497
+ },
1498
+ });
1438
1499
  let sessionMergerGitState = dependencies.mergerGitState;
1439
1500
  const merger = createMergerRoleRuntime(roleHost, {
1440
1501
  async loadSoul() { if (!dependencies.loadMergerSoul) throw new Error("Merger runtime dependencies are not configured"); return dependencies.loadMergerSoul(); },
@@ -1583,6 +1644,8 @@ export function createRoleRuntimeExtension(
1583
1644
  countersign,
1584
1645
  gleanerLeft,
1585
1646
  inspector,
1647
+ gatekeeper,
1648
+ navigator,
1586
1649
  merger: async () => {
1587
1650
  if (dependencies.mergerGitState === undefined) {
1588
1651
  sessionMergerGitState = dependencies.createMergerGitState?.(ctx.cwd);
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Session opening materials (#443 / #524). Missing files fail as native readFile
3
- * errors. Main-role materials derive from PUBLIC_ROLE_RECORDS; gatekeeper seats
4
- * stay independent except notary (shared NOTARY_SESSION_MATERIALS). Navigator is
5
- * name-only here, not a public role record. Auditor composition stays in
3
+ * errors. Main-role materials derive from PUBLIC_ROLE_RECORDS (including
4
+ * gatekeeper and navigator). Province map reuses that public gatekeeper record
5
+ * plus officer material constants (notary shared). Auditor composition stays in
6
6
  * loadAuditorSoul; loaders share joinPackageMaterials.
7
7
  */
8
8
  import { existsSync } from "node:fs";
@@ -61,12 +61,11 @@ type PublicRoleMaterials = {
61
61
  >["sessionMaterials"];
62
62
  };
63
63
 
64
- /** Derived projection: public records + navigator name-only materials. */
64
+ /** Derived projection: public records (#639 includes navigator/gatekeeper). */
65
65
  export const MAIN_ROLE_SESSION_MATERIALS = {
66
66
  ...(Object.fromEntries(
67
67
  PUBLIC_ROLE_RECORDS.map((record) => [record.role, record.sessionMaterials]),
68
68
  ) as PublicRoleMaterials),
69
- navigator: ["CLAUDE.md", "souls/navigator.md"] as const,
70
69
  } as const;
71
70
 
72
71
  export type MainRoleSession = keyof typeof MAIN_ROLE_SESSION_MATERIALS;
@@ -79,12 +78,8 @@ export function loadMainRoleSessionMaterials(
79
78
 
80
79
  /** Gatekeeper province; notary reuses the public notary materials definition. */
81
80
  export const GATEKEEPER_SESSION_MATERIALS = {
82
- gatekeeper: [
83
- "CLAUDE.md",
84
- "souls/gatekeeper.md",
85
- "souls/quality-law.md",
86
- "souls/gate-output-guide.md",
87
- ],
81
+ // #639: single authority — the public gatekeeper record owns the province list.
82
+ gatekeeper: PUBLIC_ROLE_RECORDS.find((entry) => entry.role === "gatekeeper")!.sessionMaterials,
88
83
  inspector: INSPECTOR_SESSION_MATERIALS,
89
84
  notary: NOTARY_SESSION_MATERIALS,
90
85
  } as const;