@akagilnc/pi-workflow-roles 0.1.4800 → 0.1.4870

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 (143) hide show
  1. package/dist/acp-host/production-host.js +19434 -18218
  2. package/dist/analyst-book-key.js +63 -0
  3. package/dist/analyst-cohort.js +167 -0
  4. package/dist/analyst-entry.js +320 -0
  5. package/dist/analyst-index.js +247 -0
  6. package/dist/analyst-ledger.js +561 -0
  7. package/dist/analyst-median.js +16 -0
  8. package/dist/analyst-metric-families/acceptance-success-rework.js +249 -0
  9. package/dist/analyst-metric-families/b2-frame-buckets-actions.js +189 -0
  10. package/dist/analyst-metric-families/gate-cycles.js +77 -0
  11. package/dist/analyst-metric-families/leg-wall-clock.js +56 -0
  12. package/dist/analyst-metric-families/round-timeline.js +126 -0
  13. package/dist/analyst-metric-families.js +23 -0
  14. package/dist/analyst-metric-family.js +11 -0
  15. package/dist/analyst-model-groups.js +135 -0
  16. package/dist/analyst-page.js +182 -0
  17. package/dist/atomic-write.js +23 -0
  18. package/dist/auditor-soul.js +1 -1
  19. package/dist/countersign-contracts.js +0 -2
  20. package/dist/diarist-contracts.js +0 -1
  21. package/dist/doctor-contracts.js +2 -2
  22. package/dist/gatekeeper-role.js +15 -16
  23. package/dist/gleaner-left-contracts.js +0 -2
  24. package/dist/headless-host/production-host.js +16967 -15749
  25. package/dist/host-contracts.js +0 -4
  26. package/dist/inspector-contracts.js +0 -2
  27. package/dist/institutional-resolution.js +4 -2
  28. package/dist/merger-contracts.js +0 -2
  29. package/dist/migrate-book-topology.js +3908 -3089
  30. package/dist/navigator-public-session.js +4 -3
  31. package/dist/notary-contracts.js +0 -2
  32. package/dist/package-contracts/auditor-output.js +0 -1
  33. package/dist/package-contracts/collector-output.js +0 -2
  34. package/dist/package-contracts/fixer-output.js +0 -2
  35. package/dist/package-contracts/gatekeeper-output.js +0 -2
  36. package/dist/package-contracts/judge-output.js +0 -2
  37. package/dist/package-contracts/navigator-output.js +0 -2
  38. package/dist/package-contracts/reviewer-output.js +0 -2
  39. package/dist/package-contracts/terminating-tools.js +32 -92
  40. package/dist/package-contracts/worker-output.js +0 -4
  41. package/dist/packaged-role-registry.js +518 -36
  42. package/dist/pi/role-turn-host.js +2 -1
  43. package/dist/public-cli/analyst-run.js +185 -0
  44. package/dist/public-cli/cli.js +885 -0
  45. package/dist/public-cli/config.js +12 -9
  46. package/dist/public-cli/countersign-run.js +4 -311
  47. package/dist/public-cli/instruction-seat-run.js +628 -158
  48. package/dist/public-cli/invocation.js +806 -1550
  49. package/dist/public-cli/main.js +6962 -9882
  50. package/dist/public-cli/option-definitions.js +51 -99
  51. package/dist/public-cli/post-admission.js +30 -2
  52. package/dist/public-cli/run-lifecycle.js +234 -353
  53. package/dist/public-cli/seat-ticket-binding.js +6 -0
  54. package/dist/public-cli/settlement.js +261 -675
  55. package/dist/public-cli/turn-request.js +76 -0
  56. package/dist/public-role-summons.js +38 -112
  57. package/dist/role-activation-flags.js +23 -45
  58. package/dist/secretariat-contracts.js +0 -2
  59. package/dist/session-identity.js +17 -8
  60. package/dist/session-opening-materials.js +3 -2
  61. package/extensions/role-runtime.ts +6 -80
  62. package/package.json +1 -1
  63. package/souls/coder.md +1 -2
  64. package/src/acp-host/role-turn-host.ts +4 -1
  65. package/src/analyst-metric-families/acceptance-success-rework.ts +3 -2
  66. package/src/auditor-role.ts +1 -2
  67. package/src/auditor-soul.ts +1 -1
  68. package/src/collector-role.ts +2 -2
  69. package/src/countersign-contracts.ts +0 -1
  70. package/src/countersign-role.ts +1 -1
  71. package/src/diarist-contracts.ts +0 -1
  72. package/src/diarist-role.ts +0 -1
  73. package/src/doctor-auditor.ts +1 -2
  74. package/src/doctor-contracts.ts +1 -1
  75. package/src/doctor-role.ts +3 -2
  76. package/src/external-host-turn-loop.ts +1 -1
  77. package/src/factory-board.ts +10 -7
  78. package/src/gatekeeper-role.ts +16 -10
  79. package/src/gleaner-left-contracts.ts +0 -1
  80. package/src/gleaner-left-role.ts +0 -1
  81. package/src/headless-host/role-turn-host.ts +7 -1
  82. package/src/host-contracts.ts +10 -6
  83. package/src/inspector-contracts.ts +0 -1
  84. package/src/inspector-role.ts +0 -2
  85. package/src/institutional-resolution.ts +6 -4
  86. package/src/judge-role.ts +3 -3
  87. package/src/merger-contracts.ts +0 -1
  88. package/src/merger-role.ts +2 -2
  89. package/src/navigator-public-session.ts +7 -6
  90. package/src/navigator-work-context.ts +6 -8
  91. package/src/notary-contracts.ts +0 -1
  92. package/src/notary-role.ts +2 -3
  93. package/src/package-contracts/auditor-output.ts +0 -1
  94. package/src/package-contracts/collector-output.ts +0 -1
  95. package/src/package-contracts/fixer-output.ts +0 -1
  96. package/src/package-contracts/gatekeeper-output.ts +0 -1
  97. package/src/package-contracts/judge-output.ts +0 -1
  98. package/src/package-contracts/navigator-output.ts +0 -1
  99. package/src/package-contracts/reviewer-output.ts +0 -1
  100. package/src/package-contracts/terminating-tools.ts +27 -99
  101. package/src/package-contracts/worker-output.ts +0 -2
  102. package/src/packaged-role-registry.ts +604 -35
  103. package/src/pi/role-turn-host.ts +2 -1
  104. package/src/public-cli/cli.ts +64 -259
  105. package/src/public-cli/config.ts +18 -10
  106. package/src/public-cli/countersign-run.ts +14 -449
  107. package/src/public-cli/instruction-seat-run.ts +758 -277
  108. package/src/public-cli/invocation.ts +1097 -2051
  109. package/src/public-cli/option-definitions.ts +62 -127
  110. package/src/public-cli/post-admission.ts +47 -2
  111. package/src/public-cli/run-lifecycle.ts +303 -613
  112. package/src/public-cli/seat-ticket-binding.ts +6 -0
  113. package/src/public-cli/settlement.ts +399 -1185
  114. package/src/public-cli/turn-request.ts +92 -1
  115. package/src/public-role-summons.ts +44 -128
  116. package/src/reviewer-role.ts +3 -2
  117. package/src/role-activation-flags.ts +20 -41
  118. package/src/role-runtime-dependencies.ts +25 -26
  119. package/src/role-runtime.ts +121 -232
  120. package/src/secretariat-contracts.ts +0 -1
  121. package/src/secretariat-role.ts +0 -2
  122. package/src/session-identity.ts +23 -8
  123. package/src/session-opening-materials.ts +2 -1
  124. package/src/worker-role.ts +3 -4
  125. package/dist/doctor-auditor.js +0 -25
  126. package/dist/public-cli/diarist-run.js +0 -130
  127. package/dist/public-cli/doctor-run.js +0 -87
  128. package/dist/public-cli/inspector-run.js +0 -151
  129. package/dist/public-cli/judge-run.js +0 -114
  130. package/dist/public-cli/notary-run.js +0 -174
  131. package/dist/public-cli/reviewer-run.js +0 -339
  132. package/src/public-cli/coder-run.ts +0 -255
  133. package/src/public-cli/collector-run.ts +0 -189
  134. package/src/public-cli/diarist-run.ts +0 -233
  135. package/src/public-cli/doctor-run.ts +0 -167
  136. package/src/public-cli/fixer-run.ts +0 -265
  137. package/src/public-cli/gleaner-left-run.ts +0 -167
  138. package/src/public-cli/inspector-run.ts +0 -261
  139. package/src/public-cli/judge-run.ts +0 -196
  140. package/src/public-cli/merger-run.ts +0 -294
  141. package/src/public-cli/notary-run.ts +0 -279
  142. package/src/public-cli/reviewer-run.ts +0 -480
  143. package/src/public-cli/secretariat-run.ts +0 -265
