@akagilnc/pi-workflow-roles 0.1.4802 → 0.1.4874

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 (142) 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/src/acp-host/role-turn-host.ts +4 -1
  64. package/src/analyst-metric-families/acceptance-success-rework.ts +3 -2
  65. package/src/auditor-role.ts +1 -2
  66. package/src/auditor-soul.ts +1 -1
  67. package/src/collector-role.ts +2 -2
  68. package/src/countersign-contracts.ts +0 -1
  69. package/src/countersign-role.ts +1 -1
  70. package/src/diarist-contracts.ts +0 -1
  71. package/src/diarist-role.ts +0 -1
  72. package/src/doctor-auditor.ts +1 -2
  73. package/src/doctor-contracts.ts +1 -1
  74. package/src/doctor-role.ts +3 -2
  75. package/src/external-host-turn-loop.ts +1 -1
  76. package/src/factory-board.ts +10 -7
  77. package/src/gatekeeper-role.ts +16 -10
  78. package/src/gleaner-left-contracts.ts +0 -1
  79. package/src/gleaner-left-role.ts +0 -1
  80. package/src/headless-host/role-turn-host.ts +7 -1
  81. package/src/host-contracts.ts +10 -6
  82. package/src/inspector-contracts.ts +0 -1
  83. package/src/inspector-role.ts +0 -2
  84. package/src/institutional-resolution.ts +6 -4
  85. package/src/judge-role.ts +3 -3
  86. package/src/merger-contracts.ts +0 -1
  87. package/src/merger-role.ts +2 -2
  88. package/src/navigator-public-session.ts +7 -6
  89. package/src/navigator-work-context.ts +6 -8
  90. package/src/notary-contracts.ts +0 -1
  91. package/src/notary-role.ts +2 -3
  92. package/src/package-contracts/auditor-output.ts +0 -1
  93. package/src/package-contracts/collector-output.ts +0 -1
  94. package/src/package-contracts/fixer-output.ts +0 -1
  95. package/src/package-contracts/gatekeeper-output.ts +0 -1
  96. package/src/package-contracts/judge-output.ts +0 -1
  97. package/src/package-contracts/navigator-output.ts +0 -1
  98. package/src/package-contracts/reviewer-output.ts +0 -1
  99. package/src/package-contracts/terminating-tools.ts +27 -99
  100. package/src/package-contracts/worker-output.ts +0 -2
  101. package/src/packaged-role-registry.ts +604 -35
  102. package/src/pi/role-turn-host.ts +2 -1
  103. package/src/public-cli/cli.ts +64 -259
  104. package/src/public-cli/config.ts +18 -10
  105. package/src/public-cli/countersign-run.ts +14 -449
  106. package/src/public-cli/instruction-seat-run.ts +758 -277
  107. package/src/public-cli/invocation.ts +1097 -2051
  108. package/src/public-cli/option-definitions.ts +62 -127
  109. package/src/public-cli/post-admission.ts +47 -2
  110. package/src/public-cli/run-lifecycle.ts +303 -613
  111. package/src/public-cli/seat-ticket-binding.ts +6 -0
  112. package/src/public-cli/settlement.ts +399 -1185
  113. package/src/public-cli/turn-request.ts +92 -1
  114. package/src/public-role-summons.ts +44 -128
  115. package/src/reviewer-role.ts +3 -2
  116. package/src/role-activation-flags.ts +20 -41
  117. package/src/role-runtime-dependencies.ts +25 -26
  118. package/src/role-runtime.ts +121 -232
  119. package/src/secretariat-contracts.ts +0 -1
  120. package/src/secretariat-role.ts +0 -2
  121. package/src/session-identity.ts +23 -8
  122. package/src/session-opening-materials.ts +2 -1
  123. package/src/worker-role.ts +3 -4
  124. package/dist/doctor-auditor.js +0 -25
  125. package/dist/public-cli/diarist-run.js +0 -130
  126. package/dist/public-cli/doctor-run.js +0 -87
  127. package/dist/public-cli/inspector-run.js +0 -151
  128. package/dist/public-cli/judge-run.js +0 -114
  129. package/dist/public-cli/notary-run.js +0 -174
  130. package/dist/public-cli/reviewer-run.js +0 -339
  131. package/src/public-cli/coder-run.ts +0 -255
  132. package/src/public-cli/collector-run.ts +0 -189
  133. package/src/public-cli/diarist-run.ts +0 -233
  134. package/src/public-cli/doctor-run.ts +0 -167
  135. package/src/public-cli/fixer-run.ts +0 -265
  136. package/src/public-cli/gleaner-left-run.ts +0 -167
  137. package/src/public-cli/inspector-run.ts +0 -261
  138. package/src/public-cli/judge-run.ts +0 -196
  139. package/src/public-cli/merger-run.ts +0 -294
  140. package/src/public-cli/notary-run.ts +0 -279
  141. package/src/public-cli/reviewer-run.ts +0 -480
  142. package/src/public-cli/secretariat-run.ts +0 -265
@@ -1,11 +1,12 @@
1
1
  /** Composition-root unique authoritative public-role records (#509 / #524). */
2
2
  import { COLLECTOR_OUTPUT_TOOL } from "./package-contracts/collector-output.ts";
3
+ import { COLLECTOR_WAIT_TOOL } from "./collector-ledger.ts";
3
4
  import { GATEKEEPER_OUTPUT_TOOL_NAME } from "./package-contracts/gatekeeper-output.ts";
4
5
  import { NAVIGATOR_OUTPUT_TOOL_NAME } from "./package-contracts/navigator-output.ts";
