@akagilnc/pi-workflow-roles 0.1.5015 → 0.1.5063
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/README.md +2 -2
- package/README.zh-CN.md +2 -2
- package/THIRD_PARTY_NOTICES.md +8 -8
- package/dist/acp-host/production-host.js +525 -978
- package/dist/headless-host/description.js +0 -2
- package/dist/headless-host/production-host.js +528 -1014
- package/dist/host-descriptions.js +2 -3
- package/dist/migrate-book-topology.js +7 -12
- package/dist/packaged-role-registry.js +20 -18
- package/dist/pi/role-turn-host.js +3 -27
- package/dist/public-cli/cli.js +23 -2
- package/dist/public-cli/countersign-run.js +13 -8
- package/dist/public-cli/instruction-seat-run.js +75 -107
- package/dist/public-cli/invocation.js +13 -32
- package/dist/public-cli/machine-method-skills.js +150 -0
- package/dist/public-cli/main.js +549 -679
- package/dist/public-cli/post-admission.js +10 -5
- package/dist/public-cli/registry.js +2 -1
- package/dist/public-cli/run-lifecycle.js +12 -15
- package/dist/public-cli/seat-ticket-binding.js +5 -8
- package/dist/public-cli/settlement.js +12 -99
- package/dist/public-cli/turn-request.js +16 -8
- package/dist/public-role-summons.js +8 -3
- package/package.json +5 -1
- package/resources/countersign-ticket-issue.md +5 -0
- package/resources/diarist-collect.md +1 -0
- package/resources/secretariat-ticket-identity.md +15 -0
- package/scripts/build-package.mjs +1 -6
- package/src/headless-host/description.ts +0 -3
- package/src/headless-host/role-turn-host.ts +2 -23
- package/src/host-contracts.ts +2 -23
- package/src/host-descriptions.ts +2 -3
- package/src/packaged-role-registry.ts +17 -16
- package/src/pi/adapter.ts +0 -27
- package/src/pi/role-turn-host.ts +3 -31
- package/src/public-cli/cli.ts +24 -2
- package/src/public-cli/countersign-run.ts +17 -10
- package/src/public-cli/instruction-seat-run.ts +75 -105
- package/src/public-cli/invocation.ts +10 -38
- package/src/public-cli/machine-method-skills.ts +153 -0
- package/src/public-cli/post-admission.ts +12 -6
- package/src/public-cli/registry.ts +1 -0
- package/src/public-cli/run-lifecycle.ts +12 -13
- package/src/public-cli/seat-ticket-binding.ts +5 -8
- package/src/public-cli/settlement.ts +6 -138
- package/src/public-cli/turn-request.ts +24 -16
- package/src/public-role-summons.ts +16 -3
- package/src/reviewer-role.ts +1 -12
- package/src/role-envelope.ts +0 -13
- package/src/role-runtime-dependencies.ts +0 -13
- package/src/role-runtime.ts +4 -56
- package/src/worker-role.ts +1 -81
- package/dist/method-host-plugin/.claude-plugin/plugin.json +0 -5
- package/dist/method-host-plugin/skills/ak-cross-m-review/CONTEXT.md +0 -48
- package/dist/method-host-plugin/skills/ak-cross-m-review/LICENSE +0 -21
- package/dist/method-host-plugin/skills/ak-cross-m-review/SKILL.md +0 -170
- package/dist/method-host-plugin/skills/ak-cross-m-review/prompts/cmr-completeness.md +0 -118
- package/dist/method-host-plugin/skills/ak-cross-m-review/prompts/cmr-reviewer.md +0 -128
- package/dist/method-host-plugin/skills/ak-cross-m-review/provenance.json +0 -41
- package/dist/method-host-plugin/skills/diagnosing-bugs/SKILL.md +0 -134
- package/dist/method-host-plugin/skills/diagnosing-bugs/agents/openai.yaml +0 -3
- package/dist/method-host-plugin/skills/diagnosing-bugs/provenance.json +0 -31
- package/dist/method-host-plugin/skills/diagnosing-bugs/scripts/hitl-loop.template.sh +0 -41
- package/dist/method-host-plugin/skills/resolving-merge-conflicts/SKILL.md +0 -14
- package/dist/method-host-plugin/skills/resolving-merge-conflicts/agents/openai.yaml +0 -3
- package/dist/method-host-plugin/skills/resolving-merge-conflicts/provenance.json +0 -26
- package/dist/method-host-plugin/skills/tdd/SKILL.md +0 -38
- package/dist/method-host-plugin/skills/tdd/agents/openai.yaml +0 -3
- package/dist/method-host-plugin/skills/tdd/mocking.md +0 -59
- package/dist/method-host-plugin/skills/tdd/provenance.json +0 -36
- package/dist/method-host-plugin/skills/tdd/tests.md +0 -77
- package/dist/package-resources/method-skill.js +0 -259
- package/resources/method-host-plugin/.claude-plugin/plugin.json +0 -5
- package/resources/methods/ak-cross-m-review/CONTEXT.md +0 -48
- package/resources/methods/ak-cross-m-review/LICENSE +0 -21
- package/resources/methods/ak-cross-m-review/SKILL.md +0 -170
- package/resources/methods/ak-cross-m-review/prompts/cmr-completeness.md +0 -118
- package/resources/methods/ak-cross-m-review/prompts/cmr-reviewer.md +0 -128
- package/resources/methods/ak-cross-m-review/provenance.json +0 -41
- package/resources/methods/diagnosing-bugs/SKILL.md +0 -134
- package/resources/methods/diagnosing-bugs/agents/openai.yaml +0 -3
- package/resources/methods/diagnosing-bugs/provenance.json +0 -31
- package/resources/methods/diagnosing-bugs/scripts/hitl-loop.template.sh +0 -41
- package/resources/methods/resolving-merge-conflicts/SKILL.md +0 -14
- package/resources/methods/resolving-merge-conflicts/agents/openai.yaml +0 -3
- package/resources/methods/resolving-merge-conflicts/provenance.json +0 -26
- package/resources/methods/tdd/SKILL.md +0 -38
- package/resources/methods/tdd/agents/openai.yaml +0 -3
- package/resources/methods/tdd/mocking.md +0 -59
- package/resources/methods/tdd/provenance.json +0 -36
- package/resources/methods/tdd/tests.md +0 -77
- package/src/canonical-skill-binding.ts +0 -118
- package/src/host-native-method.ts +0 -185
- package/src/package-resources/method-skill-binding.ts +0 -60
- package/src/package-resources/method-skill.ts +0 -363
package/src/host-descriptions.ts
CHANGED
|
@@ -56,9 +56,8 @@ export const HOST_DESCRIPTIONS: Readonly<Record<string, AcpHostDescription>> = O
|
|
|
56
56
|
* Headless CLI family (#645 / #646). Claude print-mode is the first row;
|
|
57
57
|
* codex exec (#646) adds another. Protocol-specific argv/parse live in
|
|
58
58
|
* headless-host helpers (#752 per-host impl).
|
|
59
|
-
* Claude fixedArgs: print mode
|
|
60
|
-
* host events for sitian records (#811); result is last line.
|
|
61
|
-
* ride `--plugin-dir` (#922); operator skill/setting surfaces stay open.
|
|
59
|
+
* Claude fixedArgs: print mode. stream-json + verbose: live
|
|
60
|
+
* host events for sitian records (#811); result is last line.
|
|
62
61
|
*/
|
|
63
62
|
export const HEADLESS_HOST_DESCRIPTIONS: Readonly<Record<string, HeadlessHostDescription>> = Object.freeze({
|
|
64
63
|
"claude": Object.freeze({
|
|
@@ -42,7 +42,6 @@ export type PackagedArtifactFace = {
|
|
|
42
42
|
readonly reportPhase?: true;
|
|
43
43
|
readonly evidenceRole?: true;
|
|
44
44
|
readonly leaves: readonly PackagedArtifactLeaf[];
|
|
45
|
-
readonly method?: "optional" | "observed";
|
|
46
45
|
readonly doctorReportFacts?: true;
|
|
47
46
|
};
|
|
48
47
|
|
|
@@ -132,7 +131,6 @@ export const PUBLIC_ROLE_RECORDS = [
|
|
|
132
131
|
{ key: "prerequisitesPath", omitUndefined: true },
|
|
133
132
|
{ key: "prerequisites" },
|
|
134
133
|
],
|
|
135
|
-
method: "observed",
|
|
136
134
|
},
|
|
137
135
|
boardPlacement: "marshal",
|
|
138
136
|
activationFlags: [
|
|
@@ -158,7 +156,6 @@ export const PUBLIC_ROLE_RECORDS = [
|
|
|
158
156
|
worker: true,
|
|
159
157
|
applyMethod: "tdd",
|
|
160
158
|
/** Method-material load failure keeps the activation cause (not reviewer/fixer). */
|
|
161
|
-
methodLoadFailureCause: "activation",
|
|
162
159
|
boardPlacement: "coder",
|
|
163
160
|
phases: ["plan", "apply"],
|
|
164
161
|
outputTool: CODER_OUTPUT_TOOL_NAME,
|
|
@@ -170,7 +167,6 @@ export const PUBLIC_ROLE_RECORDS = [
|
|
|
170
167
|
{ key: "phase" },
|
|
171
168
|
{ key: "taskPath" },
|
|
172
169
|
],
|
|
173
|
-
method: "optional",
|
|
174
170
|
},
|
|
175
171
|
activationFlags: [
|
|
176
172
|
{ field: "taskPath", flag: "ak-coder-task", binds: "input" },
|
|
@@ -212,7 +208,6 @@ export const PUBLIC_ROLE_RECORDS = [
|
|
|
212
208
|
{ key: "authorityRefs", copyArray: true },
|
|
213
209
|
{ key: "callerProvenance", callerProvenance: true },
|
|
214
210
|
],
|
|
215
|
-
method: "observed",
|
|
216
211
|
},
|
|
217
212
|
/** Frozen base/lens/authority become the initial prompt; instruction follows. */
|
|
218
213
|
transportPrompt: "skill-args",
|
|
@@ -311,7 +306,6 @@ export const PUBLIC_ROLE_RECORDS = [
|
|
|
311
306
|
methodSkills: ["resolving-merge-conflicts"],
|
|
312
307
|
settleMethod: "resolving-merge-conflicts",
|
|
313
308
|
/** Method-material load failure keeps the activation cause (not reviewer/fixer). */
|
|
314
|
-
methodLoadFailureCause: "activation",
|
|
315
309
|
phases: [null],
|
|
316
310
|
outputTool: MERGER_OUTPUT_TOOL_NAME,
|
|
317
311
|
settlement: "residual",
|
|
@@ -324,7 +318,6 @@ export const PUBLIC_ROLE_RECORDS = [
|
|
|
324
318
|
{ key: "mergerInputPath" },
|
|
325
319
|
{ key: "derived" },
|
|
326
320
|
],
|
|
327
|
-
method: "observed",
|
|
328
321
|
},
|
|
329
322
|
activationFlags: [
|
|
330
323
|
{ field: "inputPath", from: "mergerInputPath", flag: "ak-merger-input", binds: "input" },
|
|
@@ -391,7 +384,7 @@ export const PUBLIC_ROLE_RECORDS = [
|
|
|
391
384
|
activationStage: "load-and-install",
|
|
392
385
|
receiptStatusKey: "status",
|
|
393
386
|
// #924: 公用《票面法》三席同装
|
|
394
|
-
sessionMaterials: ["CLAUDE.md", "souls/countersign.md", "souls/ticket-law.md"],
|
|
387
|
+
sessionMaterials: ["CLAUDE.md", "souls/countersign.md", "souls/ticket-law.md", "resources/countersign-ticket-issue.md"],
|
|
395
388
|
},
|
|
396
389
|
{
|
|
397
390
|
role: "secretariat",
|
|
@@ -399,7 +392,7 @@ export const PUBLIC_ROLE_RECORDS = [
|
|
|
399
392
|
presentSettled: "always",
|
|
400
393
|
summonResume: false,
|
|
401
394
|
admission: "instruction",
|
|
402
|
-
sameParent: "
|
|
395
|
+
sameParent: "none",
|
|
403
396
|
phases: [null],
|
|
404
397
|
outputTool: SECRETARIAT_OUTPUT_TOOL_NAME,
|
|
405
398
|
settlement: "accepted",
|
|
@@ -415,6 +408,7 @@ export const PUBLIC_ROLE_RECORDS = [
|
|
|
415
408
|
"CLAUDE.md",
|
|
416
409
|
"souls/secretariat.md",
|
|
417
410
|
"souls/ticket-law.md",
|
|
411
|
+
"resources/secretariat-ticket-identity.md",
|
|
418
412
|
"souls/countersign.md",
|
|
419
413
|
"souls/notary.md",
|
|
420
414
|
],
|
|
@@ -581,6 +575,20 @@ export function packagedRoleMetadata(role: string): PackagedRoleMetadata | undef
|
|
|
581
575
|
return PACKAGED_ROLE_REGISTRY.find((entry) => entry.role === role);
|
|
582
576
|
}
|
|
583
577
|
|
|
578
|
+
/** Names any public seat may require. Setup and missing-Skill checks both read this. */
|
|
579
|
+
export function packagedMethodSkillNames(): readonly string[] {
|
|
580
|
+
const names: string[] = [];
|
|
581
|
+
for (const record of PACKAGED_ROLE_REGISTRY) {
|
|
582
|
+
if ("methodSkills" in record && record.methodSkills !== undefined) {
|
|
583
|
+
for (const name of record.methodSkills) if (!names.includes(name)) names.push(name);
|
|
584
|
+
}
|
|
585
|
+
if ("applyMethod" in record && record.applyMethod !== undefined && !names.includes(record.applyMethod)) {
|
|
586
|
+
names.push(record.applyMethod);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
return names;
|
|
590
|
+
}
|
|
591
|
+
|
|
584
592
|
/** Review officers (台院 / 符宝郎 / 审刑院). Absent on every other seat. */
|
|
585
593
|
export function isOfficerReviewSeat(role: string): boolean {
|
|
586
594
|
const record = packagedRoleMetadata(role);
|
|
@@ -651,13 +659,6 @@ export function packagedRoleOutputTool(role: string): string | undefined {
|
|
|
651
659
|
return packagedRoleMetadata(role)?.outputTool;
|
|
652
660
|
}
|
|
653
661
|
|
|
654
|
-
/** Method-material load failure cause declared on the seat. Absent means no typed cause. */
|
|
655
|
-
export function packagedMethodLoadFailureCause(role: string): "activation" | undefined {
|
|
656
|
-
const record = packagedRoleMetadata(role);
|
|
657
|
-
if (record === undefined || !("methodLoadFailureCause" in record)) return undefined;
|
|
658
|
-
return record.methodLoadFailureCause;
|
|
659
|
-
}
|
|
660
|
-
|
|
661
662
|
/** Diarist binds a board ticket onto its own run. Other seats do not. */
|
|
662
663
|
export function packagedBindsBoardTicket(role: string): boolean {
|
|
663
664
|
const record = packagedRoleMetadata(role);
|
package/src/pi/adapter.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
parseSkillBlock,
|
|
3
2
|
type BeforeAgentStartEventResult,
|
|
4
3
|
type ExtensionAPI,
|
|
5
4
|
type ExtensionContext,
|
|
@@ -166,32 +165,6 @@ export function createPiRoleHostAdapter(
|
|
|
166
165
|
deliverSubmissionRejection(_rejection) {
|
|
167
166
|
// #836 删 1/A4.5: no package-authored non-sole resume sentence.
|
|
168
167
|
},
|
|
169
|
-
capabilities: {
|
|
170
|
-
skillExpansion(prompt) {
|
|
171
|
-
const parsed = parseSkillBlock(prompt);
|
|
172
|
-
if (parsed == null) return undefined;
|
|
173
|
-
const userMessage = parsed.userMessage ?? "";
|
|
174
|
-
return Object.freeze({
|
|
175
|
-
name: parsed.name,
|
|
176
|
-
location: parsed.location,
|
|
177
|
-
content: parsed.content,
|
|
178
|
-
userMessage,
|
|
179
|
-
});
|
|
180
|
-
},
|
|
181
|
-
/** Recover plain original request from Pi-native `/skill:` turn text (ADR 0082). */
|
|
182
|
-
skillOriginalRequest(name, text) {
|
|
183
|
-
const token = `/skill:${name}`;
|
|
184
|
-
const trimmed = text.trimStart();
|
|
185
|
-
if (
|
|
186
|
-
trimmed === token
|
|
187
|
-
|| trimmed.startsWith(`${token} `)
|
|
188
|
-
|| trimmed.startsWith(`${token}\n`)
|
|
189
|
-
) {
|
|
190
|
-
return text.slice(text.indexOf(token) + token.length).trim();
|
|
191
|
-
}
|
|
192
|
-
return text.trim();
|
|
193
|
-
},
|
|
194
|
-
},
|
|
195
168
|
registerFlag: (name, definition) => pi.registerFlag(name, definition),
|
|
196
169
|
getFlag: (name) => pi.getFlag(name),
|
|
197
170
|
registerTool: (tool) => pi.registerTool(toPiToolDefinition(
|
package/src/pi/role-turn-host.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { execFile, spawn } from "node:child_process";
|
|
7
7
|
import { constants } from "node:fs";
|
|
8
8
|
import { access, appendFile, readFile, realpath } from "node:fs/promises";
|
|
9
|
-
import {
|
|
9
|
+
import { delimiter, dirname, isAbsolute, join, resolve } from "node:path";
|
|
10
10
|
import { platform } from "node:process";
|
|
11
11
|
import { promisify } from "node:util";
|
|
12
12
|
import { randomUUID } from "node:crypto";
|
|
@@ -86,38 +86,12 @@ function buildMethodArgs(methods: readonly MethodBinding[]): string[] {
|
|
|
86
86
|
const skillArgs: string[] = [];
|
|
87
87
|
for (const method of methods) {
|
|
88
88
|
if (method.kind === "skill") {
|
|
89
|
-
skillArgs.push("--skill", method.path);
|
|
89
|
+
skillArgs.push("--skill", dirname(method.path));
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
return skillArgs;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
/**
|
|
96
|
-
* Pi-native `/skill:<name>` for a single forced method (ADR 0082: pi is one adapter
|
|
97
|
-
* with no privilege; Pi-only seams stay inside the pi adapter).
|
|
98
|
-
* Driven by typed RoleTurnRequest.methods — middle-layer decision, Pi-only syntax.
|
|
99
|
-
* Zero/many methods leave the prompt alone (Fixer optional pair stays `--skill` only).
|
|
100
|
-
*/
|
|
101
|
-
export function applyPiNativeSkillInvocation(
|
|
102
|
-
methods: readonly MethodBinding[],
|
|
103
|
-
prompt: string,
|
|
104
|
-
): string {
|
|
105
|
-
const skills = methods.filter((method) => method.kind === "skill");
|
|
106
|
-
if (skills.length !== 1) return prompt;
|
|
107
|
-
const name = basename(dirname(skills[0]!.path));
|
|
108
|
-
if (name.length === 0) return prompt;
|
|
109
|
-
const token = `/skill:${name}`;
|
|
110
|
-
const trimmed = prompt.trimStart();
|
|
111
|
-
if (
|
|
112
|
-
trimmed === token
|
|
113
|
-
|| trimmed.startsWith(`${token} `)
|
|
114
|
-
|| trimmed.startsWith(`${token}\n`)
|
|
115
|
-
) {
|
|
116
|
-
return prompt;
|
|
117
|
-
}
|
|
118
|
-
return prompt.length === 0 ? token : `${token} ${prompt}`;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
95
|
/**
|
|
122
96
|
* Pi last-hop argv after `--no-extensions -e entry` (#819).
|
|
123
97
|
* Activation flag membership comes from middle-layer projectActivationFlags;
|
|
@@ -165,9 +139,7 @@ function piUserDialogueBody(request: RoleTurnRequest): string {
|
|
|
165
139
|
const _exhaustive: never = request.continuation;
|
|
166
140
|
return _exhaustive;
|
|
167
141
|
})();
|
|
168
|
-
return
|
|
169
|
-
? rawPrompt
|
|
170
|
-
: applyPiNativeSkillInvocation(request.methods, rawPrompt);
|
|
142
|
+
return rawPrompt;
|
|
171
143
|
}
|
|
172
144
|
|
|
173
145
|
export type PiSpawnRunner = (
|
package/src/public-cli/cli.ts
CHANGED
|
@@ -48,6 +48,7 @@ import { packagedModelParent } from "../packaged-role-registry.ts";
|
|
|
48
48
|
import { seatModelOnly } from "./registry.ts";
|
|
49
49
|
import { CliUsageError } from "./cli-errors.ts";
|
|
50
50
|
import type { CliIo } from "./cli-io.ts";
|
|
51
|
+
import { runMachineSkillSetup } from "./machine-method-skills.ts";
|
|
51
52
|
import type { PostAdmissionEnv } from "./post-admission.ts";
|
|
52
53
|
import type { RoleTurnHost } from "../host-contracts.ts";
|
|
53
54
|
import { appendPiSessionCustomEntry } from "../pi/role-turn-host.ts";
|
|
@@ -77,7 +78,8 @@ import {
|
|
|
77
78
|
type PublicRoleOptionOwner,
|
|
78
79
|
type TypedOptionConsumer,
|
|
79
80
|
} from "./option-definitions.ts";
|
|
80
|
-
import { runPublicInstructionSeat, runPublicInstructionSeatResume } from "./instruction-seat-run.ts";
|
|
81
|
+
import { continueParentAfterChild, runPublicInstructionSeat, runPublicInstructionSeatResume } from "./instruction-seat-run.ts";
|
|
82
|
+
import { courtDiaristEscalated } from "./countersign-run.ts";
|
|
81
83
|
import { runPublicAnalyst } from "./analyst-run.ts";
|
|
82
84
|
import {
|
|
83
85
|
AUTO_RESUME_LIMIT,
|
|
@@ -1178,6 +1180,11 @@ export async function runAkRole(
|
|
|
1178
1180
|
};
|
|
1179
1181
|
}
|
|
1180
1182
|
|
|
1183
|
+
if (parsed.command === "setup") {
|
|
1184
|
+
if (parsed.args.length !== 0) throw new CliUsageError("setup takes no arguments");
|
|
1185
|
+
return { exitCode: await runMachineSkillSetup(home, io.stdout) };
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1181
1188
|
// #724 explicit fresh summons: `ak-role new <role> …` — same role argv, always mint.
|
|
1182
1189
|
// Rewrites onto the role command with freshSummons; auto-resume and resume stay intact.
|
|
1183
1190
|
if (parsed.command === "new") {
|
|
@@ -1229,7 +1236,22 @@ export async function runAkRole(
|
|
|
1229
1236
|
}),
|
|
1230
1237
|
io,
|
|
1231
1238
|
);
|
|
1232
|
-
|
|
1239
|
+
let current = result;
|
|
1240
|
+
while (
|
|
1241
|
+
current.exitCode === 0 && current.admitted?.correlationId !== undefined
|
|
1242
|
+
&& current.terminal?.roleOutcome.kind === "accepted"
|
|
1243
|
+
&& !courtDiaristEscalated(current.terminal.roleOutcome)
|
|
1244
|
+
) {
|
|
1245
|
+
const parentRunId = current.admitted.correlationId;
|
|
1246
|
+
const parentRole = await peekRoleRunRole(home, parentRunId);
|
|
1247
|
+
if (parentRole === undefined) break;
|
|
1248
|
+
const parentSeat = resolveEffectiveSeat(config, parentRole, credentials, invocationFromParsed(parsed));
|
|
1249
|
+
const parentEnv = createRoleEnvironment(env, {
|
|
1250
|
+
role: parentRole, home, agentDir, cwd, credentials, seat: parentSeat, config,
|
|
1251
|
+
});
|
|
1252
|
+
current = await continueParentAfterChild(parentRunId, current.admitted, parentEnv, io);
|
|
1253
|
+
}
|
|
1254
|
+
return cliResultFromRoleRun(current);
|
|
1233
1255
|
}
|
|
1234
1256
|
|
|
1235
1257
|
if (
|
|
@@ -45,8 +45,8 @@ export type CountersignRunEnv = PostAdmissionEnv & {
|
|
|
45
45
|
*/
|
|
46
46
|
gateReviewInstruction?: string;
|
|
47
47
|
/**
|
|
48
|
-
* #969 / #987 gate path: parent run durable board ticket handoff for bind
|
|
49
|
-
*
|
|
48
|
+
* #969 / #987 gate path: parent run durable board ticket handoff for bind.
|
|
49
|
+
* Same-ticket resume lookup narrows the parent path by this typed number.
|
|
50
50
|
*/
|
|
51
51
|
boundTicketNumber?: number;
|
|
52
52
|
/**
|
|
@@ -79,6 +79,7 @@ export type CourtDiaristIdentity =
|
|
|
79
79
|
export type CourtDiaristInvocationResult = {
|
|
80
80
|
readonly identity: CourtDiaristIdentity;
|
|
81
81
|
readonly admitted?: import("./invocation.ts").AdmittedRoleInvocation;
|
|
82
|
+
readonly terminal?: import("./terminal.ts").TerminalResult;
|
|
82
83
|
readonly failedWithoutEscalate?: { readonly diagnostic: string };
|
|
83
84
|
};
|
|
84
85
|
|
|
@@ -161,7 +162,7 @@ export type CourtDiaristSummonEnv = Pick<
|
|
|
161
162
|
* - Multiple submissions: last qualifying set wins.
|
|
162
163
|
* Live path never shape-rejects the role turn; durable damage is a separate seam.
|
|
163
164
|
*/
|
|
164
|
-
function courtTicketNumbersFromOutcome(
|
|
165
|
+
export function courtTicketNumbersFromOutcome(
|
|
165
166
|
roleOutcome: TerminalRoleOutcome | undefined,
|
|
166
167
|
principalTicket: number,
|
|
167
168
|
submissions?: readonly unknown[],
|
|
@@ -199,7 +200,7 @@ function courtTicketNumbersFromOutcome(
|
|
|
199
200
|
}
|
|
200
201
|
|
|
201
202
|
/** Routing boolean over the child's own typed sequence — does not pick or rewrite a sole row. */
|
|
202
|
-
function courtDiaristEscalated(
|
|
203
|
+
export function courtDiaristEscalated(
|
|
203
204
|
roleOutcome: TerminalRoleOutcome | undefined,
|
|
204
205
|
): boolean {
|
|
205
206
|
if (roleOutcome === undefined) return false;
|
|
@@ -280,6 +281,7 @@ export async function invokeCourtDiarist(
|
|
|
280
281
|
diagnostic: courtDiaristEscalateDiagnostic(roleOutcome, submissions),
|
|
281
282
|
},
|
|
282
283
|
...(result.admitted === undefined ? {} : { admitted: result.admitted }),
|
|
284
|
+
...(result.terminal === undefined ? {} : { terminal: result.terminal }),
|
|
283
285
|
};
|
|
284
286
|
}
|
|
285
287
|
|
|
@@ -328,14 +330,15 @@ export async function invokeCourtDiarist(
|
|
|
328
330
|
* Missing ticketNumber (true-unbound / identity deferred) skips the refresh
|
|
329
331
|
* station — no diary is minted for a true-unbound run. First-entry identity
|
|
330
332
|
* lives on the shared countersign entry (typed 起居郎 key for bind). Bound refresh:
|
|
331
|
-
*
|
|
333
|
+
* technical failure propagates; LLM escalation remains a recorded conclusion.
|
|
332
334
|
* Path delivery onto materials is not this station's job — post-admission owns it.
|
|
333
335
|
*/
|
|
334
336
|
export async function runCountersignCourtDiaristStation(
|
|
335
337
|
admitted: AdmittedCountersignInvocation,
|
|
336
338
|
env: CountersignRunEnv,
|
|
337
339
|
io: CliIo,
|
|
338
|
-
|
|
340
|
+
afterTicketNumber?: number,
|
|
341
|
+
): Promise<{ readonly terminal: import("./terminal.ts").TerminalResult; readonly childRunId?: string } | undefined> {
|
|
339
342
|
if (env.runCourtDiaristStation !== undefined) {
|
|
340
343
|
await env.runCourtDiaristStation(admitted);
|
|
341
344
|
return;
|
|
@@ -362,7 +365,8 @@ export async function runCountersignCourtDiaristStation(
|
|
|
362
365
|
refreshTickets = [admitted.ticketNumber];
|
|
363
366
|
}
|
|
364
367
|
|
|
365
|
-
|
|
368
|
+
const completedIndex = afterTicketNumber === undefined ? -1 : refreshTickets.indexOf(afterTicketNumber);
|
|
369
|
+
for (const ticketNumber of refreshTickets.slice(completedIndex + 1)) {
|
|
366
370
|
const outcome = await invokeCourtDiarist(
|
|
367
371
|
{
|
|
368
372
|
instruction: `整理 #${ticketNumber} 的本案依据。`,
|
|
@@ -376,13 +380,16 @@ export async function runCountersignCourtDiaristStation(
|
|
|
376
380
|
io,
|
|
377
381
|
);
|
|
378
382
|
|
|
379
|
-
if (outcome.identity.kind === "escalate") {
|
|
380
|
-
throw new StationChildExhaustedError(outcome.identity.diagnostic);
|
|
381
|
-
}
|
|
382
383
|
if (outcome.failedWithoutEscalate !== undefined) {
|
|
383
384
|
throw new StationChildExhaustedError(
|
|
384
385
|
outcome.failedWithoutEscalate.diagnostic,
|
|
385
386
|
);
|
|
386
387
|
}
|
|
388
|
+
if (outcome.identity.kind === "escalate" && outcome.terminal !== undefined) {
|
|
389
|
+
return {
|
|
390
|
+
terminal: outcome.terminal,
|
|
391
|
+
...(outcome.admitted === undefined ? {} : { childRunId: outcome.admitted.runId }),
|
|
392
|
+
};
|
|
393
|
+
}
|
|
387
394
|
}
|
|
388
395
|
}
|