@@ -1,4 +1,7 @@
1
1
  import { pickEngineAxis } from "../package-resources/engine-material.js";
2
+ import { resolvePackagedMethodSkillPath, } from "../package-resources/method-skill.js";
3
+ import { packagedRoleActivationFlags, packagedRoleMetadata, } from "../packaged-role-registry.js";
4
+ import { parentRunPathFromGatePointerInstruction } from "./run-lifecycle.js";
2
5
  export function projectRoleTurnRequest(admitted, roleDetails, options) {
3
6
  const cwd = options.cwd ?? admitted.projectRoot ?? admitted.repoRoot ?? admitted.cwd;
4
7
  if (cwd === undefined)
@@ -31,3 +34,76 @@ export function projectRoleTurnRequest(admitted, roleDetails, options) {
31
34
  ...(options.stationChild === undefined ? {} : { stationChild: options.stationChild }),
32
35
  };
33
36
  }
37
+ /**
38
+ * Packaged method this admitted run settles with.
39
+ * Coder carries one only on apply. Other seats read `settleMethod`.
40
+ */
41
+ export function packagedSettleSkill(admitted) {
42
+ const record = packagedRoleMetadata(admitted.role);
43
+ if (record === undefined)
44
+ return undefined;
45
+ if ("applyMethod" in record && record.applyMethod !== undefined) {
46
+ return "phase" in admitted && admitted.phase === "apply" ? record.applyMethod : undefined;
47
+ }
48
+ if ("settleMethod" in record && record.settleMethod !== undefined)
49
+ return record.settleMethod;
50
+ return undefined;
51
+ }
52
+ function readAdmittedPath(admitted, path) {
53
+ let current = admitted;
54
+ for (const key of path.split(".")) {
55
+ if (current === null || typeof current !== "object")
56
+ return undefined;
57
+ current = current[key];
58
+ }
59
+ return current;
60
+ }
61
+ /** Activation object for one admitted run. Field copies come from the composition-root record. */
62
+ function activationForAdmitted(admitted) {
63
+ if (packagedRoleMetadata(admitted.role) === undefined) {
64
+ throw new Error(`no turn projection for ${admitted.role}`);
65
+ }
66
+ const activation = { role: admitted.role };
67
+ for (const spec of packagedRoleActivationFlags(admitted.role)) {
68
+ let value = readAdmittedPath(admitted, spec.from ?? spec.field);
69
+ if (spec.fallback === "gate-pointer") {
70
+ const trimmed = typeof value === "string" ? value.trim() : "";
71
+ value = trimmed !== ""
72
+ ? trimmed
73
+ : parentRunPathFromGatePointerInstruction(admitted.instruction);
74
+ if (typeof value !== "string" || value === "")
75
+ continue;
76
+ }
77
+ if (value === undefined)
78
+ continue;
79
+ if (spec.text === true) {
80
+ if (typeof value !== "number")
81
+ continue;
82
+ value = String(value);
83
+ }
84
+ activation[spec.field] = value;
85
+ }
86
+ return activation;
87
+ }
88
+ /** Skill bindings declared on the composition-root record for this admitted run. */
89
+ function methodBindings(admitted, packageRoot) {
90
+ const record = packagedRoleMetadata(admitted.role);
91
+ const names = [];
92
+ if (record !== undefined && "methodSkills" in record && record.methodSkills !== undefined) {
93
+ names.push(...record.methodSkills);
94
+ }
95
+ const apply = packagedSettleSkill(admitted);
96
+ if (apply !== undefined && !names.includes(apply))
97
+ names.push(apply);
98
+ return names.map((name) => ({
99
+ kind: "skill",
100
+ path: resolvePackagedMethodSkillPath(packageRoot, name),
101
+ }));
102
+ }
103
+ /** Registry activation and method bindings for one admitted public seat. */
104
+ export function admittedSeatTurnDetails(admitted, packageRoot) {
105
+ return {
106
+ activation: activationForAdmitted(admitted),
107
+ methods: methodBindings(admitted, packageRoot),
108
+ };
109
+ }
@@ -236,118 +236,42 @@ async function summonPublicRole(options) {
236
236
  ...stderr2 === void 0 ? {} : { stderr: stderr2 }
237
237
  };