5
6
  import { JUDGE_OUTPUT_TOOL_NAME } from "./package-contracts/judge-output.ts";
6
7
  import { REVIEWER_OUTPUT_TOOL_NAME } from "./package-contracts/reviewer-output.ts";
7
8
  import { CODER_OUTPUT_TOOL_NAME, FIXER_OUTPUT_TOOL_NAME } from "./package-contracts/worker-output.ts";
8
- import { DOCTOR_OUTPUT_TOOL_NAME } from "./doctor-contracts.ts";
9
+ import { DOCTOR_AUDIT_TOOL_NAME, DOCTOR_OUTPUT_TOOL_NAME } from "./doctor-contracts.ts";
9
10
  import { MERGER_OUTPUT_TOOL_NAME } from "./merger-contracts.ts";
10
11
  import { NOTARY_OUTPUT_TOOL_NAME } from "./notary-contracts.ts";
11
12
  import { COUNTERSIGN_OUTPUT_TOOL_NAME } from "./countersign-contracts.ts";
@@ -14,6 +15,27 @@ import { INSPECTOR_OUTPUT_TOOL_NAME } from "./inspector-contracts.ts";
14
15
  import { AUDITOR_OUTPUT_TOOL_NAME } from "./package-contracts/auditor-output.ts";
15
16
  import { DIARIST_OUTPUT_TOOL_NAME } from "./diarist-contracts.ts";
16
17
  import { SECRETARIAT_OUTPUT_TOOL_NAME } from "./secretariat-contracts.ts";
18
+ import { JUDGE_AUDIT_TOOL_NAME } from "./judge-auditor.ts";
19
+
20
+ /**
21
+ * Success-face fields that still differ by seat. Presence and omission match
22
+ * the former per-seat publishers. Key order is not part of the contract.
23
+ */
24
+ export type PackagedArtifactLeaf = {
25
+ readonly key: string;
26
+ readonly from?: string;
27
+ readonly omitUndefined?: true;
28
+ readonly copyArray?: true;
29
+ readonly callerProvenance?: true;
30
+ };
31
+
32
+ export type PackagedArtifactFace = {
33
+ readonly reportPhase?: true;
34
+ readonly evidenceRole?: true;
35
+ readonly leaves: readonly PackagedArtifactLeaf[];
36
+ readonly method?: "optional" | "observed";
37
+ readonly doctorReportFacts?: true;
38
+ };
17
39
 
18
40
  /** Shared by public notary and gatekeeper-province notary. */
