@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.
- package/dist/acp-host/production-host.js +19434 -18218
- package/dist/analyst-book-key.js +63 -0
- package/dist/analyst-cohort.js +167 -0
- package/dist/analyst-entry.js +320 -0
- package/dist/analyst-index.js +247 -0
- package/dist/analyst-ledger.js +561 -0
- package/dist/analyst-median.js +16 -0
- package/dist/analyst-metric-families/acceptance-success-rework.js +249 -0
- package/dist/analyst-metric-families/b2-frame-buckets-actions.js +189 -0
- package/dist/analyst-metric-families/gate-cycles.js +77 -0
- package/dist/analyst-metric-families/leg-wall-clock.js +56 -0
- package/dist/analyst-metric-families/round-timeline.js +126 -0
- package/dist/analyst-metric-families.js +23 -0
- package/dist/analyst-metric-family.js +11 -0
- package/dist/analyst-model-groups.js +135 -0
- package/dist/analyst-page.js +182 -0
- package/dist/atomic-write.js +23 -0
- package/dist/auditor-soul.js +1 -1
- package/dist/countersign-contracts.js +0 -2
- package/dist/diarist-contracts.js +0 -1
- package/dist/doctor-contracts.js +2 -2
- package/dist/gatekeeper-role.js +15 -16
- package/dist/gleaner-left-contracts.js +0 -2
- package/dist/headless-host/production-host.js +16967 -15749
- package/dist/host-contracts.js +0 -4
- package/dist/inspector-contracts.js +0 -2
- package/dist/institutional-resolution.js +4 -2
- package/dist/merger-contracts.js +0 -2
- package/dist/migrate-book-topology.js +3908 -3089
- package/dist/navigator-public-session.js +4 -3
- package/dist/notary-contracts.js +0 -2
- package/dist/package-contracts/auditor-output.js +0 -1
- package/dist/package-contracts/collector-output.js +0 -2
- package/dist/package-contracts/fixer-output.js +0 -2
- package/dist/package-contracts/gatekeeper-output.js +0 -2
- package/dist/package-contracts/judge-output.js +0 -2
- package/dist/package-contracts/navigator-output.js +0 -2
- package/dist/package-contracts/reviewer-output.js +0 -2
- package/dist/package-contracts/terminating-tools.js +32 -92
- package/dist/package-contracts/worker-output.js +0 -4
- package/dist/packaged-role-registry.js +518 -36
- package/dist/pi/role-turn-host.js +2 -1
- package/dist/public-cli/analyst-run.js +185 -0
- package/dist/public-cli/cli.js +885 -0
- package/dist/public-cli/config.js +12 -9
- package/dist/public-cli/countersign-run.js +4 -311
- package/dist/public-cli/instruction-seat-run.js +628 -158
- package/dist/public-cli/invocation.js +806 -1550
- package/dist/public-cli/main.js +6962 -9882
- package/dist/public-cli/option-definitions.js +51 -99
- package/dist/public-cli/post-admission.js +30 -2
- package/dist/public-cli/run-lifecycle.js +234 -353
- package/dist/public-cli/seat-ticket-binding.js +6 -0
- package/dist/public-cli/settlement.js +261 -675
- package/dist/public-cli/turn-request.js +76 -0
- package/dist/public-role-summons.js +38 -112
- package/dist/role-activation-flags.js +23 -45
- package/dist/secretariat-contracts.js +0 -2
- package/dist/session-identity.js +17 -8
- package/dist/session-opening-materials.js +3 -2
- package/extensions/role-runtime.ts +6 -80
- package/package.json +1 -1
- package/src/acp-host/role-turn-host.ts +4 -1
- package/src/analyst-metric-families/acceptance-success-rework.ts +3 -2
- package/src/auditor-role.ts +1 -2
- package/src/auditor-soul.ts +1 -1
- package/src/collector-role.ts +2 -2
- package/src/countersign-contracts.ts +0 -1
- package/src/countersign-role.ts +1 -1
- package/src/diarist-contracts.ts +0 -1
- package/src/diarist-role.ts +0 -1
- package/src/doctor-auditor.ts +1 -2
- package/src/doctor-contracts.ts +1 -1
- package/src/doctor-role.ts +3 -2
- package/src/external-host-turn-loop.ts +1 -1
- package/src/factory-board.ts +10 -7
- package/src/gatekeeper-role.ts +16 -10
- package/src/gleaner-left-contracts.ts +0 -1
- package/src/gleaner-left-role.ts +0 -1
- package/src/headless-host/role-turn-host.ts +7 -1
- package/src/host-contracts.ts +10 -6
- package/src/inspector-contracts.ts +0 -1
- package/src/inspector-role.ts +0 -2
- package/src/institutional-resolution.ts +6 -4
- package/src/judge-role.ts +3 -3
- package/src/merger-contracts.ts +0 -1
- package/src/merger-role.ts +2 -2
- package/src/navigator-public-session.ts +7 -6
- package/src/navigator-work-context.ts +6 -8
- package/src/notary-contracts.ts +0 -1
- package/src/notary-role.ts +2 -3
- package/src/package-contracts/auditor-output.ts +0 -1
- package/src/package-contracts/collector-output.ts +0 -1
- package/src/package-contracts/fixer-output.ts +0 -1
- package/src/package-contracts/gatekeeper-output.ts +0 -1
- package/src/package-contracts/judge-output.ts +0 -1
- package/src/package-contracts/navigator-output.ts +0 -1
- package/src/package-contracts/reviewer-output.ts +0 -1
- package/src/package-contracts/terminating-tools.ts +27 -99
- package/src/package-contracts/worker-output.ts +0 -2
- package/src/packaged-role-registry.ts +604 -35
- package/src/pi/role-turn-host.ts +2 -1
- package/src/public-cli/cli.ts +64 -259
- package/src/public-cli/config.ts +18 -10
- package/src/public-cli/countersign-run.ts +14 -449
- package/src/public-cli/instruction-seat-run.ts +758 -277
- package/src/public-cli/invocation.ts +1097 -2051
- package/src/public-cli/option-definitions.ts +62 -127
- package/src/public-cli/post-admission.ts +47 -2
- package/src/public-cli/run-lifecycle.ts +303 -613
- package/src/public-cli/seat-ticket-binding.ts +6 -0
- package/src/public-cli/settlement.ts +399 -1185
- package/src/public-cli/turn-request.ts +92 -1
- package/src/public-role-summons.ts +44 -128
- package/src/reviewer-role.ts +3 -2
- package/src/role-activation-flags.ts +20 -41
- package/src/role-runtime-dependencies.ts +25 -26
- package/src/role-runtime.ts +121 -232
- package/src/secretariat-contracts.ts +0 -1
- package/src/secretariat-role.ts +0 -2
- package/src/session-identity.ts +23 -8
- package/src/session-opening-materials.ts +2 -1
- package/src/worker-role.ts +3 -4
- package/dist/doctor-auditor.js +0 -25
- package/dist/public-cli/diarist-run.js +0 -130
- package/dist/public-cli/doctor-run.js +0 -87
- package/dist/public-cli/inspector-run.js +0 -151
- package/dist/public-cli/judge-run.js +0 -114
- package/dist/public-cli/notary-run.js +0 -174
- package/dist/public-cli/reviewer-run.js +0 -339
- package/src/public-cli/coder-run.ts +0 -255
- package/src/public-cli/collector-run.ts +0 -189
- package/src/public-cli/diarist-run.ts +0 -233
- package/src/public-cli/doctor-run.ts +0 -167
- package/src/public-cli/fixer-run.ts +0 -265
- package/src/public-cli/gleaner-left-run.ts +0 -167
- package/src/public-cli/inspector-run.ts +0 -261
- package/src/public-cli/judge-run.ts +0 -196
- package/src/public-cli/merger-run.ts +0 -294
- package/src/public-cli/notary-run.ts +0 -279
- package/src/public-cli/reviewer-run.ts +0 -480
- 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
|
-
|
|
59
|
-
|
|
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
|
-
|
|
74
|
-
|
|
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
|
-
|
|
88
|
-
|
|
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
|
-
|
|
103
|
-
|
|
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
|
-
|
|
119
|
-
|
|
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
|
-
|
|
129
|
-
|
|
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
|
-
|
|
138
|
-
|
|
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
|
-
|
|
148
|
-
|
|
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
|
-
|
|
157
|
-
|
|
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
|
-
|
|
167
|
-
|
|
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
|
-
|
|
184
|
-
|
|
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
|
-
|
|
197
|
-
|
|
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
|
-
|
|
209
|
-
|
|
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
|
-
|
|
219
|
-
|
|
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
|
-
|
|
229
|
-
|
|
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
|
-
|
|
240
|
-
|
|
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
|
|
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
|
|
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
|
+
}
|