238
238
  }
239
- async function runPrepared(parse, run) {
239
+ async function runPrepared(parse2, run) {
240
240
  let parsedArgv;
241
241
  const prepared = await prepareSummonEnv(() => {
242
- parsedArgv = parse(options.argv);
242
+ parsedArgv = parse2(options.argv);
243
243
  });
244
244
  if (!prepared.ok) return { fail: projectPrepareFailure(prepared) };
245
245
  return { ok: await run(prepared.env, () => parsedArgv) };
246
246
  }
247
+ const [{ runPublicInstructionSeat, runPublicInstructionSeatResume }, { PUBLIC_ROLE_ARGV }] = await Promise.all([
248
+ import("./public-cli/instruction-seat-run.js"),
249
+ import("./public-cli/cli.js")
250
+ ]);
251
+ const { packagedRoleMetadata } = await import("./packaged-role-registry.js");
252
+ const record = packagedRoleMetadata(options.role);
253
+ const parse = ((args) => PUBLIC_ROLE_ARGV[options.role].parse(args));
254
+ const resumeRunId = record?.summonResume === true && typeof options.resumeRunId === "string" && options.resumeRunId.trim() !== "" ? options.resumeRunId.trim() : void 0;
247
255
  let result;
248
- switch (options.role) {
249
- case "notary": {
250
- const [{ runPublicNotary }, { parseNotaryArgv }] = await Promise.all([
251
- import("./public-cli/notary-run.js"),
252
- import("./public-cli/invocation.js")
253
- ]);
254
- const stepped = await runPrepared(parseNotaryArgv, (env, once) => runPublicNotary(options.argv, env, io, once));
255
- if ("fail" in stepped) return stepped.fail;
256
- result = stepped.ok;
257
- break;
258
- }
259
- case "inspector": {
260
- const [{ runPublicInspector }, { parseInspectorArgv }] = await Promise.all([
261
- import("./public-cli/inspector-run.js"),
262
- import("./public-cli/invocation.js")
263
- ]);
264
- const stepped = await runPrepared(parseInspectorArgv, (env, once) => runPublicInspector(options.argv, env, io, once));
265
- if ("fail" in stepped) return stepped.fail;
266
- result = stepped.ok;
267
- break;
268
- }
269
- case "auditor":
270
- case "navigator":
271
- case "gatekeeper": {
272
- const seat2 = options.role;
273
- const [{ runPublicInstructionSeat, runPublicInstructionSeatResume }, invocation] = await Promise.all([
274
- import("./public-cli/instruction-seat-run.js"),
275
- import("./public-cli/invocation.js")
276
- ]);
277
- const parse = seat2 === "auditor" ? invocation.parseAuditorArgv : seat2 === "navigator" ? invocation.parseNavigatorArgv : invocation.parseGatekeeperArgv;
278
- const resumeRunId = typeof options.resumeRunId === "string" && options.resumeRunId.trim() !== "" ? options.resumeRunId.trim() : void 0;
279
- if (resumeRunId !== void 0) {
280
- const instruction = options.argv[0] ?? "";
281
- const stepped = await runPrepared(parse, (env) => runPublicInstructionSeatResume(
282
- {
283
- runId: resumeRunId,
284
- summons: {
285
- instruction,
286
- instructionEmpty: instruction.trim() === ""
287
- }
288
- },
289
- env,
290
- io
291
- ));
292
- if ("fail" in stepped) return stepped.fail;
293
- result = stepped.ok;
294
- } else {
295
- const stepped = await runPrepared(parse, (env, once) => runPublicInstructionSeat(options.argv, env, io, seat2, once));
296
- if ("fail" in stepped) return stepped.fail;
297
- result = stepped.ok;
298
- }
299
- break;
300
- }
301
- case "judge": {
302
- const [{ runPublicJudge }, { parseJudgeArgv }] = await Promise.all([
303
- import("./public-cli/judge-run.js"),
304
- import("./public-cli/invocation.js")
305
- ]);
306
- const stepped = await runPrepared(parseJudgeArgv, (env, once) => runPublicJudge(options.argv, env, io, once));
307
- if ("fail" in stepped) return stepped.fail;
308
- result = stepped.ok;
309
- break;
310
- }
311
- case "doctor": {
312
- const [{ runPublicDoctor }, { parseDoctorArgv }] = await Promise.all([
313
- import("./public-cli/doctor-run.js"),
314
- import("./public-cli/invocation.js")
315
- ]);
316
- const stepped = await runPrepared(parseDoctorArgv, (env, once) => runPublicDoctor(options.argv, env, io, once));
317
- if ("fail" in stepped) return stepped.fail;
318
- result = stepped.ok;
319
- break;
320
- }
321
- case "diarist": {
322
- const [{ runPublicDiarist }, { parseDiaristArgv }] = await Promise.all([
323
- import("./public-cli/diarist-run.js"),
324
- import("./public-cli/invocation.js")
325
- ]);
326
- const stepped = await runPrepared(parseDiaristArgv, (env, once) => runPublicDiarist(options.argv, env, io, once));
327
- if ("fail" in stepped) return stepped.fail;
328
- result = stepped.ok;
329
- break;
330
- }
331
- case "countersign": {
332
- const [{ runPublicCountersign }, { parseCountersignArgv }] = await Promise.all([
333
- import("./public-cli/countersign-run.js"),
334
- import("./public-cli/invocation.js")
335
- ]);
336
- const stepped = await runPrepared(parseCountersignArgv, (env, once) => runPublicCountersign(options.argv, env, io, once));
337
- if ("fail" in stepped) return stepped.fail;
338
- result = stepped.ok;
339
- break;
340
- }
341
- case "reviewer": {
342
- const [{ runPublicReviewer }, { parseReviewerArgv }] = await Promise.all([
343
- import("./public-cli/reviewer-run.js"),
344
- import("./public-cli/invocation.js")
345
- ]);
346
- const stepped = await runPrepared(parseReviewerArgv, (env, once) => runPublicReviewer(options.argv, env, io, once));
347
- if ("fail" in stepped) return stepped.fail;
348
- result = stepped.ok;
349
- break;
350
- }
256
+ if (resumeRunId !== void 0) {
257
+ const instruction = options.argv[0] ?? "";
258
+ const stepped = await runPrepared(parse, (env) => runPublicInstructionSeatResume(
259
+ {
260
+ runId: resumeRunId,
261
+ summons: {
262
+ instruction,
263
+ instructionEmpty: instruction.trim() === ""
264
+ }
265
+ },
266
+ env,
267
+ io
268
+ ));
269
+ if ("fail" in stepped) return stepped.fail;
270
+ result = stepped.ok;
271
+ } else {
272
+ const stepped = await runPrepared(parse, (env, once) => runPublicInstructionSeat(options.argv, env, io, options.role, once));
273
+ if ("fail" in stepped) return stepped.fail;
274
+ result = stepped.ok;
351
275
  }
352
276
  const stderr = captured?.stderrText();
353
277
  const runDirectory = result.admitted?.runDirectory;
@@ -672,16 +596,18 @@ async function summonGateOfficer(options) {
672
596
  ...options.hostAdapters === void 0 ? {} : { hostAdapters: options.hostAdapters },
673
597
  ...options.createRunId === void 0 ? {} : { createRunId: options.createRunId }
674
598
  };
675
- if (options.officer === "notary") {
599
+ const { packagedGateSummon } = await import("./packaged-role-registry.js");
600
+ const gateSummon = packagedGateSummon(options.officer);
601
+ if (gateSummon === "source-run") {
676
602
  return summonPublicRole({
677
- role: "notary",
603
+ role: options.officer,
678
604
  argv: ["--source-run", options.sourceRunDirectory, "--project", options.cwd],
679
605
  ...common
680
606
  });
681
607
  }
682
- if (options.officer === "auditor") {
608
+ if (gateSummon === "subject-source") {
683
609
  return summonPublicRole({
684
- role: "auditor",
610
+ role: options.officer,
685
611
  argv: [
686
612
  "--subject",
687
613
  "judge",
@@ -692,7 +618,7 @@ async function summonGateOfficer(options) {
692
618
  ...common
693
619
  });
694
620
  }
695
- if (options.officer === "countersign") {
621
+ if (gateSummon === "parent-instruction") {
696
622
  const { runIdFromRunDirectory } = await import("./run-terminal-artifacts.js");
697
623
  const correlationId = runIdFromRunDirectory(options.sourceRunDirectory);
698
624
  if (correlationId === void 0 || correlationId.trim() === "") {
@@ -704,7 +630,7 @@ async function summonGateOfficer(options) {
704
630
  const parentTicket = await readBoardTicketNumber(options.sourceRunDirectory);
705
631
  const instruction = options.reask ?? gateReviewInstruction ?? "";
706
632
  return summonPublicRole({
707
- role: "countersign",
633
+ role: options.officer,
708
634
  argv: ["--project", options.cwd, "--", instruction],
709
635
  ...common,
710
636
  correlationId,
@@ -713,7 +639,7 @@ async function summonGateOfficer(options) {
713
639
  });
714
640
  }
715
641
  return summonPublicRole({
716
- role: "inspector",
642
+ role: options.officer,
717
643
  argv: [`\u5377\u5B97\u6307\u9488\uFF1A${options.sourceRunDirectory}`],
718
644
  ...common
719
645
  });
@@ -1,54 +1,32 @@
1
- import { packagedRoleInputFlag, packagedRolePhaseFlag } from "./packaged-role-registry.js";
2
- /** Project closed RoleTurnActivation onto the shared host flag map. */
1
+ import { packagedRoleActivationFlags } from "./packaged-role-registry.js";
2
+ /**
3
+ * Project closed RoleTurnActivation onto the shared host flag map.
4
+ * Seat flag names and fields come from the composition-root record.
5
+ * countersign ticketNumber stays off this map (no private transport flag, #632).
6
+ */
3
7
  export function projectActivationFlags(request) {
4
8
  const activation = request.activation;
5
9
  const flags = new Map([["ak-role", activation.role]]);
6
10
  if (request.stationChild === true) {
7
11
  flags.set("ak-station-child", true);
8
12
  }
9
- const inputFlag = packagedRoleInputFlag(activation.role);
10
- const phaseFlag = packagedRolePhaseFlag(activation.role);
11
- if ("phase" in activation && phaseFlag !== undefined)
12
- flags.set(phaseFlag, activation.phase);
13
- if (inputFlag !== undefined) {
14
- const path = "taskPath" in activation ? activation.taskPath
15
- : "packetPath" in activation ? activation.packetPath
16
- : "casePath" in activation ? activation.casePath
17
- : "inputPath" in activation ? activation.inputPath
18
- : "sourceRun" in activation ? activation.sourceRun
19
- : undefined;
20
- if (path !== undefined)
21
- flags.set(inputFlag, path);
22
- }
23
- if (activation.role === "fixer" && activation.prerequisitesPath !== undefined) {
24
- flags.set("ak-fixer-prerequisites", activation.prerequisitesPath);
25
- }
26
- if (activation.role === "reviewer") {
27
- flags.set("ak-review-base", activation.baseRevision);
28
- flags.set("ak-review-lens", activation.lens);
29
- flags.set("ak-review-authority-refs", JSON.stringify(activation.authorityRefs));
30
- if (activation.ticketNumber !== undefined) {
31
- flags.set("ak-review-ticket-number", String(activation.ticketNumber));
32
- }
33
- }
34
- // countersign ticketNumber stays on activation/admission/invocation only —
35
- // no private transport flag (inner-gate material path deleted in #632).
36
- if (activation.role === "notary" && activation.ticketNumber !== undefined) {
37
- flags.set("ak-notary-ticket-number", String(activation.ticketNumber));
38
- }
39
- if (activation.role === "gleaner-left") {
40
- flags.set("ak-gleaner-left-base", activation.baseRevision);
41
- }
42
- if (activation.role === "collector") {
43
- flags.set("ak-collector-repo", activation.repo);
44
- // #676 D1: pr optional at admission; omit flag when role binds from materials.
45
- if (activation.pr !== undefined)
46
- flags.set("ak-collector-pr", activation.pr);
47
- if (activation.requestManifestPath !== undefined) {
48
- flags.set("ak-collector-request-manifest", activation.requestManifestPath);
49
- }
50
- if (activation.waitMs !== undefined)
51
- flags.set("ak-collector-wait-ms", activation.waitMs);
13
+ const values = activation;
14
+ for (const spec of packagedRoleActivationFlags(activation.role)) {
15
+ if (spec.flag === undefined)
16
+ continue;
17
+ const text = activationFlagText(values[spec.field]);
18
+ if (text !== undefined)
19
+ flags.set(spec.flag, text);
52
20
  }
53
21
  return flags;
54
22
  }
23
+ function activationFlagText(value) {
24
+ if (typeof value === "string")
25
+ return value;
26
+ if (typeof value === "number")
27
+ return String(value);
28
+ if (Array.isArray(value) && value.every((item) => typeof item === "string")) {
29
+ return JSON.stringify(value);
30
+ }
31
+ return undefined;
32
+ }
@@ -1,10 +1,8 @@
1
1
  const SECRETARIAT_OUTPUT_TOOL_NAME = "ak_secretariat_output";
2
2
  const SECRETARIAT_SUMMON_COUNTERSIGN_TOOL_NAME = "ak_secretariat_summon_countersign";
3
- const SECRETARIAT_ACCEPTED_TEXT = "\u4E2D\u4E66\u7701\u56DE\u6267\u5DF2\u63A5\u53D7";
4
3
  const SECRETARIAT_GATE_OFFICER_ENTRY_TYPE = "ak-secretariat-gate-officer";
5
4
  const SECRETARIAT_COUNTERSIGN_TERMINAL_FACT_KEY = "countersignTerminal";
6
5
  export {
7
- SECRETARIAT_ACCEPTED_TEXT,
8
6
  SECRETARIAT_COUNTERSIGN_TERMINAL_FACT_KEY,
9
7
  SECRETARIAT_GATE_OFFICER_ENTRY_TYPE,
10
8
  SECRETARIAT_OUTPUT_TOOL_NAME,
@@ -46,13 +46,22 @@ export function resolveHostAwareSessionAvailability(host, principalAuthority) {
46
46
  if (host === undefined || host === DEFAULT_ROLE_TURN_HOST) {
47
47
  return (principal) => principalAuthority.isAvailable(principal);
48
48
  }
49
+ // Unregistered names have no binding file: absence, not a guess at pi.
50
+ return async (principal) => (await readStoredHostSessionId(host, principalAuthority, principal)) !== undefined;
51
+ }
52
+ /**
53
+ * Native session/thread id already stored for this principal on `host`.
54
+ * Public explicit resume reads it once and hands it to the host adapter.
55
+ * Pi has no separate binding file. A missing file is absence, not the package run id.
56
+ */
57
+ export async function readStoredHostSessionId(host, authority, principal) {
58
+ if (host === undefined || host === DEFAULT_ROLE_TURN_HOST)
59
+ return undefined;
49
60
  const description = lookupHostDescription(host) ?? lookupHeadlessHostDescription(host);
50
- if (description === undefined) {
51
- // Host selection already fails closed on an unregistered name (#510) long
52
- // before a turn dispatches; mirror the same fail-closed default here
53
- // rather than guessing at pi's binding for a name pi does not own.
54
- return () => Promise.resolve(false);
55
- }
56
- const sessionIdentity = createSessionIdentityAuthority(principalAuthority, description.sessionBindingFile);
57
- return async (principal) => (await sessionIdentity.load(principal)) !== undefined;
61
+ if (description === undefined)
62
+ return undefined;
63
+ const sessionId = await createSessionIdentityAuthority(authority, description.sessionBindingFile).load(principal);
64
+ if (sessionId === undefined || sessionId === "")
65
+ return undefined;
66
+ return sessionId;
58
67
  }
@@ -5,7 +5,8 @@ import { fileURLToPath, pathToFileURL } from "node:url";
5
5
  import {
6
6
  INSPECTOR_SESSION_MATERIALS,
7
7
  NOTARY_SESSION_MATERIALS,
8
- PUBLIC_ROLE_RECORDS
8
+ PUBLIC_ROLE_RECORDS,
9
+ packagedRoleSessionMaterials
9
10
  } from "./packaged-role-registry.js";
10
11
  function resolvePackageRootDir(moduleUrl = import.meta.url) {
11
12
  let dir = dirname(fileURLToPath(moduleUrl));
@@ -51,7 +52,7 @@ function loadMainRoleReferenceMaterials(role) {
51
52
  }
52
53
  const GATEKEEPER_SESSION_MATERIALS = {
53
54
  // #639: single authority — the public gatekeeper record owns the province list.
54
- gatekeeper: PUBLIC_ROLE_RECORDS.find((entry) => entry.role === "gatekeeper").sessionMaterials,
55
+ gatekeeper: packagedRoleSessionMaterials("gatekeeper"),
55
56
  inspector: INSPECTOR_SESSION_MATERIALS,
56
57
  notary: NOTARY_SESSION_MATERIALS
57
58
  };
@@ -1,8 +1,5 @@
1
- import { readFile } from "node:fs/promises";
2
1
  import { fileURLToPath } from "node:url";
3
2
 
4
- import { loadDoctorCase } from "../src/doctor-evidence.ts";
5
- import { loadNotarySourceRunLocator } from "../src/notary-source-run.ts";
6
3
  import { createPiRoleRuntimeExtension } from "../src/pi/adapter.ts";
7
4
 
8
5
  import {
@@ -14,35 +11,21 @@ import {
14
11
  } from "@earendil-works/pi-coding-agent";
15
12
  import type { Message } from "@earendil-works/pi-ai";
16
13
 
17
- import { createGhCollectorGitHubTransport } from "../src/collector-github.ts";
18
- import { createPiDoctorAuditor } from "../src/doctor-auditor.ts";
19
14
  import {
20
- createNativeNavigatorSessionFactory,
21
- createNavigatorAttendance,
22
15
  registerNavigatorModelCommand,
23
16
  resolveNavigatorAuthorityMaterial,
24
17
  type NavigatorTargetRole,
25
18
  } from "../src/navigator-attendance.ts";
26
19
  import { loadNavigatorWorkContext as loadHostNeutralNavigatorWorkContext } from "../src/navigator-work-context.ts";
27
20
  export { resolveNavigatorAuthorityMaterial };
28
- import { loadCanonicalSkillBinding as loadHomeCanonicalSkillBinding } from "../src/canonical-skill-binding.ts";
29
- import { loadPackagedCanonicalSkillBinding } from "../src/package-resources/method-skill-binding.ts";
30
21
  import { JUDGE_OUTPUT_TOOL_NAME } from "../src/package-contracts/judge-output.ts";
31
22
  import { readOAuthKeepaliveProviders } from "../src/oauth-keepalive.ts";
32
23
  import {
33
24
  formatNavigatorRoleHelp,
34
25
  type RoleRuntimeDependencies,
35
26
  } from "../src/role-runtime.ts";
36
- import { loadAuditorSoulFromSubjectInput } from "../src/auditor-soul.ts";
37
- import { loadPackagedRoleReferenceMaterials } from "../src/role-runtime-dependencies.ts";
38
- import {
39
- loadGatekeeperSessionMaterials,
40
- loadMainRoleSessionMaterials,
41
- } from "../src/session-opening-materials.ts";
42
- const extensionPath = fileURLToPath(import.meta.url);
27
+ import { createRoleRuntimeDependencies } from "../src/role-runtime-dependencies.ts";
43
28
  const packageRoot = fileURLToPath(new URL("..", import.meta.url));
44
- const navigatorRoutePlaybookPath = fileURLToPath(new URL("../resources/navigator-route-playbook.md", import.meta.url));
45
- const collectorHandbookSeedPath = fileURLToPath(new URL("../resources/collector-bot-handbook.md", import.meta.url));
46
29
  // #675: nested public summons (gate/auditor) resolve root via env under jiti.
47
30
  if (process.env.AK_ROLE_PACKAGE_ROOT === undefined || process.env.AK_ROLE_PACKAGE_ROOT.trim() === "") {
48
31
  process.env.AK_ROLE_PACKAGE_ROOT = packageRoot;
@@ -110,68 +93,11 @@ export async function loadNavigatorWorkContext(
110
93
  });
111
94
  }
112
95
 
113
- export function createPiRoleRuntimeDependencies(pi: ExtensionAPI): RoleRuntimeDependencies {
114
- const navigatorSessionFactory = createNativeNavigatorSessionFactory();
115
- return {
116
- packageRoot,
117
- loadRoleReferenceMaterials: loadPackagedRoleReferenceMaterials,
118
- loadJudgeSoul: () => loadMainRoleSessionMaterials("judge"),
119
- loadFixerSoul: () => loadMainRoleSessionMaterials("fixer"),
120
- loadFixPacket: (path) => readFile(path, "utf8"),
121
- loadCoderSoul: () => loadMainRoleSessionMaterials("coder"),
122
- loadCoderTask: (path) => readFile(path, "utf8"),
123
- loadReviewerSoul: () => loadMainRoleSessionMaterials("reviewer"),
124
- loadCollectorSoul: () => loadMainRoleSessionMaterials("collector"),
125
- loadCollectorHandbookSeed: () => readFile(collectorHandbookSeedPath, "utf8"),
126
- createCollectorTransport: () => createGhCollectorGitHubTransport(),
127
- loadDoctorSoul: () => loadMainRoleSessionMaterials("doctor"),
128
- loadDoctorCase,
129
- // #590: auditors / navigator / reviewer consume HostContext directly (no Pi WeakMap recover).
130
- auditDoctorCompliance: (options) => createPiDoctorAuditor()(options),
131
- loadNotarySoul: () => loadMainRoleSessionMaterials("notary"),
132
- loadCountersignSoul: () => loadMainRoleSessionMaterials("countersign"),
133
- loadGleanerLeftSoul: () => loadMainRoleSessionMaterials("gleaner-left"),
134
- loadDiaristSoul: () => loadMainRoleSessionMaterials("diarist"),
135
- loadSecretariatSoul: () => loadMainRoleSessionMaterials("secretariat"),
136
- loadInspectorSoul: () => loadMainRoleSessionMaterials("inspector"),
137
- loadGatekeeperSoul: () => loadGatekeeperSessionMaterials("gatekeeper"),
138
- loadNavigatorSoul: () => loadMainRoleSessionMaterials("navigator"),
139
- loadAuditorSoul: () => loadAuditorSoulFromSubjectInput(),
140
- loadNotarySourceRun: loadNotarySourceRunLocator,
141
- loadNavigatorWorkContext: (options) => loadNavigatorWorkContext(pi, options),
142
- createNavigatorAttendance: (options) => {
143
- return createNavigatorAttendance({
144
- context: options.context,
145
- role: options.role,
146
- phase: options.phase,
147
- subjectKey: options.subjectKey,
148
- subject: options.subject,
149
- authority: options.authority,
150
- invocationId: options.invocationId,
151
- loadSoul: () => loadMainRoleSessionMaterials("navigator"),
152
- loadRoutePlaybook: () => readFile(navigatorRoutePlaybookPath, "utf8"),
153
- // In-process help: subprocess pi --help is reserved for cold-install proofs.
154
- // N child pi processes cannot fit the accepted 3s post-role grace under CI load.
155
- loadRoleHelp: async (role) => formatNavigatorRoleHelp(role),
156
- createSession: navigatorSessionFactory,
157
- contextError: options.contextError,
158
- onEvent: options.onEvent,
159
- });
160
- },
161
- loadMergerSoul: () => loadMainRoleSessionMaterials("merger"),
162
- loadMergerInput: async (path) => JSON.parse(await readFile(path, "utf8")),
163
- async loadCanonicalSkillBinding(name) {
164
- // Coder TDD (#109) and Reviewer ak-cross-m-review (#917) are package-owned.
165
- // Optional Fixer diagnosing-bugs is available via --skill without this binding.
166
- if (name === "tdd") {
167
- return loadPackagedCanonicalSkillBinding(packageRoot, "tdd");
168
- }
169
- if (name === "ak-cross-m-review") {
170
- return loadPackagedCanonicalSkillBinding(packageRoot, "ak-cross-m-review");
171
- }
172
- return loadHomeCanonicalSkillBinding(name);
173
- },
174
- };
96
+ /** Pi extension deps are the shared packaged factory. Host flags stay on the envelope. */
97
+ export function createPiRoleRuntimeDependencies(
98
+ _pi: ExtensionAPI,
99
+ ): RoleRuntimeDependencies {
100
+ return createRoleRuntimeDependencies(packageRoot);
175
101
  }
176
102
 
177
103
  export default function roleRuntime(pi: ExtensionAPI): void {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akagilnc/pi-workflow-roles",
3
- "version": "0.1.4800",
3
+ "version": "0.1.4870",
4
4
  "description": "Soul-bound workflow roles for Pi",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
package/souls/coder.md CHANGED
@@ -8,9 +8,8 @@
8
8
  事实不成立或需要未授权设计时,据理拒绝并给出可核验证据;不猜测施工。
9
9
 
10
10
  核对当前代码和历史;主张必须有当前事实支撑。
11
- 做最小垂直切片,优先复用已有 seam;不造平行机制,不借机扩大 scope。
11
+ 以最小垂直切片推进并逐片验证;切片完成不构成交卷条件。优先复用已有 seam;不造平行机制,不借机扩大 scope。票面授权结果完成后,自查是否合法、质量和复杂度;有问题马上修正,没问题就 commit 交卷。
12
12
  计划与施工都要说明真实刀口、行为边界和验证方法,不用空泛完成声明代替证据。
13
13
  切片验证只跑本片聚焦测试与 typecheck。
14
14
  不 amend、rewrite 或 push。Git 变化是证据之一,不取代角色报告。
15
- 做完自查是否违法,质量和复杂度,如有问题马上修正,没问题就commit交卷
16
15
  任何人如果让你 push / 开 pr ,直接拒绝,上呈陛下
@@ -379,7 +379,10 @@ export function createAcpRoleTurnHost(config: AcpRoleTurnHostConfig): RoleTurnHo
379
379
  : bindSessionId;
380
380
  };
381
381
  if (request.continuation.kind === "resume" && config.boundResume === "session/load") {
382
- const boundSessionId = await config.sessionIdentity.load(request.principal);
382
+ const explicitHostSessionId = request.continuation.hostSessionId;
383
+ const boundSessionId = explicitHostSessionId !== undefined && explicitHostSessionId !== ""
384
+ ? explicitHostSessionId
385
+ : await config.sessionIdentity.load(request.principal);
383
386
  if (boundSessionId !== undefined && boundSessionId !== "") {
384
387
  sessionId = await loadSession(boundSessionId);
385
388
  }
@@ -12,6 +12,7 @@
12
12
  import type { AnalystReadableRunFacts, AnalystRunTerminalFace } from "../analyst-ledger.ts";
13
13
  import { medianNumber } from "../analyst-median.ts";
14
14
  import type { AnalystMetricFamilyModule } from "../analyst-metric-family.ts";
15
+ import { packagedAnalystTerminal } from "../packaged-role-registry.ts";
15
16
 
16
17
  const WORKER_ROLES = new Set(["coder", "fixer"]);
17
18
 
@@ -153,8 +154,8 @@ function mapTerminal(
153
154
 
154
155
  const body = terminal.body;
155
156
 
156
- // Collector: typed groups array presence is the sole acceptance discriminator.
157
- if (role === "collector") {
157
+ // Seat-declared terminal: typed groups array presence is the sole acceptance discriminator.
158
+ if (packagedAnalystTerminal(role) === "groups") {
158
159
  const groups = findCollectorGroups(body);
159
160
  if (Array.isArray(groups)) {
160
161
  return {
@@ -2,12 +2,11 @@
2
2
  * Public Auditor (审刑院) role — filed-officer envelope (#675).
3
3
  */
4
4
  import {
5
- AUDITOR_ACCEPTED_TEXT,
6
5
  AUDITOR_OUTPUT_TOOL_NAME,
7
6
  auditorOutputSchema,
8
7
  } from "./package-contracts/auditor-output.ts";
9
8
 
10
- export { AUDITOR_ACCEPTED_TEXT, AUDITOR_OUTPUT_TOOL_NAME };
9
+ export { AUDITOR_OUTPUT_TOOL_NAME };
11
10
 
12
11
  export type AuditorRuntimeDependencies = {
13
12
  loadSoul(): Promise<string>;
@@ -54,7 +54,7 @@ export const AUDITOR_SESSION_MATERIALS = {
54
54
  >;
55
55
 
56
56
  export function isAuditorSoulRole(value: unknown): value is AuditorSoulRole {
57
- return value === "judge" || value === "doctor";
57
+ return typeof value === "string" && Object.hasOwn(AUDITOR_SESSION_MATERIALS, value);
58
58
  }
59
59
 
60
60
  /** Resolve audited subject from explicit value or the subject-input env. */
@@ -55,7 +55,7 @@ import {
55
55
  collectorRequestArgsSchema,
56
56
  collectorWaitArgsSchema,
57
57
  } from "./collector-tool-schemas.ts";
58
- import { COLLECTOR_ACCEPTED_TEXT } from "./package-contracts/collector-output.ts";
58
+ import { packagedRoleAcceptedText } from "./packaged-role-registry.ts";
59
59
  import { CorrectableSubmissionError, isCorrectableExecuteError } from "./submission-correctable-error.ts";
60
60
  import { CollectorUnknownEvidenceError } from "./collector-identity.ts";
61
61
 
@@ -666,7 +666,7 @@ export function createCollectorRoleRuntime(
666
666
  return {
667
667
  content: [{
668
668
  type: "text" as const,
669
- text: COLLECTOR_ACCEPTED_TEXT,
669
+ text: packagedRoleAcceptedText("collector"),
670
670
  }],
671
671
  details: params,
672
672
  terminate: true as const,
@@ -6,7 +6,6 @@
6
6
  */
7
7
 
8
8
  export const COUNTERSIGN_OUTPUT_TOOL_NAME = "ak_countersign_output";
9
- export const COUNTERSIGN_ACCEPTED_TEXT = "给事中回执已接受";
10
9
 
11
10
  export type CountersignVerdict =
12
11
  | { countersignStatus: "converged"; note?: string; evidence?: unknown }