@akagilnc/pi-workflow-roles 0.1.5368 → 0.1.5382
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 +1192 -1195
- package/dist/activation-ledger-git.js +2 -2
- package/dist/activation-ledger-topology.js +1 -7
- package/dist/analyst-entry.js +4 -8
- package/dist/analyst-gate-cycles-read.js +3 -11
- package/dist/analyst-index.js +3 -9
- package/dist/analyst-ledger.js +1 -11
- package/dist/analyst-metric-families/acceptance-success-rework.js +1 -3
- package/dist/analyst-metric-families/round-timeline.js +1 -3
- package/dist/analyst-page.js +2 -2
- package/dist/archivist-record-topology.js +2 -2
- package/dist/audit-escalation.js +2 -1
- package/dist/auditor-soul.js +2 -1
- package/dist/collector-config.js +6 -8
- package/dist/collector-tool-schemas.js +18 -0
- package/dist/compliance-transport.js +2 -1
- package/dist/countersign-contracts.js +2 -1
- package/dist/diarist-contracts.js +29 -2
- package/dist/doctor-contracts.js +1 -3
- package/dist/doctor-evidence.js +7 -8
- package/dist/dossier-resolution.js +1 -3
- package/dist/engine-detour-usage.js +1 -3
- package/dist/filed-submission.js +28 -0
- package/dist/gatekeeper-role.js +8 -19
- package/dist/gleaner-left-contracts.js +18 -1
- package/dist/headless-host/description.js +14 -17
- package/dist/headless-host/production-host.js +1210 -1215
- package/dist/host-session-record.js +3 -2
- package/dist/inspector-contracts.js +2 -1
- package/dist/judge-role.js +8 -16
- package/dist/ledger-session-read.js +1 -3
- package/dist/merger-contracts.js +9 -9
- package/dist/migrate-book-topology.js +610 -321
- package/dist/navigator-attendance.js +9 -11
- package/dist/navigator-invocation-identity.js +3 -2
- package/dist/navigator-public-session.js +3 -5
- package/dist/navigator-session-contracts.js +8 -10
- package/dist/navigator-work-base.js +5 -8
- package/dist/notary-contracts.js +3 -5
- package/dist/package-contracts/auditor-output.js +1 -3
- package/dist/package-contracts/fixer-packet.js +3 -6
- package/dist/package-contracts/gatekeeper-output.js +1 -3
- package/dist/package-contracts/navigator-output.js +8 -8
- package/dist/package-contracts/reviewer-output.js +16 -0
- package/dist/package-contracts/terminating-infrastructure.js +5 -9
- package/dist/package-contracts/terminating-tools.js +4 -3
- package/dist/package-contracts/worker-output.js +18 -2
- package/dist/public-cli/analyst-run.js +3 -2
- package/dist/public-cli/auto-resume.js +3 -8
- package/dist/public-cli/cli.js +9 -8
- package/dist/public-cli/config.js +8 -11
- package/dist/public-cli/countersign-run.js +1 -3
- package/dist/public-cli/host-providers.js +7 -14
- package/dist/public-cli/instruction-seat-run.js +12 -14
- package/dist/public-cli/invocation.js +9 -8
- package/dist/public-cli/main.js +1820 -1599
- package/dist/public-cli/post-admission.js +4 -3
- package/dist/public-cli/run-lifecycle.js +14 -26
- package/dist/public-cli/settlement.js +10 -26
- package/dist/public-role-summons.js +3 -2
- package/dist/receipt-delivery-policy.js +1 -3
- package/dist/role-run-placement.js +3 -5
- package/dist/role-run-relocation.js +12 -19
- package/dist/role-submission-declarations.js +131 -0
- package/dist/run-terminal-artifacts.js +1 -11
- package/dist/run-ticket-number.js +2 -4
- package/dist/secretariat-contracts.js +23 -1
- package/dist/session-assistant-usage.js +2 -1
- package/dist/session-dialogue.js +1 -14
- package/dist/sitian-reader.js +2 -4
- package/dist/submission-correctable-error.js +2 -1
- package/dist/submission-errors.js +2 -1
- package/dist/submission-gate.js +6 -8
- package/dist/submission-ledger.js +4 -5
- package/dist/ticket-provenance-contracts.js +1 -3
- package/dist/ticket-provenance.js +2 -1
- package/dist/typed-provider-http.js +4 -7
- package/dist/unknown-value.js +28 -0
- package/dist/user-dialogue-stdin.js +2 -1
- package/package.json +1 -1
- package/src/acp-host/role-turn-host.ts +4 -2
- package/src/activation-ledger-git.ts +3 -2
- package/src/activation-ledger-topology.ts +4 -12
- package/src/analyst-entry.ts +3 -11
- package/src/analyst-gate-cycles-read.ts +3 -15
- package/src/analyst-index.ts +3 -13
- package/src/analyst-ledger.ts +2 -16
- package/src/analyst-metric-families/acceptance-success-rework.ts +2 -4
- package/src/analyst-metric-families/round-timeline.ts +2 -4
- package/src/analyst-page.ts +2 -2
- package/src/archivist-record-topology.ts +2 -2
- package/src/audit-escalation.ts +2 -1
- package/src/auditor-role.ts +2 -8
- package/src/auditor-soul.ts +3 -1
- package/src/book-topology-migration-placement.ts +5 -16
- package/src/book-topology-migrators-t11.ts +16 -15
- package/src/book-topology-mixed-volume-migrators.ts +3 -6
- package/src/book-topology-record-class-migrators.ts +7 -10
- package/src/book-topology-runs-migrator.ts +4 -3
- package/src/collector-config.ts +7 -9
- package/src/collector-role.ts +5 -28
- package/src/compliance-transport.ts +2 -1
- package/src/countersign-contracts.ts +2 -1
- package/src/countersign-role.ts +2 -7
- package/src/diarist-contracts.ts +40 -2
- package/src/diarist-role.ts +4 -44
- package/src/doctor-contracts.ts +3 -1
- package/src/doctor-evidence.ts +8 -7
- package/src/doctor-role.ts +20 -13
- package/src/dossier-resolution.ts +2 -4
- package/src/engine-detour-tool.ts +0 -2
- package/src/engine-detour-usage.ts +2 -4
- package/src/external-host-turn-loop.ts +3 -1
- package/src/factory-board.ts +1 -8
- package/src/filed-submission.ts +44 -0
- package/src/gatekeeper-role.ts +8 -24
- package/src/gleaner-left-contracts.ts +29 -2
- package/src/gleaner-left-role.ts +4 -32
- package/src/headless-host/description.ts +15 -18
- package/src/headless-host/role-turn-host.ts +10 -9
- package/src/host-session-record.ts +4 -2
- package/src/inspector-contracts.ts +2 -1
- package/src/inspector-role.ts +2 -7
- package/src/judge-role.ts +12 -24
- package/src/ledger-session-read.ts +2 -5
- package/src/merger-contracts.ts +10 -9
- package/src/merger-role.ts +5 -8
- package/src/navigator-attendance.ts +10 -12
- package/src/navigator-invocation-identity.ts +3 -2
- package/src/navigator-public-session.ts +4 -6
- package/src/navigator-role.ts +2 -8
- package/src/navigator-session-contracts.ts +8 -11
- package/src/navigator-work-base.ts +5 -8
- package/src/navigator-work-context.ts +2 -1
- package/src/notary-contracts.ts +4 -6
- package/src/notary-role.ts +5 -20
- package/src/oauth-keepalive.ts +5 -18
- package/src/package-contracts/auditor-output.ts +2 -4
- package/src/package-contracts/fixer-packet.ts +4 -6
- package/src/package-contracts/gatekeeper-output.ts +2 -4
- package/src/package-contracts/judge-output.ts +0 -1
- package/src/package-contracts/navigator-output.ts +8 -8
- package/src/package-contracts/reviewer-output.ts +25 -0
- package/src/package-contracts/terminating-infrastructure.ts +6 -20
- package/src/package-contracts/terminating-tools.ts +8 -12
- package/src/package-contracts/worker-output.ts +43 -5
- package/src/pi/adapter.ts +0 -1
- package/src/pi/role-turn-host.ts +0 -1
- package/src/public-cli/analyst-run.ts +4 -2
- package/src/public-cli/auto-resume.ts +4 -11
- package/src/public-cli/cli.ts +10 -10
- package/src/public-cli/config.ts +8 -27
- package/src/public-cli/countersign-run.ts +2 -4
- package/src/public-cli/host-providers.ts +10 -27
- package/src/public-cli/instruction-seat-run.ts +14 -15
- package/src/public-cli/invocation.ts +11 -10
- package/src/public-cli/post-admission.ts +5 -3
- package/src/public-cli/run-lifecycle.ts +20 -41
- package/src/public-cli/settlement.ts +11 -33
- package/src/public-role-summons.ts +4 -3
- package/src/receipt-delivery-policy.ts +1 -4
- package/src/reviewer-role.ts +7 -36
- package/src/role-envelope.ts +5 -3
- package/src/role-run-placement.ts +4 -10
- package/src/role-run-relocation.ts +13 -23
- package/src/role-runtime.ts +16 -50
- package/src/role-submission-declarations.ts +143 -0
- package/src/run-terminal-artifacts.ts +2 -16
- package/src/run-ticket-number.ts +4 -10
- package/src/secretariat-contracts.ts +35 -0
- package/src/secretariat-role.ts +4 -40
- package/src/session-assistant-usage.ts +3 -1
- package/src/session-dialogue.ts +1 -4
- package/src/session-identity.ts +0 -1
- package/src/sitian-reader.ts +2 -4
- package/src/submission-correctable-error.ts +3 -1
- package/src/submission-errors.ts +2 -1
- package/src/submission-gate.ts +10 -9
- package/src/submission-ledger.ts +5 -6
- package/src/ticket-provenance-contracts.ts +1 -4
- package/src/ticket-provenance.ts +3 -1
- package/src/ticket-snapshot.ts +2 -4
- package/src/ticket-trajectory.ts +1 -8
- package/src/typed-provider-http.ts +5 -15
- package/src/unknown-value.ts +34 -0
- package/src/user-dialogue-stdin.ts +3 -1
- package/src/worker-role.ts +63 -83
- package/src/worker-submission-gates.ts +8 -7
package/src/reviewer-role.ts
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import type { RoleHost, HostContext
|
|
2
|
-
import { Type } from "typebox";
|
|
3
|
-
import { openToolObject } from "./open-tool-schema.ts";
|
|
4
|
-
import { withTerminatingOutputDeclarations } from "./package-contracts/terminating-infrastructure.ts";
|
|
1
|
+
import type { RoleHost, HostContext } from "./host-contracts.ts";
|
|
5
2
|
|
|
6
|
-
import {
|
|
3
|
+
import { registerFiledSubmissionTool } from "./filed-submission.ts";
|
|
4
|
+
import { roleSubmissionDeclaration } from "./role-submission-declarations.ts";
|
|
7
5
|
|
|
8
|
-
export { REVIEWER_OUTPUT_TOOL_NAME };
|
|
9
|
-
export type { ReviewerIntent };
|
|
6
|
+
export { REVIEWER_OUTPUT_TOOL_NAME, reviewerOutputSchema, type ReviewerIntent } from "./package-contracts/reviewer-output.ts";
|
|
10
7
|
|
|
11
8
|
/** Frozen admitted inputs the behavior layer may consume — no flag surface. */
|
|
12
9
|
export type ReviewerAdmittedInputs = Readonly<{
|
|
@@ -17,31 +14,11 @@ export type ReviewerAdmittedInputs = Readonly<{
|
|
|
17
14
|
ticketNumber?: number;
|
|
18
15
|
}>;
|
|
19
16
|
|
|
20
|
-
const REVIEWER_AMENDMENTS_DESCRIPTION =
|
|
21
|
-
"已运行 lens 的 amendments 承载 candidates、逐条处置与 verdict 的完整报告(非仅 verdict 行);显式单轴时另一轴可省略(completeness / correctness)。hard-stop/usage error 为 refused 时,已产出报告仍照录对应 lens 字段。" as const;
|
|
22
|
-
// #1134: `status` alone is the trajectory field (#917 §6 two normal lens verdicts →
|
|
23
|
-
// completed; hard-stop / usage error → refused); its words ride the description.
|
|
24
|
-
// amendments/diagnostic are LLM/human-read narrative content returned as
|
|
25
|
-
// submitted — declaration keeps name + semantic description only, no nested
|
|
26
|
-
// object shape, no string type, no required constraint.
|
|
27
|
-
const REVIEWER_STATUS_DESCRIPTION =
|
|
28
|
-
"completed | refused。两种正常 lens verdict(completeness / correctness)均 completed;hard-stop 与 usage error 为 refused(已产出报告仍照录进所选 lens amendments)。" as const;
|
|
29
|
-
const reviewerOutputObject = Type.Object({
|
|
30
|
-
status: Type.Unknown({ description: REVIEWER_STATUS_DESCRIPTION }),
|
|
31
|
-
amendments: Type.Unknown({ description: REVIEWER_AMENDMENTS_DESCRIPTION }),
|
|
32
|
-
diagnostic: Type.Unknown({
|
|
33
|
-
description: "拒绝诊断说明;hard-stop/usage error 原因进此字段,已产出报告另照录 amendments",
|
|
34
|
-
}),
|
|
35
|
-
});
|
|
36
|
-
export const reviewerOutputSchema = withTerminatingOutputDeclarations(
|
|
37
|
-
openToolObject(reviewerOutputObject),
|
|
38
|
-
);
|
|
39
17
|
export type ReviewerRoleDependencies = {
|
|
40
18
|
loadSoul(): Promise<string>;
|
|
41
19
|
};
|
|
42
20
|
export type ReviewerRoleHostActions = { failInfrastructure(error: unknown, ctx: HostContext, toolCallId?: string): never };
|
|
43
21
|
|
|
44
|
-
|
|
45
22
|
export type ReviewerActivation = Readonly<{
|
|
46
23
|
fixedBaseRevision: string;
|
|
47
24
|
soul: string;
|
|
@@ -71,15 +48,9 @@ export function createReviewerRoleRuntime(
|
|
|
71
48
|
|
|
72
49
|
if (!registered) {
|
|
73
50
|
registered = true;
|
|
74
|
-
pi
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
return {
|
|
78
|
-
content: [],
|
|
79
|
-
details: parameters,
|
|
80
|
-
terminate: true as const,
|
|
81
|
-
};
|
|
82
|
-
} });
|
|
51
|
+
registerFiledSubmissionTool(pi, roleSubmissionDeclaration("reviewer"), {
|
|
52
|
+
readyError: () => (soul === undefined || soul.length === 0 ? "御史台输入未装载" : undefined),
|
|
53
|
+
});
|
|
83
54
|
}
|
|
84
55
|
const activatedSoul = soul;
|
|
85
56
|
const activatedBase = fixedBaseRevision;
|
package/src/role-envelope.ts
CHANGED
|
@@ -35,6 +35,8 @@ import {
|
|
|
35
35
|
} from "./navigator-invocation-identity.ts";
|
|
36
36
|
import { serializeThrownValue } from "./serialize-thrown-value.ts";
|
|
37
37
|
|
|
38
|
+
import { isRecord, errorText } from "./unknown-value.ts";
|
|
39
|
+
|
|
38
40
|
export { projectActivationFlags };
|
|
39
41
|
|
|
40
42
|
type Handler = HostEventRegistration[1];
|
|
@@ -158,7 +160,7 @@ export async function prepareRoleEnvelope(options: {
|
|
|
158
160
|
try {
|
|
159
161
|
await appendFile(sessionFile, line, "utf8");
|
|
160
162
|
} catch (error) {
|
|
161
|
-
const diagnostic =
|
|
163
|
+
const diagnostic = errorText(error);
|
|
162
164
|
armDurableWriteFailure?.(customType, diagnostic);
|
|
163
165
|
}
|
|
164
166
|
});
|
|
@@ -291,7 +293,7 @@ export async function prepareRoleEnvelope(options: {
|
|
|
291
293
|
content: ContentPart[],
|
|
292
294
|
): void {
|
|
293
295
|
if (infrastructureRoundFailure !== undefined) return;
|
|
294
|
-
const record =
|
|
296
|
+
const record = isRecord(details)
|
|
295
297
|
? details as Record<string, unknown>
|
|
296
298
|
: undefined;
|
|
297
299
|
const isInfra = record !== undefined && (
|
|
@@ -336,7 +338,7 @@ export async function prepareRoleEnvelope(options: {
|
|
|
336
338
|
content: ContentPart[];
|
|
337
339
|
details: Record<string, unknown>;
|
|
338
340
|
} {
|
|
339
|
-
const diagnostic =
|
|
341
|
+
const diagnostic = errorText(error);
|
|
340
342
|
const content: ContentPart[] = [{ type: "text", text: diagnostic }];
|
|
341
343
|
const errorCode = typeof (error as unknown as { code?: unknown })?.code === "string"
|
|
342
344
|
? (error as unknown as { code: string }).code
|
|
@@ -7,6 +7,8 @@ import {
|
|
|
7
7
|
} from "./activation-ledger-topology.ts";
|
|
8
8
|
import { requireSafePositiveTicketNumber } from "./run-ticket-number.ts";
|
|
9
9
|
|
|
10
|
+
import { isEnoent } from "./unknown-value.ts";
|
|
11
|
+
|
|
10
12
|
export type RoleRunSubject =
|
|
11
13
|
| { readonly ticketNumber: number }
|
|
12
14
|
| { readonly unbound: true };
|
|
@@ -19,14 +21,6 @@ export type RoleRunPlacement = {
|
|
|
19
21
|
readonly attachmentsDirectory: string;
|
|
20
22
|
};
|
|
21
23
|
|
|
22
|
-
function isMissingPathError(error: unknown): boolean {
|
|
23
|
-
return (
|
|
24
|
-
error instanceof Error &&
|
|
25
|
-
"code" in error &&
|
|
26
|
-
(error as NodeJS.ErrnoException).code === "ENOENT"
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
24
|
/**
|
|
31
25
|
* Sole book-level run directory walk: flat legacy `runs/` plus each
|
|
32
26
|
* `subject/runs/` child (ticket / unbound). One authority for read-side
|
|
@@ -42,7 +36,7 @@ export async function listBookRunDirectories(bookDir: string): Promise<string[]>
|
|
|
42
36
|
try {
|
|
43
37
|
entries = await readdir(runsDir, { withFileTypes: true });
|
|
44
38
|
} catch (error) {
|
|
45
|
-
if (
|
|
39
|
+
if (isEnoent(error)) return;
|
|
46
40
|
throw error;
|
|
47
41
|
}
|
|
48
42
|
for (const entry of entries) {
|
|
@@ -60,7 +54,7 @@ export async function listBookRunDirectories(bookDir: string): Promise<string[]>
|
|
|
60
54
|
try {
|
|
61
55
|
subjects = await readdir(bookDir, { withFileTypes: true });
|
|
62
56
|
} catch (error) {
|
|
63
|
-
if (
|
|
57
|
+
if (isEnoent(error)) return out.sort();
|
|
64
58
|
throw error;
|
|
65
59
|
}
|
|
66
60
|
for (const subject of subjects) {
|
|
@@ -12,6 +12,8 @@ import { join, sep } from "node:path";
|
|
|
12
12
|
|
|
13
13
|
import { AUDITOR_PARENT_ATTEMPT_BINDING_ENTRY_TYPE } from "./compliance-transport.ts";
|
|
14
14
|
|
|
15
|
+
import { isRecord, isEnoent } from "./unknown-value.ts";
|
|
16
|
+
|
|
15
17
|
const ADMITTED_PAGE_FIELDS = [
|
|
16
18
|
"runDirectory",
|
|
17
19
|
"admittedRequestPath",
|
|
@@ -50,14 +52,6 @@ export type RunDirectoryPathRewrite = {
|
|
|
50
52
|
readonly newRunDirectory: string;
|
|
51
53
|
};
|
|
52
54
|
|
|
53
|
-
function isEnoent(error: unknown): boolean {
|
|
54
|
-
return (
|
|
55
|
-
error instanceof Error &&
|
|
56
|
-
"code" in error &&
|
|
57
|
-
(error as NodeJS.ErrnoException).code === "ENOENT"
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
55
|
/** Rewrite one path value that points at or under oldRunDirectory. */
|
|
62
56
|
export function rewriteRunDirectoryPathValue(
|
|
63
57
|
value: unknown,
|
|
@@ -158,16 +152,12 @@ function collectRewrites(input: {
|
|
|
158
152
|
return out;
|
|
159
153
|
}
|
|
160
154
|
|
|
161
|
-
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
162
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
155
|
/** Typed notary/source-run locator: only runDirectory is a path. */
|
|
166
156
|
function rewriteSourceRunLocator(
|
|
167
157
|
value: unknown,
|
|
168
158
|
rewrites: readonly RunDirectoryPathRewrite[],
|
|
169
159
|
): void {
|
|
170
|
-
if (!
|
|
160
|
+
if (!isRecord(value)) return;
|
|
171
161
|
rewriteRunDirectoryPathFieldsAgainstRewrites(
|
|
172
162
|
value,
|
|
173
163
|
SOURCE_RUN_LOCATOR_FIELDS,
|
|
@@ -180,7 +170,7 @@ function rewriteSummonsMaterials(
|
|
|
180
170
|
value: unknown,
|
|
181
171
|
rewrites: readonly RunDirectoryPathRewrite[],
|
|
182
172
|
): void {
|
|
183
|
-
if (!
|
|
173
|
+
if (!isRecord(value)) return;
|
|
184
174
|
rewriteRunDirectoryPathFieldsAgainstRewrites(
|
|
185
175
|
value,
|
|
186
176
|
SUMMONS_PATH_FIELDS,
|
|
@@ -204,12 +194,12 @@ export function rewriteAdmittedRoleRunPage(
|
|
|
204
194
|
rewriteSourceRunLocator(page.sourceRun, rewrites);
|
|
205
195
|
if (Array.isArray(page.attachments)) {
|
|
206
196
|
for (const attachment of page.attachments) {
|
|
207
|
-
if (
|
|
197
|
+
if (isRecord(attachment)) {
|
|
208
198
|
rewriteRunDirectoryPathFieldsAgainstRewrites(attachment, ["frozenPath"], rewrites);
|
|
209
199
|
}
|
|
210
200
|
}
|
|
211
201
|
}
|
|
212
|
-
if (
|
|
202
|
+
if (isRecord(page.principal)) {
|
|
213
203
|
rewriteRunDirectoryPathFieldsAgainstRewrites(
|
|
214
204
|
page.principal,
|
|
215
205
|
["sessionDirectory", "sessionFile"],
|
|
@@ -224,7 +214,7 @@ async function rewriteOfficerPointerFile(
|
|
|
224
214
|
): Promise<void> {
|
|
225
215
|
if (!existsSync(path)) return;
|
|
226
216
|
const page = JSON.parse(await readFile(path, "utf8")) as unknown;
|
|
227
|
-
if (!
|
|
217
|
+
if (!isRecord(page)) return;
|
|
228
218
|
// Only the typed direct-officer pointer shape — never arbitrary .pointer.json.
|
|
229
219
|
if (page.kind !== "direct-officer-run-pointer") return;
|
|
230
220
|
const before = JSON.stringify(page);
|
|
@@ -267,7 +257,7 @@ async function rewriteSitianRecordsJsonl(
|
|
|
267
257
|
out.push(line);
|
|
268
258
|
continue;
|
|
269
259
|
}
|
|
270
|
-
if (!
|
|
260
|
+
if (!isRecord(parsed)) {
|
|
271
261
|
out.push(line);
|
|
272
262
|
continue;
|
|
273
263
|
}
|
|
@@ -325,7 +315,7 @@ async function rewriteSessionTranscriptBindings(
|
|
|
325
315
|
out.push(line);
|
|
326
316
|
continue;
|
|
327
317
|
}
|
|
328
|
-
if (!
|
|
318
|
+
if (!isRecord(parsed)) {
|
|
329
319
|
out.push(line);
|
|
330
320
|
continue;
|
|
331
321
|
}
|
|
@@ -341,8 +331,8 @@ async function rewriteSessionTranscriptBindings(
|
|
|
341
331
|
} else if (
|
|
342
332
|
parsed.type === "custom" &&
|
|
343
333
|
parsed.customType === AUDITOR_PARENT_ATTEMPT_BINDING_ENTRY_TYPE &&
|
|
344
|
-
|
|
345
|
-
|
|
334
|
+
isRecord(parsed.data) &&
|
|
335
|
+
isRecord(parsed.data.parent)
|
|
346
336
|
) {
|
|
347
337
|
const parent = parsed.data.parent;
|
|
348
338
|
const before = parent.sessionFile;
|
|
@@ -454,7 +444,7 @@ export async function rewriteRoleRunDurablePages(input: {
|
|
|
454
444
|
RUN_STATE_PAGE_FIELDS,
|
|
455
445
|
rewrites,
|
|
456
446
|
);
|
|
457
|
-
if (
|
|
447
|
+
if (isRecord(page.principal)) {
|
|
458
448
|
rewriteRunDirectoryPathFieldsAgainstRewrites(
|
|
459
449
|
page.principal,
|
|
460
450
|
["sessionDirectory", "sessionFile"],
|
|
@@ -462,7 +452,7 @@ export async function rewriteRoleRunDurablePages(input: {
|
|
|
462
452
|
);
|
|
463
453
|
}
|
|
464
454
|
// Open court summons: source-run locators + frozen attachment path pointers.
|
|
465
|
-
if (
|
|
455
|
+
if (isRecord(page.currentCourt)) {
|
|
466
456
|
rewriteSummonsMaterials(page.currentCourt.summons, rewrites);
|
|
467
457
|
}
|
|
468
458
|
if (JSON.stringify(page) !== before) {
|
package/src/role-runtime.ts
CHANGED
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
|
|
7
7
|
runDirectoryFromHostContext,
|
|
8
8
|
type HostContext,
|
|
9
|
-
type HostToolResult,
|
|
10
9
|
type RoleEnvelopeHost,
|
|
11
10
|
type RoleHost,
|
|
12
11
|
} from "./host-contracts.ts";
|
|
@@ -14,6 +13,8 @@ import {
|
|
|
14
13
|
import { Value } from "typebox/value";
|
|
15
14
|
import { sitianReport } from "./sitian-facade.ts";
|
|
16
15
|
import { createSubmissionLedgerHost, sealAcceptedSubmission } from "./submission-ledger.ts";
|
|
16
|
+
import { registerFiledSubmissionTool, type FiledSubmissionBeforeAccept } from "./filed-submission.ts";
|
|
17
|
+
import type { RoleSubmissionDeclaration } from "./role-submission-declarations.ts";
|
|
17
18
|
|
|
18
19
|
import { activationTraceRecordSchema, namedActivationCause, type ActivationTraceRecord, type ActivationTraceWriter } from "./activation-trace.ts";
|
|
19
20
|
import { homeFromRunDirectory } from "./activation-ledger-topology.ts";
|
|
@@ -188,7 +189,7 @@ function decodeReviewerAdmittedInputs(getFlag: (name: string) => unknown): Revie
|
|
|
188
189
|
parsed = JSON.parse(rawAuthorityRefs);
|
|
189
190
|
} catch (error) {
|
|
190
191
|
throw new Error(
|
|
191
|
-
`Reviewer authority refs transport error: JSON decode failed: ${
|
|
192
|
+
`Reviewer authority refs transport error: JSON decode failed: ${errorText(error)}`,
|
|
192
193
|
);
|
|
193
194
|
}
|
|
194
195
|
if (!Array.isArray(parsed) || parsed.some((ref) => typeof ref !== "string")) {
|
|
@@ -297,6 +298,8 @@ export type { GatekeeperResult, GatekeeperSubject, SubmissionGateNonPassResult,
|
|
|
297
298
|
import { ParentQueueReaskError, unreadableDiscriminatorNotice } from "./submission-errors.ts";
|
|
298
299
|
import { REVIEW_QUEUE_STATUSES } from "./review-submission.ts";
|
|
299
300
|
|
|
301
|
+
import { isRecord, errorText, isEnoent } from "./unknown-value.ts";
|
|
302
|
+
|
|
300
303
|
export {
|
|
301
304
|
DOCTOR_EVIDENCE_TOOL_NAME,
|
|
302
305
|
DOCTOR_OUTPUT_TOOL_NAME,
|
|
@@ -507,7 +510,7 @@ export function publicNavigatorSettlement(role: string, phase: NavigatorPhase, e
|
|
|
507
510
|
return { kind: "role_infrastructure_failure", role, phase };
|
|
508
511
|
}
|
|
509
512
|
// accepted/human — project role/phase status; classifier already rejected infra/contradiction.
|
|
510
|
-
const details =
|
|
513
|
+
const details = isRecord(event.details)
|
|
511
514
|
? event.details as Record<string, unknown>
|
|
512
515
|
: {};
|
|
513
516
|
const status = typeof details.status === "string"
|
|
@@ -545,18 +548,6 @@ export async function projectClosedSubmissionLifecycle(
|
|
|
545
548
|
}
|
|
546
549
|
}
|
|
547
550
|
|
|
548
|
-
/**
|
|
549
|
-
* Optional pre-accept hook on the shared filed-officer envelope (ADR 0075).
|
|
550
|
-
* May return a details projection (envelope-owned machine facts recorded next to
|
|
551
|
-
* the submitted parameters); undefined keeps the parameters as submitted.
|
|
552
|
-
*/
|
|
553
|
-
type FiledOfficerBeforeAccept = (input: {
|
|
554
|
-
readonly toolCallId: string;
|
|
555
|
-
readonly parameters: unknown;
|
|
556
|
-
readonly signal: AbortSignal | undefined;
|
|
557
|
-
readonly ctx: HostContext;
|
|
558
|
-
}) => Promise<unknown>;
|
|
559
|
-
|
|
560
551
|
/**
|
|
561
552
|
* Shared registration envelope for filed officers (ADR 0018 / #572):
|
|
562
553
|
* activate, tool register, before_agent_start prompt, inventory check.
|
|
@@ -567,9 +558,9 @@ function createFiledOfficerRuntime(
|
|
|
567
558
|
roleHost: RoleHost,
|
|
568
559
|
spec: {
|
|
569
560
|
role: PackagedRole;
|
|
570
|
-
tool:
|
|
561
|
+
tool: RoleSubmissionDeclaration;
|
|
571
562
|
soulTag: string;
|
|
572
|
-
beforeAccept?:
|
|
563
|
+
beforeAccept?: FiledSubmissionBeforeAccept;
|
|
573
564
|
},
|
|
574
565
|
dependencies: { loadSoul(): Promise<string> },
|
|
575
566
|
) {
|
|
@@ -582,26 +573,9 @@ function createFiledOfficerRuntime(
|
|
|
582
573
|
soul = loaded;
|
|
583
574
|
if (!registered) {
|
|
584
575
|
registered = true;
|
|
585
|
-
roleHost.
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
description: spec.tool.description,
|
|
589
|
-
promptSnippet: spec.tool.promptSnippet,
|
|
590
|
-
parameters: spec.tool.parameters as never,
|
|
591
|
-
async execute(toolCallId, parameters, signal, _onUpdate, ctx): Promise<HostToolResult<unknown>> {
|
|
592
|
-
if (soul === undefined) throw new Error(`${spec.role} 职分未装载`);
|
|
593
|
-
const projected =
|
|
594
|
-
spec.beforeAccept === undefined
|
|
595
|
-
? undefined
|
|
596
|
-
: await spec.beforeAccept({ toolCallId, parameters, signal, ctx });
|
|
597
|
-
// Accept-as-is + terminate only. Shape is not an admission gate
|
|
598
|
-
// (第 0 条 / ADR 0055); sole-final barrier is ledger-owned (#575).
|
|
599
|
-
return {
|
|
600
|
-
content: [],
|
|
601
|
-
details: projected === undefined ? parameters : projected,
|
|
602
|
-
terminate: true as const,
|
|
603
|
-
};
|
|
604
|
-
},
|
|
576
|
+
registerFiledSubmissionTool(roleHost, spec.tool, {
|
|
577
|
+
readyError: () => (soul === undefined ? `${spec.role} 职分未装载` : undefined),
|
|
578
|
+
...(spec.beforeAccept === undefined ? {} : { beforeAccept: spec.beforeAccept }),
|
|
605
579
|
});
|
|
606
580
|
roleHost.on("before_agent_start", (event) => {
|
|
607
581
|
if (soul === undefined) throw new Error(`${spec.role} 职分未装载`);
|
|
@@ -710,7 +684,7 @@ export function createNavigatorRoleRuntime(
|
|
|
710
684
|
dependencies.recordRoutePlaybookReadFailure?.(undefined);
|
|
711
685
|
if (content.trim() !== "") parts.push(content);
|
|
712
686
|
} catch (error) {
|
|
713
|
-
const message =
|
|
687
|
+
const message = errorText(error);
|
|
714
688
|
if (message.trim() !== "") {
|
|
715
689
|
dependencies.recordRoutePlaybookReadFailure?.(message);
|
|
716
690
|
parts.push(message);
|
|
@@ -854,7 +828,7 @@ export function createDiaristRoleRuntime(
|
|
|
854
828
|
soulTag: "diarist",
|
|
855
829
|
beforeAccept: async ({ parameters, ctx }) => {
|
|
856
830
|
const submitted =
|
|
857
|
-
|
|
831
|
+
isRecord(parameters)
|
|
858
832
|
? (parameters as Record<string, unknown>)
|
|
859
833
|
: undefined;
|
|
860
834
|
// Routing belongs to the public seam after this tool call has returned.
|
|
@@ -1073,7 +1047,7 @@ export function createRoleRuntimeExtension(
|
|
|
1073
1047
|
): void => {
|
|
1074
1048
|
if (attendance === undefined) return;
|
|
1075
1049
|
const recordDisposeFailure = (error: unknown): void => {
|
|
1076
|
-
const diagnostic =
|
|
1050
|
+
const diagnostic = errorText(error);
|
|
1077
1051
|
try {
|
|
1078
1052
|
sitianReport({
|
|
1079
1053
|
level: "event",
|
|
@@ -1087,7 +1061,7 @@ export function createRoleRuntimeExtension(
|
|
|
1087
1061
|
try {
|
|
1088
1062
|
envelopeHost.appendEntry?.("ak-navigator-dispose-failure", {
|
|
1089
1063
|
diagnostic,
|
|
1090
|
-
recordFailure:
|
|
1064
|
+
recordFailure: errorText(recordError),
|
|
1091
1065
|
});
|
|
1092
1066
|
} catch {
|
|
1093
1067
|
// Failure already diagnosed; recording must not create unhandled rejection (#959).
|
|
@@ -1655,15 +1629,7 @@ export function createRoleRuntimeExtension(
|
|
|
1655
1629
|
try {
|
|
1656
1630
|
await recordTypedProviderHttpStatus(runDir, { httpStatus: status, provider });
|
|
1657
1631
|
} catch (error) {
|
|
1658
|
-
if (
|
|
1659
|
-
status >= 200 &&
|
|
1660
|
-
status < 300 &&
|
|
1661
|
-
error instanceof Error &&
|
|
1662
|
-
"code" in error &&
|
|
1663
|
-
(error as { code?: unknown }).code === "ENOENT"
|
|
1664
|
-
) {
|
|
1665
|
-
return;
|
|
1666
|
-
}
|
|
1632
|
+
if (status >= 200 && status < 300 && isEnoent(error)) return;
|
|
1667
1633
|
failInfrastructure(error, ctx);
|
|
1668
1634
|
}
|
|
1669
1635
|
};
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Field guidance for each public seat's submission tool (#1031).
|
|
3
|
+
* The tool name is the role registry's outputTool. This module does not restate it.
|
|
4
|
+
* Review seats keep the #1028 schema. Other seats keep their own field guidance.
|
|
5
|
+
* Execute lives in filed-submission.ts.
|
|
6
|
+
*/
|
|
7
|
+
import { packagedRoleOutputTool, type PackagedRole } from "./packaged-role-registry.ts";
|
|
8
|
+
import { reviewSubmissionSchema } from "./review-submission.ts";
|
|
9
|
+
import { collectorOutputArgsSchema } from "./collector-tool-schemas.ts";
|
|
10
|
+
import { diaristOutputSchema } from "./diarist-contracts.ts";
|
|
11
|
+
import { doctorSubmissionSchema, DOCTOR_OUTPUT_TOOL_DESCRIPTION } from "./doctor-contracts.ts";
|
|
12
|
+
import { fixerOutputSchema } from "./package-contracts/fixer-output.ts";
|
|
13
|
+
import { gatekeeperOutputSchema } from "./package-contracts/gatekeeper-output.ts";
|
|
14
|
+
import { gleanerLeftOutputSchema } from "./gleaner-left-contracts.ts";
|
|
15
|
+
import { mergerOutputSchema } from "./merger-contracts.ts";
|
|
16
|
+
import { navigatorOutputSchema } from "./package-contracts/navigator-output.ts";
|
|
17
|
+
import { reviewerOutputSchema } from "./package-contracts/reviewer-output.ts";
|
|
18
|
+
import { secretariatVerdictSchema } from "./secretariat-contracts.ts";
|
|
19
|
+
import { coderOutputSchema } from "./package-contracts/worker-output.ts";
|
|
20
|
+
|
|
21
|
+
export type RoleSubmissionDeclaration = {
|
|
22
|
+
readonly role: PackagedRole;
|
|
23
|
+
readonly name: string;
|
|
24
|
+
readonly label: string;
|
|
25
|
+
readonly description: string;
|
|
26
|
+
readonly promptSnippet?: string;
|
|
27
|
+
readonly parameters: unknown;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
type SubmissionFace = Omit<RoleSubmissionDeclaration, "role" | "name">;
|
|
31
|
+
|
|
32
|
+
const SUBMISSION_FACE = {
|
|
33
|
+
judge: {
|
|
34
|
+
label: "大理寺输出",
|
|
35
|
+
description: "提交大理寺终局判词;交卷调用结束后,由公开调用接缝按判词状态执行适用审核。",
|
|
36
|
+
promptSnippet: "提交大理寺终局判词",
|
|
37
|
+
parameters: reviewSubmissionSchema,
|
|
38
|
+
},
|
|
39
|
+
fixer: {
|
|
40
|
+
label: "修内司输出",
|
|
41
|
+
description: "提交修内司终局回执。",
|
|
42
|
+
promptSnippet: "提交修内司终局回执",
|
|
43
|
+
parameters: fixerOutputSchema,
|
|
44
|
+
},
|
|
45
|
+
coder: {
|
|
46
|
+
label: "将作监输出",
|
|
47
|
+
description: "提交将作监终局回执。",
|
|
48
|
+
promptSnippet: "提交将作监终局回执",
|
|
49
|
+
parameters: coderOutputSchema,
|
|
50
|
+
},
|
|
51
|
+
reviewer: {
|
|
52
|
+
label: "御史台输出",
|
|
53
|
+
description: "提交御史台终局回执。",
|
|
54
|
+
promptSnippet: "提交御史台终局回执",
|
|
55
|
+
parameters: reviewerOutputSchema,
|
|
56
|
+
},
|
|
57
|
+
collector: {
|
|
58
|
+
label: "通进司输出",
|
|
59
|
+
description: "提交通进司回执。",
|
|
60
|
+
promptSnippet: "提交通进司回执",
|
|
61
|
+
parameters: collectorOutputArgsSchema,
|
|
62
|
+
},
|
|
63
|
+
doctor: {
|
|
64
|
+
label: "太医署输出",
|
|
65
|
+
description: DOCTOR_OUTPUT_TOOL_DESCRIPTION,
|
|
66
|
+
parameters: doctorSubmissionSchema,
|
|
67
|
+
},
|
|
68
|
+
merger: {
|
|
69
|
+
label: "合并输出",
|
|
70
|
+
description: "提交合并结果;输出分支为 completed 与 escalate。",
|
|
71
|
+
promptSnippet: "提交合并结果",
|
|
72
|
+
parameters: mergerOutputSchema,
|
|
73
|
+
},
|
|
74
|
+
notary: {
|
|
75
|
+
label: "符宝郎输出",
|
|
76
|
+
description: "提交引文保真与票面对齐的 converged/continue/escalate 决议。",
|
|
77
|
+
promptSnippet: "提交符宝郎决议",
|
|
78
|
+
parameters: reviewSubmissionSchema,
|
|
79
|
+
},
|
|
80
|
+
countersign: {
|
|
81
|
+
label: "给事中输出",
|
|
82
|
+
description: "给事中决议。",
|
|
83
|
+
promptSnippet: "给事中决议",
|
|
84
|
+
parameters: reviewSubmissionSchema,
|
|
85
|
+
},
|
|
86
|
+
secretariat: {
|
|
87
|
+
label: "中书省输出",
|
|
88
|
+
description: "中书省终局回执。",
|
|
89
|
+
promptSnippet: "中书省终局回执",
|
|
90
|
+
parameters: secretariatVerdictSchema,
|
|
91
|
+
},
|
|
92
|
+
"gleaner-left": {
|
|
93
|
+
label: "左拾遗输出",
|
|
94
|
+
description: "左拾遗弹章。",
|
|
95
|
+
promptSnippet: "左拾遗弹章",
|
|
96
|
+
parameters: gleanerLeftOutputSchema,
|
|
97
|
+
},
|
|
98
|
+
inspector: {
|
|
99
|
+
label: "台院输出",
|
|
100
|
+
description: "台院终局回执,状态为 converged、continue 或 escalate。",
|
|
101
|
+
promptSnippet: "台院终局回执",
|
|
102
|
+
parameters: reviewSubmissionSchema,
|
|
103
|
+
},
|
|
104
|
+
gatekeeper: {
|
|
105
|
+
label: "门下省决议",
|
|
106
|
+
description: "门下省终局决议。status 为 dispatch 或 pass。",
|
|
107
|
+
promptSnippet: "门下省决议",
|
|
108
|
+
parameters: gatekeeperOutputSchema,
|
|
109
|
+
},
|
|
110
|
+
navigator: {
|
|
111
|
+
label: "游奕使建议",
|
|
112
|
+
description: "游奕使终局回执:散文建议,原样呈现。",
|
|
113
|
+
promptSnippet: "游奕使建议",
|
|
114
|
+
parameters: navigatorOutputSchema,
|
|
115
|
+
},
|
|
116
|
+
auditor: {
|
|
117
|
+
label: "审刑院输出",
|
|
118
|
+
description: "审刑院终局回执,status 为 converged、continue 或 escalate。",
|
|
119
|
+
promptSnippet: "审刑院终局回执",
|
|
120
|
+
parameters: reviewSubmissionSchema,
|
|
121
|
+
},
|
|
122
|
+
diarist: {
|
|
123
|
+
label: "起居郎输出",
|
|
124
|
+
description: "起居郎交单票 sessions 或多票逐票 ticketSessions 边界;认不出本庭对象则 escalate。",
|
|
125
|
+
promptSnippet: "起居郎交边界",
|
|
126
|
+
parameters: diaristOutputSchema,
|
|
127
|
+
},
|
|
128
|
+
} as const satisfies Record<PackagedRole, SubmissionFace>;
|
|
129
|
+
|
|
130
|
+
/** Tool name comes from the registry record. Label and schema stay on this face. */
|
|
131
|
+
export function roleSubmissionDeclaration(role: PackagedRole): RoleSubmissionDeclaration {
|
|
132
|
+
const name = packagedRoleOutputTool(role);
|
|
133
|
+
if (name === undefined) throw new Error(`${role} output tool is not declared`);
|
|
134
|
+
const face = SUBMISSION_FACE[role];
|
|
135
|
+
return {
|
|
136
|
+
role,
|
|
137
|
+
name,
|
|
138
|
+
label: face.label,
|
|
139
|
+
description: face.description,
|
|
140
|
+
...("promptSnippet" in face ? { promptSnippet: face.promptSnippet } : {}),
|
|
141
|
+
parameters: face.parameters,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
@@ -11,6 +11,8 @@ import { basename, dirname, join } from "node:path";
|
|
|
11
11
|
|
|
12
12
|
import { roleRunArtifactsDirectory } from "./role-run-placement.ts";
|
|
13
13
|
|
|
14
|
+
import { isRecord, errorText, isMissingPathError } from "./unknown-value.ts";
|
|
15
|
+
|
|
14
16
|
export const RUN_TERMINAL_ARTIFACT_FILES = [
|
|
15
17
|
"report.json",
|
|
16
18
|
"error.json",
|
|
@@ -49,22 +51,6 @@ export type RunTerminalArtifactRead =
|
|
|
49
51
|
readonly reason: string;
|
|
50
52
|
};
|
|
51
53
|
|
|
52
|
-
function isMissingPathError(error: unknown): boolean {
|
|
53
|
-
return (
|
|
54
|
-
error instanceof Error
|
|
55
|
-
&& "code" in error
|
|
56
|
-
&& (error.code === "ENOENT" || error.code === "ENOTDIR")
|
|
57
|
-
);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function errorText(error: unknown): string {
|
|
61
|
-
return error instanceof Error ? error.message : String(error);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
65
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
54
|
/**
|
|
69
55
|
* Minimum producer-owned face shared by settlement terminal artifacts
|
|
70
56
|
* (report / error / audit-incomplete). Consumer-driven: enough to identify a
|
package/src/run-ticket-number.ts
CHANGED
|
@@ -8,18 +8,12 @@
|
|
|
8
8
|
import { readFile } from "node:fs/promises";
|
|
9
9
|
import { join } from "node:path";
|
|
10
10
|
|
|
11
|
+
import { isEnoent, isRecord } from "./unknown-value.ts";
|
|
12
|
+
|
|
11
13
|
/** Sole on-disk page for worktree-basename ticket derivation (#865). */
|
|
12
14
|
export const MIGRATION_TICKET_DERIVATION_PAGE =
|
|
13
15
|
"migration-ticket-derivation.json" as const;
|
|
14
16
|
|
|
15
|
-
function isEnoent(error: unknown): boolean {
|
|
16
|
-
return (
|
|
17
|
-
error instanceof Error &&
|
|
18
|
-
"code" in error &&
|
|
19
|
-
(error as NodeJS.ErrnoException).code === "ENOENT"
|
|
20
|
-
);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
17
|
/** Sole safe-positive ticket invariant (bind / admission / placement / readers). */
|
|
24
18
|
export function isSafePositiveTicketNumber(value: unknown): value is number {
|
|
25
19
|
return typeof value === "number" && Number.isSafeInteger(value) && value >= 1;
|
|
@@ -69,10 +63,10 @@ async function readJsonObject(
|
|
|
69
63
|
): Promise<Record<string, unknown> | undefined> {
|
|
70
64
|
try {
|
|
71
65
|
const raw: unknown = JSON.parse(await readFile(path, "utf8"));
|
|
72
|
-
if (
|
|
66
|
+
if (!isRecord(raw)) {
|
|
73
67
|
return undefined;
|
|
74
68
|
}
|
|
75
|
-
return raw
|
|
69
|
+
return raw;
|
|
76
70
|
} catch (error) {
|
|
77
71
|
if (isEnoent(error)) return undefined;
|
|
78
72
|
throw error;
|
|
@@ -7,7 +7,42 @@
|
|
|
7
7
|
* is defaulted, rewritten, or dropped (ADR 0055).
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import { Type } from "typebox";
|
|
11
|
+
|
|
12
|
+
import { withTerminatingOutputDeclarations } from "./package-contracts/terminating-infrastructure.ts";
|
|
13
|
+
|
|
10
14
|
export const SECRETARIAT_OUTPUT_TOOL_NAME = "ak_secretariat_output";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 中书省终局回执形状。
|
|
18
|
+
* #1134: `secretariatStatus` alone is the trajectory field
|
|
19
|
+
* (src/packaged-role-registry.ts receiptStatusKey; the public settlement reads
|
|
20
|
+
* converged | escalate to route); its words ride the description. note/evidence/
|
|
21
|
+
* decisionGate are declared name + semantic description only — the string type, the
|
|
22
|
+
* number type, the nested question/options object shape and the required constraint
|
|
23
|
+
* are deleted, because the package declaration IS the host's pre-dispatch validator.
|
|
24
|
+
* (ticketNumber keeps its own declaration: it is the declared seat identity the
|
|
25
|
+
* activation flag and settlement read, not narrative content.)
|
|
26
|
+
*/
|
|
27
|
+
export const secretariatVerdictSchema = withTerminatingOutputDeclarations(
|
|
28
|
+
Type.Object(
|
|
29
|
+
{
|
|
30
|
+
secretariatStatus: Type.Unknown({
|
|
31
|
+
description: "converged | escalate",
|
|
32
|
+
}),
|
|
33
|
+
ticketNumber: Type.Optional(
|
|
34
|
+
Type.Unknown({ description: "本票号;署时指向最终正文所在票" }),
|
|
35
|
+
),
|
|
36
|
+
note: Type.Unknown({ description: "附注" }),
|
|
37
|
+
evidence: Type.Optional(Type.Unknown({ description: "留存证据" })),
|
|
38
|
+
decisionGate: Type.Unknown({
|
|
39
|
+
description: "需陛下处置的问题与选项;可写 question 与 options,原样留存。",
|
|
40
|
+
}),
|
|
41
|
+
},
|
|
42
|
+
{ additionalProperties: true },
|
|
43
|
+
),
|
|
44
|
+
);
|
|
45
|
+
(secretariatVerdictSchema as unknown as { required: string[] }).required = [];
|
|
11
46
|
/**
|
|
12
47
|
* #969 durable custom entry: 给事中 terminal (署|上呈) for seat settlement projection.
|
|
13
48
|
* Carries original receipt bytes + nested runId. Envelope persists custom entries
|