19
41
  export const NOTARY_SESSION_MATERIALS = [
@@ -53,11 +75,25 @@ export const AUDITOR_PUBLIC_SESSION_MATERIALS = [
53
75
  export const PUBLIC_ROLE_RECORDS = [
54
76
  {
55
77
  role: "judge",
78
+ inCallAutoResume: true,
79
+ presentSettled: "default",
80
+ summonResume: false,
81
+ admission: "instruction",
82
+ /** Public argv rejects a burden selector. */
83
+ bareToken: "burden",
84
+ sameParent: "none",
56
85
  phases: [null],
57
86
  outputTool: JUDGE_OUTPUT_TOOL_NAME,
58
- inputFlag: undefined,
59
- phaseFlag: undefined,
87
+ auditTool: JUDGE_AUDIT_TOOL_NAME,
88
+ settlement: "sealed",
89
+ runnerFailure: "engine-detour-known-first",
90
+ acceptedText: "大理寺回执已接受",
91
+ /** Factory board: court until another station has started, then marshal. */
92
+ boardPlacement: "judge-history",
93
+ /** Navigator subject is the public admitted instruction when the run is bound. */
94
+ navigatorSubject: "public-instruction",
60
95
  activationStage: "load-and-install",
96
+ receiptStatusKey: "judgeStatus",
61
97
  sessionMaterials: [
62
98
  "CLAUDE.md",
63
99
  "souls/judge.md",
@@ -68,10 +104,35 @@ export const PUBLIC_ROLE_RECORDS = [
68
104
  },
69
105
  {
70
106
  role: "fixer",
107
+ inCallAutoResume: true,
108
+ presentSettled: "default",
109
+ summonResume: false,
110
+ admission: "worker-packet",
111
+ sameParent: "none",
112
+ worker: true,
113
+ methodSkills: ["diagnosing-bugs", "tdd"],
114
+ settleMethod: "diagnosing-bugs",
71
115
  phases: ["plan", "apply"],
72
116
  outputTool: FIXER_OUTPUT_TOOL_NAME,
73
- inputFlag: "ak-fix-packet",
74
- phaseFlag: "ak-fixer-phase",
117
+ settlement: "sealed",
118
+ artifactFace: {
119
+ reportPhase: true,
120
+ evidenceRole: true,
121
+ leaves: [
122
+ { key: "phase" },
123
+ { key: "packetPath" },
124
+ { key: "prerequisitesPath", omitUndefined: true },
125
+ { key: "prerequisites" },
126
+ ],
127
+ method: "observed",
128
+ },
129
+ acceptedText: "修内司回执已接受",
130
+ boardPlacement: "marshal",
131
+ activationFlags: [
132
+ { field: "packetPath", flag: "ak-fix-packet", binds: "input" },
133
+ { field: "phase", flag: "ak-fixer-phase", binds: "phase" },
134
+ { field: "prerequisitesPath", flag: "ak-fixer-prerequisites" },
135
+ ],
75
136
  activationStage: "load-and-install",
76
137
  sessionMaterials: [
77
138
  "CLAUDE.md",
@@ -82,10 +143,33 @@ export const PUBLIC_ROLE_RECORDS = [
82
143
  },
83
144
  {
84
145
  role: "coder",
146
+ inCallAutoResume: true,
147
+ presentSettled: "default",
148
+ summonResume: false,
149
+ admission: "worker-task",
150
+ sameParent: "none",
151
+ worker: true,
152
+ applyMethod: "tdd",
153
+ /** Method-material load failure keeps the activation cause (not reviewer/fixer). */
154
+ methodLoadFailureCause: "activation",
155
+ boardPlacement: "coder",
85
156
  phases: ["plan", "apply"],
86
157
  outputTool: CODER_OUTPUT_TOOL_NAME,
87
- inputFlag: "ak-coder-task",
88
- phaseFlag: "ak-coder-phase",
158
+ settlement: "sealed",
159
+ artifactFace: {
160
+ reportPhase: true,
161
+ evidenceRole: true,
162
+ leaves: [
163
+ { key: "phase" },
164
+ { key: "taskPath" },
165
+ ],
166
+ method: "optional",
167
+ },
168
+ acceptedText: "将作监回执已接受",
169
+ activationFlags: [
170
+ { field: "taskPath", flag: "ak-coder-task", binds: "input" },
171
+ { field: "phase", flag: "ak-coder-phase", binds: "phase" },
172
+ ],
89
173
  activationStage: "load-and-install",
90
174
  sessionMaterials: [
91
175
  "CLAUDE.md",
@@ -96,11 +180,47 @@ export const PUBLIC_ROLE_RECORDS = [
96
180
  },
97
181
  {
98
182
  role: "reviewer",
183
+ inCallAutoResume: true,
184
+ presentSettled: "default",
185
+ summonResume: false,
186
+ admission: "review-basis",
187
+ /** --base is a single Skill-arg token, and authority refs are always emitted. */
188
+ baseValue: "revision",
189
+ emitAuthorityRefs: true,
190
+ sameParent: "none",
191
+ methodSkills: ["ak-cross-m-review"],
192
+ settleMethod: "ak-cross-m-review",
193
+ /** Omitted public lens starts two ordinary single-axis runs (ADR 0052). */
194
+ parallelLenses: true,
195
+ /** Every turn runs in a fresh worktree; durable projectRoot stays the caller project (#946). */
196
+ freshExecutionCopy: true,
99
197
  phases: [null],
100
198
  bareCommand: false,
101
199
  outputTool: REVIEWER_OUTPUT_TOOL_NAME,
102
- inputFlag: undefined,
103
- phaseFlag: undefined,
200
+ settlement: "sealed",
201
+ /** Publish only an accepted ledger outcome; audit escalation stays unsettled here. */
202
+ sealedAcceptedOnly: true,
203
+ artifactFace: {
204
+ evidenceRole: true,
205
+ leaves: [
206
+ { key: "baseRevision" },
207
+ { key: "lens" },
208
+ { key: "authorityRefs", copyArray: true },
209
+ { key: "callerProvenance", callerProvenance: true },
210
+ ],
211
+ method: "observed",
212
+ },
213
+ /** Frozen base/lens/authority become the initial prompt; instruction follows. */
214
+ transportPrompt: "skill-args",
215
+ runnerFailure: "engine-detour-record-first",
216
+ acceptedText: "御史台回执已接受",
217
+ boardPlacement: "marshal",
218
+ activationFlags: [
219
+ { field: "baseRevision", flag: "ak-review-base" },
220
+ { field: "lens", flag: "ak-review-lens" },
221
+ { field: "authorityRefs", flag: "ak-review-authority-refs" },
222
+ { field: "ticketNumber", flag: "ak-review-ticket-number" },
223
+ ],
104
224
  activationStage: "load-and-install",
105
225
  sessionMaterials: [
106
226
  "CLAUDE.md",
@@ -112,60 +232,189 @@ export const PUBLIC_ROLE_RECORDS = [
112
232
  // ak-collector-repo is GitHub owner/repo identity, not a local material path (#438).
113
233
  {
114
234
  role: "collector",
235
+ inCallAutoResume: false,
236
+ presentSettled: "always",
237
+ summonResume: false,
238
+ admission: "collect-target",
239
+ /** Public no_receipt projects a durable bind-target rejection. */
240
+ projectTargetBindRejection: true,
241
+ sameParent: "none",
115
242
  phases: [null],
116
243
  bareCommand: false,
117
244
  outputTool: COLLECTOR_OUTPUT_TOOL,
118
- inputFlag: undefined,
119
- phaseFlag: undefined,
245
+ settlement: "residual",
246
+ /** #633: a prior wait-tool residual must not mask this attempt. */
247
+ residualScan: "current-attempt",
248
+ residualTool: COLLECTOR_WAIT_TOOL,
249
+ runnerFailure: "collector-known-first",
250
+ artifactFace: {
251
+ evidenceRole: true,
252
+ leaves: [
253
+ { key: "prNumber", omitUndefined: true },
254
+ { key: "repository", from: "repository.canonical" },
255
+ { key: "manifestDigest" },
256
+ ],
257
+ },
258
+ acceptedText: "通进司回执已接受",
259
+ boardPlacement: "collector",
260
+ /** Taishi acceptance is a typed groups array, not a status leaf. */
261
+ analystTerminal: "groups",
262
+ activationFlags: [
263
+ { field: "repo", from: "repository.display", flag: "ak-collector-repo" },
264
+ { field: "pr", from: "prNumber", text: true, flag: "ak-collector-pr" },
265
+ { field: "requestManifestPath", flag: "ak-collector-request-manifest" },
266
+ { field: "waitMs", from: "waitWindowMs", text: true, flag: "ak-collector-wait-ms" },
267
+ ],
120
268
  activationStage: "load-and-install",
121
269
  sessionMaterials: ["CLAUDE.md", "souls/collector.md"],
122
270
  },
123
271
  {
124
272
  role: "doctor",
273
+ inCallAutoResume: false,
274
+ presentSettled: "typed",
275
+ summonResume: false,
276
+ admission: "case-identity",
277
+ sameParent: "none",
125
278
  phases: [null],
126
279
  bareCommand: false,
127
280
  outputTool: DOCTOR_OUTPUT_TOOL_NAME,
128
- inputFlag: "ak-doctor-case",
129
- phaseFlag: undefined,
281
+ auditTool: DOCTOR_AUDIT_TOOL_NAME,
282
+ settlement: "sealed",
283
+ artifactFace: {
284
+ evidenceRole: true,
285
+ leaves: [
286
+ { key: "issueNumber" },
287
+ { key: "caseRunsPath" },
288
+ { key: "caseIdentity" },
289
+ ],
290
+ doctorReportFacts: true,
291
+ },
292
+ acceptedText: "太医署回执已接受",
293
+ /** Navigator subject is the doctor case, not the case-path file bytes. */
294
+ navigatorSubject: "case",
295
+ activationFlags: [
296
+ { field: "casePath", from: "caseRunsPath", flag: "ak-doctor-case", binds: "input" },
297
+ ],
130
298
  activationStage: "load-and-install",
131
299
  sessionMaterials: ["CLAUDE.md", "souls/doctor.md"],
132
300
  },
133
301
  {
134
302
  role: "merger",
303
+ inCallAutoResume: true,
304
+ presentSettled: "typed",
305
+ summonResume: false,
306
+ admission: "merge-envelope",
307
+ /** Public argv rejects packet fields the adapter reads from Git. */
308
+ bareToken: "packet",
309
+ sameParent: "none",
310
+ methodSkills: ["resolving-merge-conflicts"],
311
+ settleMethod: "resolving-merge-conflicts",
312
+ /** Method-material load failure keeps the activation cause (not reviewer/fixer). */
313
+ methodLoadFailureCause: "activation",
135
314
  phases: [null],
136
315
  outputTool: MERGER_OUTPUT_TOOL_NAME,
137
- inputFlag: "ak-merger-input",
138
- phaseFlag: undefined,
316
+ settlement: "residual",
317
+ /** #836: residual scan stays on the whole host session. */
318
+ residualScan: "session",
319
+ residualTool: MERGER_OUTPUT_TOOL_NAME,
320
+ artifactFace: {
321
+ evidenceRole: true,
322
+ leaves: [
323
+ { key: "mergerInputPath" },
324
+ { key: "derived" },
325
+ ],
326
+ method: "observed",
327
+ },
328
+ acceptedText: "合并回执已接受",
329
+ activationFlags: [
330
+ { field: "inputPath", from: "mergerInputPath", flag: "ak-merger-input", binds: "input" },
331
+ ],
139
332
  activationStage: "prepare-git-and-install",
333
+ receiptCommitKey: "mergeCommitId",
334
+ receiptCommitWhen: "completed",
140
335
  sessionMaterials: ["CLAUDE.md", "souls/merger.md"],
141
336
  },
142
337
  {
143
338
  role: "notary",
339
+ inCallAutoResume: false,
340
+ presentSettled: "always",
341
+ summonResume: false,
342
+ admission: "source-locator",
343
+ /** Public argv is only the source-run locator; stored text is not trimmed. */
344
+ bareToken: "instruction",
345
+ sourceRunStored: "raw",
346
+ argvResult: "source-run",
347
+ sameParent: "source-locator",
348
+ /** Infrastructure failure at this stage has no accepted gate cycle to project. */
349
+ skipGateOnInfrastructureStage: true,
350
+ /** 符宝郎 is a review officer and inherits the gatekeeper model. */
351
+ reviewOfficer: true,
352
+ provinceConfig: true,
353
+ modelInheritsFrom: "gatekeeper",
144
354
  phases: [null],
145
355
  bareCommand: false,
146
356
  outputTool: NOTARY_OUTPUT_TOOL_NAME,
147
- inputFlag: "ak-notary-source-run",
148
- phaseFlag: undefined,
357
+ settlement: "accepted",
358
+ /** Court reask replaces the initial prompt. Otherwise the fixed kickoff. */
359
+ reaskPrompt: true,
360
+ transportPrompt: "fixed-kickoff",
361
+ acceptedText: "符宝郎回执已接受",
362
+ gateStageLabel: "符宝郎",
363
+ /** Gate summon binds --source-run and keeps dialogue off the argv. */
364
+ gateSummon: "source-run",
365
+ /** Navigator subject is the source-run locator, not the path file bytes. */
366
+ navigatorSubject: "source-run",
367
+ activationFlags: [
368
+ { field: "sourceRun", from: "sourceRunPath", flag: "ak-notary-source-run", binds: "input" },
369
+ { field: "ticketNumber", flag: "ak-notary-ticket-number" },
370
+ ],
149
371
  activationStage: "load-and-install",
150
372
  sessionMaterials: NOTARY_SESSION_MATERIALS,
151
373
  },
152
374
  {
153
375
  role: "countersign",
376
+ inCallAutoResume: false,
377
+ presentSettled: "always",
378
+ summonResume: false,
379
+ admission: "court-materials",
380
+ /** Durable custom entry names this officer. */
381
+ durableOfficerEntry: true,
382
+ sameParent: "none",
154
383
  phases: [null],
155
384
  outputTool: COUNTERSIGN_OUTPUT_TOOL_NAME,
156
- inputFlag: undefined,
157
- phaseFlag: undefined,
385
+ settlement: "accepted",
386
+ acceptedText: "给事中回执已接受",
387
+ gateStageLabel: "给事中",
388
+ /** Gate queue reads countersignStatus, not the shared three-state status. */
389
+ gateDecision: "countersign-status",
390
+ /** Gate summon carries the parent payload as the instruction and a parent run id. */
391
+ gateSummon: "parent-instruction",
392
+ activationFlags: [
393
+ { field: "ticketNumber" },
394
+ ],
158
395
  activationStage: "load-and-install",
396
+ receiptStatusKey: "countersignStatus",
159
397
  // #924: 公用《票面法》三席同装
160
398
  sessionMaterials: ["CLAUDE.md", "souls/countersign.md", "souls/ticket-law.md"],
161
399
  },
162
400
  {
163
401
  role: "secretariat",
402
+ inCallAutoResume: false,
403
+ presentSettled: "always",
404
+ summonResume: false,
405
+ admission: "instruction",
406
+ sameParent: "court-diarist",
164
407
  phases: [null],
165
408
  outputTool: SECRETARIAT_OUTPUT_TOOL_NAME,
166
- inputFlag: undefined,
167
- phaseFlag: undefined,
409
+ settlement: "accepted",
410
+ /** Project the durable 给事中 officer entry onto the shared accepted-tool settlement. */
411
+ projectCountersignTerminal: true,
412
+ acceptedText: "中书省回执已接受",
413
+ activationFlags: [
414
+ { field: "ticketNumber" },
415
+ ],
168
416
  activationStage: "load-and-install",
417
+ receiptStatusKey: "secretariatStatus",
169
418
  // #924: owner-finalized Soul + 票面法 + 给事中/符宝郎行为指南
170
419
  sessionMaterials: [
171
420
  "CLAUDE.md",
@@ -177,11 +426,23 @@ export const PUBLIC_ROLE_RECORDS = [
177
426
  },
178
427
  {
179
428
  role: "gleaner-left",
429
+ inCallAutoResume: false,
430
+ presentSettled: "always",
431
+ summonResume: false,
432
+ admission: "gleaner",
433
+ /** Public argv keeps the instruction and drops attachment paths. */
434
+ argvResult: "instruction",
435
+ sameParent: "none",
180
436
  phases: [null],
181
437
  bareCommand: false,
182
438
  outputTool: GLEANER_LEFT_OUTPUT_TOOL_NAME,
183
- inputFlag: undefined,
184
- phaseFlag: undefined,
439
+ settlement: "accepted",
440
+ /** Bound comparison base is the initial prompt; instruction follows. */
441
+ transportPrompt: "baseline",
442
+ acceptedText: "左拾遗回执已接受",
443
+ activationFlags: [
444
+ { field: "baseRevision", flag: "ak-gleaner-left-base" },
445
+ ],
185
446
  activationStage: "load-and-install",
186
447
  sessionMaterials: [
187
448
  "CLAUDE.md",
@@ -191,10 +452,35 @@ export const PUBLIC_ROLE_RECORDS = [
191
452
  },
192
453
  {
193
454
  role: "inspector",
455
+ inCallAutoResume: false,
456
+ presentSettled: "always",
457
+ summonResume: false,
458
+ admission: "instruction",
459
+ sameParent: "gate-pointer",
460
+ /** Resume restores an optional source-run path onto the admitted face. */
461
+ resumeSourcePath: true,
462
+ /** Infrastructure failure at this stage has no accepted gate cycle to project. */
463
+ skipGateOnInfrastructureStage: true,
464
+ /** 台院 is a review officer and inherits the gatekeeper model. */
465
+ reviewOfficer: true,
466
+ provinceConfig: true,
467
+ modelInheritsFrom: "gatekeeper",
194
468
  phases: [null],
195
469
  outputTool: INSPECTOR_OUTPUT_TOOL_NAME,
196
- inputFlag: "ak-inspector-source-run",
197
- phaseFlag: undefined,
470
+ settlement: "accepted",
471
+ /** Court reask replaces the initial prompt. */
472
+ reaskPrompt: true,
473
+ acceptedText: "台院回执已接受",
474
+ gateStageLabel: "台院",
475
+ activationFlags: [
476
+ {
477
+ field: "sourceRun",
478
+ from: "sourceRunPath",
479
+ fallback: "gate-pointer",
480
+ flag: "ak-inspector-source-run",
481
+ binds: "input",
482
+ },
483
+ ],
198
484
  activationStage: "load-and-install",
199
485
  sessionMaterials: INSPECTOR_SESSION_MATERIALS,
200
486
  },
@@ -203,30 +489,63 @@ export const PUBLIC_ROLE_RECORDS = [
203
489
  // unchanged and orthogonal to callability.
204
490
  {
205
491
  role: "gatekeeper",
492
+ inCallAutoResume: false,
493
+ presentSettled: "always",
494
+ summonResume: true,
495
+ admission: "instruction",
496
+ /** Infrastructure failure at this stage has no accepted gate cycle to project. */
497
+ skipGateOnInfrastructureStage: true,
498
+ sameParent: "none",
499
+ /** Province model root. Officers name this seat via modelInheritsFrom. */
500
+ provinceConfig: true,
206
501
  phases: [null],
207
502
  outputTool: GATEKEEPER_OUTPUT_TOOL_NAME,
208
- inputFlag: undefined,
209
- phaseFlag: undefined,
503
+ settlement: "accepted",
504
+ runnerFailure: "engine-detour-record-first",
505
+ acceptedText: "门下省决议已受理",
210
506
  activationStage: "load-and-install",
211
507
  // Province materials; officers reuse their own public records below.
212
508
  sessionMaterials: ["CLAUDE.md", "souls/gatekeeper.md", "souls/quality-law.md", "souls/gate-output-guide.md"],
213
509
  },
214
510
  {
215
511
  role: "navigator",
512
+ inCallAutoResume: false,
513
+ presentSettled: "always",
514
+ summonResume: true,
515
+ admission: "instruction",
516
+ sameParent: "none",
216
517
  phases: [null],
217
518
  outputTool: NAVIGATOR_OUTPUT_TOOL_NAME,
218
- inputFlag: undefined,
219
- phaseFlag: undefined,
519
+ settlement: "accepted",
520
+ runnerFailure: "engine-detour-record-first",
521
+ acceptedText: "游奕使建议已受理",
220
522
  activationStage: "load-and-install",
221
523
  sessionMaterials: ["CLAUDE.md", "souls/navigator.md"],
222
524
  },
223
525
  // #675: 审刑院 is a role like any other — public ak-role entry. (#744: evidence-child deleted)
224
526
  {
225
527
  role: "auditor",
528
+ inCallAutoResume: false,
529
+ presentSettled: "always",
530
+ summonResume: true,
531
+ admission: "instruction",
532
+ sameParent: "subject-source",
533
+ /** --subject chooses which audited seat the soul comes from. */
534
+ subjectChoices: ["judge", "doctor"],
535
+ /** 审刑院 is a review officer. Model stays on its own seat row. */
536
+ reviewOfficer: true,
537
+ /** Subject input selects the soul. The public materials list is the ship roster. */
538
+ soulSource: "subject",
226
539
  phases: [null],
227
540
  outputTool: AUDITOR_OUTPUT_TOOL_NAME,
228
- inputFlag: undefined,
229
- phaseFlag: undefined,
541
+ settlement: "accepted",
542
+ /** Court reask replaces the initial prompt. */
543
+ reaskPrompt: true,
544
+ runnerFailure: "engine-detour-record-first",
545
+ acceptedText: "审刑院回执已接受",
546
+ gateStageLabel: "审刑院",
547
+ /** Gate summon binds --subject judge and --source-run. */
548
+ gateSummon: "subject-source",
230
549
  activationStage: "load-and-install",
231
550
  sessionMaterials: AUDITOR_PUBLIC_SESSION_MATERIALS,
232
551
  },
@@ -234,10 +553,15 @@ export const PUBLIC_ROLE_RECORDS = [
234
553
  // No input flag — LLM finds materials itself (caller-transparent).
235
554
  {
236
555
  role: "diarist",
556
+ inCallAutoResume: false,
557
+ presentSettled: "always",
558
+ summonResume: false,
559
+ admission: "instruction",
560
+ sameParent: "board-ticket",
237
561
  phases: [null],
238
562
  outputTool: DIARIST_OUTPUT_TOOL_NAME,
239
- inputFlag: undefined,
240
- phaseFlag: undefined,
563
+ settlement: "accepted",
564
+ acceptedText: "起居郎回执已接受",
241
565
  activationStage: "load-and-install",
242
566
  sessionMaterials: [
243
567
  "CLAUDE.md",
@@ -268,14 +592,259 @@ export function packagedRoleMetadata(role: string): PackagedRoleMetadata | undef
268
592
  return PACKAGED_ROLE_REGISTRY.find((entry) => entry.role === role);
269
593
  }
270
594
 
595
+ /** Review officers (台院 / 符宝郎 / 审刑院). Absent on every other seat. */
596
+ export function isOfficerReviewSeat(role: string): boolean {
597
+ const record = packagedRoleMetadata(role);
598
+ return record !== undefined && "reviewOfficer" in record && record.reviewOfficer === true;
599
+ }
600
+
601
+ /** Province seats that may carry a persistent model override. */
602
+ export function packagedProvinceConfig(role: string): boolean {
603
+ const record = packagedRoleMetadata(role);
604
+ return record !== undefined && "provinceConfig" in record && record.provinceConfig === true;
605
+ }
606
+
607
+ /**
608
+ * Model parent for a subordinate province officer.
609
+ * The province root has none and does not inherit from itself.
610
+ */
611
+ export function packagedModelParent(role: string): PackagedRole | undefined {
612
+ const record = packagedRoleMetadata(role);
613
+ if (record === undefined || !("modelInheritsFrom" in record)) return undefined;
614
+ return record.modelInheritsFrom;
615
+ }
616
+
617
+ /**
618
+ * One seat's admitted → activation copy.
619
+ * `field` is the activation key. `from` is the admitted path when it differs.
620
+ * `text` writes a number as decimal text on the activation object.
621
+ * `fallback: "gate-pointer"` is the inspector instruction pointer when sourceRunPath is blank.
622
+ * `flag` omitted: the value stays on the activation object and is not a host flag
623
+ * (secretariat and countersign ticketNumber).
624
+ */
625
+ export type PackagedActivationFlag = {
626
+ readonly field: string;
627
+ readonly from?: string;
628
+ readonly text?: true;
629
+ readonly fallback?: "gate-pointer";
630
+ readonly flag?: string;
631
+ readonly binds?: "input" | "phase";
632
+ };
633
+
634
+ /**
635
+ * Output tool for seats whose settlement leaf is the shared accepted-tool scan.
636
+ * Any other settlement leaf names that seat's own reader.
637
+ */
638
+ export function packagedRoleAcceptedOutputTool(role: string): string | undefined {
639
+ const record = packagedRoleMetadata(role);
640
+ if (record === undefined || !("settlement" in record) || record.settlement !== "accepted") {
641
+ return undefined;
642
+ }
643
+ return record.outputTool;
644
+ }
645
+
646
+ /** Host flags for one seat. Absent means this seat publishes only `ak-role`. */
647
+ export function packagedRoleActivationFlags(role: string): readonly PackagedActivationFlag[] {
648
+ const record = packagedRoleMetadata(role);
649
+ if (record === undefined || !("activationFlags" in record)) return [];
650
+ return record.activationFlags;
651
+ }
652
+
271
653
  export function packagedRoleInputFlag(role: string): string | undefined {
272
- return packagedRoleMetadata(role)?.inputFlag;
654
+ return packagedRoleActivationFlags(role).find((spec) => spec.binds === "input")?.flag;
273
655
  }
274
656
 
275
657
  export function packagedRolePhaseFlag(role: string): string | undefined {
276
- return packagedRoleMetadata(role)?.phaseFlag;
658
+ return packagedRoleActivationFlags(role).find((spec) => spec.binds === "phase")?.flag;
277
659
  }
278
660
 
279
661
  export function packagedRoleOutputTool(role: string): string | undefined {
280
662
  return packagedRoleMetadata(role)?.outputTool;
281
663
  }
664
+
665
+ /** Accept-face text for a registered seat. One registry leaf; callers do not keep a copy. */
666
+ export function packagedRoleAcceptedText(role: string): string {
667
+ const record = packagedRoleMetadata(role);
668
+ if (record === undefined) {
669
+ throw new Error(`Unsupported workflow role: ${String(role)}`);
670
+ }
671
+ return record.acceptedText;
672
+ }
673
+
674
+ /** Method-material load failure cause declared on the seat. Absent means no typed cause. */
675
+ export function packagedMethodLoadFailureCause(role: string): "activation" | undefined {
676
+ const record = packagedRoleMetadata(role);
677
+ if (record === undefined || !("methodLoadFailureCause" in record)) return undefined;
678
+ return record.methodLoadFailureCause;
679
+ }
680
+
681
+ /** Diarist binds a board ticket onto its own run. Other seats do not. */
682
+ export function packagedBindsBoardTicket(role: string): boolean {
683
+ const record = packagedRoleMetadata(role);
684
+ return record?.sameParent === "board-ticket";
685
+ }
686
+
687
+ /** Notary resume may replace the stored source-run locator from the summons. */
688
+ export function packagedRebindSourceOnResume(role: string): boolean {
689
+ return packagedRoleMetadata(role)?.admission === "source-locator";
690
+ }
691
+
692
+ /** Countersign admission keeps deferred court identity on the public entry. */
693
+ export function packagedAdmitsCountersign(role: string): boolean {
694
+ return packagedRoleMetadata(role)?.admission === "court-materials";
695
+ }
696
+
697
+ export type PackagedBareToken = "burden" | "packet" | "instruction";
698
+
699
+ /** Public argv bare-token face. Absent means a bare token is instruction text. */
700
+ export function packagedBareToken(role: string): PackagedBareToken | undefined {
701
+ const record = packagedRoleMetadata(role);
702
+ if (record === undefined || !("bareToken" in record)) return undefined;
703
+ return record.bareToken;
704
+ }
705
+
706
+ /** Public argv result shape. Absent means instruction plus attachment paths. */
707
+ export function packagedArgvResult(role: string): "source-run" | "instruction" | "material" {
708
+ const record = packagedRoleMetadata(role);
709
+ if (record !== undefined && "argvResult" in record) return record.argvResult;
710
+ return "material";
711
+ }
712
+
713
+ /** Source-run text is stored without trim. Absent means trim. */
714
+ export function packagedStoresSourceRunRaw(role: string): boolean {
715
+ const record = packagedRoleMetadata(role);
716
+ return record !== undefined && "sourceRunStored" in record && record.sourceRunStored === "raw";
717
+ }
718
+
719
+ /** --base is a single Skill-arg token. Absent means a path. */
720
+ export function packagedBaseIsRevision(role: string): boolean {
721
+ const record = packagedRoleMetadata(role);
722
+ return record !== undefined && "baseValue" in record && record.baseValue === "revision";
723
+ }
724
+
725
+ /** Authority refs are present on the parse result even when empty. */
726
+ export function packagedEmitsAuthorityRefs(role: string): boolean {
727
+ const record = packagedRoleMetadata(role);
728
+ return record !== undefined && "emitAuthorityRefs" in record && record.emitAuthorityRefs === true;
729
+ }
730
+
731
+ /** Allowed --subject values. Absent means the seat has no subject option. */
732
+ export function packagedSubjectChoices(role: string): readonly string[] | undefined {
733
+ const record = packagedRoleMetadata(role);
734
+ if (record === undefined || !("subjectChoices" in record)) return undefined;
735
+ return record.subjectChoices;
736
+ }
737
+
738
+ /** Admitted --subject when the value is one of the seat's declared choices. */
739
+ export function packagedAdmittedSubject(role: string, value: string): "judge" | "doctor" | undefined {
740
+ const choices = packagedSubjectChoices(role);
741
+ if (choices === undefined || !choices.includes(value)) return undefined;
742
+ const match = choices.find((choice) => choice === value);
743
+ if (match === "judge" || match === "doctor") return match;
744
+ return undefined;
745
+ }
746
+
747
+ /** Audit decision tool declared on the audited seat. */
748
+ export function packagedAuditToolName(role: string): string | undefined {
749
+ const record = packagedRoleMetadata(role);
750
+ if (record === undefined || !("auditTool" in record)) return undefined;
751
+ return record.auditTool;
752
+ }
753
+
754
+ /** Infrastructure-failure stage that must not be re-read as an accepted gate cycle. */
755
+ export function packagedSkipsGateOnInfrastructureStage(stage: unknown): boolean {
756
+ return typeof stage === "string" && PUBLIC_ROLE_RECORDS.some((record) =>
757
+ "skipGateOnInfrastructureStage" in record
758
+ && record.skipGateOnInfrastructureStage === true
759
+ && record.role === stage
760
+ );
761
+ }
762
+
763
+ /** Durable officer entry whose name is the seat role. */
764
+ export function packagedDurableOfficerEntry(officer: unknown): boolean {
765
+ return typeof officer === "string" && PUBLIC_ROLE_RECORDS.some((record) =>
766
+ "durableOfficerEntry" in record
767
+ && record.durableOfficerEntry === true
768
+ && record.role === officer
769
+ );
770
+ }
771
+
772
+ /** Admitted-request role whose navigator subject is the public instruction. */
773
+ export function packagedPublicInstructionSubject(role: unknown): boolean {
774
+ return typeof role === "string" && PUBLIC_ROLE_RECORDS.some((record) =>
775
+ "navigatorSubject" in record
776
+ && record.navigatorSubject === "public-instruction"
777
+ && record.role === role
778
+ );
779
+ }
780
+
781
+ /** Resume restores an optional source-run path. */
782
+ export function packagedResumeSourcePath(role: string): boolean {
783
+ const record = packagedRoleMetadata(role);
784
+ return record !== undefined && "resumeSourcePath" in record && record.resumeSourcePath === true;
785
+ }
786
+
787
+ /** Public no_receipt projects a durable bind-target rejection. */
788
+ export function packagedProjectsTargetBindRejection(role: string): boolean {
789
+ const record = packagedRoleMetadata(role);
790
+ return record !== undefined
791
+ && "projectTargetBindRejection" in record
792
+ && record.projectTargetBindRejection === true;
793
+ }
794
+
795
+ export function packagedNavigatorSubject(
796
+ role: string,
797
+ ): "file" | "case" | "source-run" | "public-instruction" {
798
+ const record = packagedRoleMetadata(role);
799
+ if (record !== undefined && "navigatorSubject" in record) return record.navigatorSubject;
800
+ return "file";
801
+ }
802
+
803
+ export type PackagedBoardPlacement = "judge-history" | "coder" | "marshal" | "collector";
804
+
805
+ /** Factory-board column for a packaged seat. Absent seats use the board's other bucket. */
806
+ export function packagedBoardPlacement(role: string): PackagedBoardPlacement | undefined {
807
+ const record = packagedRoleMetadata(role);
808
+ if (record === undefined || !("boardPlacement" in record)) return undefined;
809
+ return record.boardPlacement;
810
+ }
811
+
812
+ /** Taishi terminal discriminator declared on the seat. Absent means the shared status leaf. */
813
+ export function packagedAnalystTerminal(role: string): "groups" | undefined {
814
+ const record = packagedRoleMetadata(role);
815
+ if (record === undefined || !("analystTerminal" in record)) return undefined;
816
+ return record.analystTerminal;
817
+ }
818
+
819
+ export function packagedRoleSessionMaterials(role: string): readonly string[] | undefined {
820
+ return PUBLIC_ROLE_RECORDS.find((entry) => entry.role === role)?.sessionMaterials;
821
+ }
822
+
823
+ export function isNavigatorSeat(role: string): boolean {
824
+ return packagedRoleOutputTool(role) === NAVIGATOR_OUTPUT_TOOL_NAME;
825
+ }
826
+
827
+ /** Gate-province display label. Absent when the seat is not a gate stage. */
828
+ export function packagedGateStageLabel(role: string): string | undefined {
829
+ const record = packagedRoleMetadata(role);
830
+ if (record === undefined || !("gateStageLabel" in record)) return undefined;
831
+ return record.gateStageLabel;
832
+ }
833
+
834
+ /** Countersign gate queue reads countersignStatus. Every other officer uses the shared three-state. */
835
+ export type PackagedGateSummon = "source-run" | "subject-source" | "parent-instruction" | "pointer";
836
+
837
+ /** How the gate caller builds one officer summons. Pointer is the inspector face. */
838
+ export function packagedGateSummon(role: string): PackagedGateSummon {
839
+ const record = packagedRoleMetadata(role);
840
+ if (record !== undefined && "gateSummon" in record) return record.gateSummon;
841
+ return "pointer";
842
+ }
843
+
844
+ export function packagedGateDecision(role: string): "countersign-status" | "three-state" {
845
+ const record = packagedRoleMetadata(role);
846
+ if (record !== undefined && "gateDecision" in record && record.gateDecision === "countersign-status") {
847
+ return "countersign-status";
848
+ }
849
+ return "three-state";
850
+ }