@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/auditor-role.ts
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import {
|
|
5
5
|
AUDITOR_OUTPUT_TOOL_NAME,
|
|
6
|
-
auditorOutputSchema,
|
|
7
6
|
} from "./package-contracts/auditor-output.ts";
|
|
7
|
+
import { roleSubmissionDeclaration } from "./role-submission-declarations.ts";
|
|
8
8
|
|
|
9
9
|
export { AUDITOR_OUTPUT_TOOL_NAME };
|
|
10
10
|
|
|
@@ -12,10 +12,4 @@ export type AuditorRuntimeDependencies = {
|
|
|
12
12
|
loadSoul(): Promise<string>;
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
-
export const AUDITOR_TOOL_SPEC =
|
|
16
|
-
name: AUDITOR_OUTPUT_TOOL_NAME,
|
|
17
|
-
label: "审刑院输出",
|
|
18
|
-
description: "审刑院终局回执,status 为 converged、continue 或 escalate。",
|
|
19
|
-
promptSnippet: "审刑院终局回执",
|
|
20
|
-
parameters: auditorOutputSchema,
|
|
21
|
-
} as const;
|
|
15
|
+
export const AUDITOR_TOOL_SPEC = roleSubmissionDeclaration("auditor");
|
package/src/auditor-soul.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
2
|
import { basename, join } from "node:path";
|
|
3
3
|
|
|
4
|
+
import { isRecord } from "./unknown-value.ts";
|
|
5
|
+
|
|
4
6
|
import {
|
|
5
7
|
joinPackageMaterials,
|
|
6
8
|
readPackageMaterial,
|
|
@@ -126,7 +128,7 @@ export async function readAuditorResumeBinding(runDirectory: string): Promise<
|
|
|
126
128
|
if ((error as NodeJS.ErrnoException).code === "ENOENT") return undefined;
|
|
127
129
|
throw error;
|
|
128
130
|
}
|
|
129
|
-
if (
|
|
131
|
+
if (!isRecord(raw)) return undefined;
|
|
130
132
|
const record = raw as { sourceRunPath?: unknown; auditorSubject?: unknown };
|
|
131
133
|
if (typeof record.sourceRunPath !== "string" || record.sourceRunPath.trim() === "") return undefined;
|
|
132
134
|
const subject = isAuditorSoulRole(record.auditorSubject)
|
|
@@ -19,22 +19,11 @@ import {
|
|
|
19
19
|
readMigrationDerivedTicketNumber,
|
|
20
20
|
} from "./run-ticket-number.ts";
|
|
21
21
|
|
|
22
|
+
import { isRecord, isEnoent } from "./unknown-value.ts";
|
|
23
|
+
|
|
22
24
|
const TICKET_NUMBER_RE = /^[1-9][0-9]*$/;
|
|
23
25
|
const RUN_DIR_NAME_RE = /^([^@]+)@([^@]+)$/;
|
|
24
26
|
|
|
25
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
26
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/** Sole migration ENOENT projection — non-ENOENT must propagate. */
|
|
30
|
-
export function isMigrationEnoent(error: unknown): boolean {
|
|
31
|
-
return (
|
|
32
|
-
error instanceof Error &&
|
|
33
|
-
"code" in error &&
|
|
34
|
-
(error as NodeJS.ErrnoException).code === "ENOENT"
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
27
|
/** Book-key directories under a books root; missing root → []. */
|
|
39
28
|
export async function listMigrationBookKeys(
|
|
40
29
|
booksDirectory: string,
|
|
@@ -46,7 +35,7 @@ export async function listMigrationBookKeys(
|
|
|
46
35
|
.map((entry) => entry.name)
|
|
47
36
|
.sort((a, b) => a.localeCompare(b));
|
|
48
37
|
} catch (error) {
|
|
49
|
-
if (
|
|
38
|
+
if (isEnoent(error)) return [];
|
|
50
39
|
throw error;
|
|
51
40
|
}
|
|
52
41
|
}
|
|
@@ -59,7 +48,7 @@ export async function listMigrationDirents(
|
|
|
59
48
|
const entries = await readdir(directory, { withFileTypes: true });
|
|
60
49
|
return [...entries].sort((a, b) => a.name.localeCompare(b.name));
|
|
61
50
|
} catch (error) {
|
|
62
|
-
if (
|
|
51
|
+
if (isEnoent(error)) return [];
|
|
63
52
|
throw error;
|
|
64
53
|
}
|
|
65
54
|
}
|
|
@@ -109,7 +98,7 @@ async function readProjectRootFromRun(
|
|
|
109
98
|
return { projectRoot, sourcePage: page };
|
|
110
99
|
}
|
|
111
100
|
} catch (error) {
|
|
112
|
-
if (
|
|
101
|
+
if (isEnoent(error)) continue;
|
|
113
102
|
throw error;
|
|
114
103
|
}
|
|
115
104
|
}
|
|
@@ -25,7 +25,6 @@ import {
|
|
|
25
25
|
import {
|
|
26
26
|
findPlacedMigratingRun,
|
|
27
27
|
isFlatRunsRelative,
|
|
28
|
-
isMigrationEnoent,
|
|
29
28
|
isTicketNumberString,
|
|
30
29
|
listBackupRunLeaves,
|
|
31
30
|
listMigrationBookKeys,
|
|
@@ -37,6 +36,8 @@ import {
|
|
|
37
36
|
type RunDirectoryPathRewrite,
|
|
38
37
|
} from "./role-run-relocation.ts";
|
|
39
38
|
|
|
39
|
+
import { isRecord, errorText, isEnoent } from "./unknown-value.ts";
|
|
40
|
+
|
|
40
41
|
const AUDITOR_ROLES_PARTITION = "auditor-roles";
|
|
41
42
|
const ISSUES_PARTITION = "issues";
|
|
42
43
|
const DEPRECATED_KINDS_PARTITION = "deprecated-kinds";
|
|
@@ -101,7 +102,7 @@ async function directoryExists(path: string): Promise<boolean> {
|
|
|
101
102
|
const info = await stat(path);
|
|
102
103
|
return info.isDirectory();
|
|
103
104
|
} catch (error) {
|
|
104
|
-
if (
|
|
105
|
+
if (isEnoent(error)) return false;
|
|
105
106
|
throw error;
|
|
106
107
|
}
|
|
107
108
|
}
|
|
@@ -219,7 +220,7 @@ async function readJsonlParentSession(path: string): Promise<string | undefined>
|
|
|
219
220
|
try {
|
|
220
221
|
raw = await readFile(path, "utf8");
|
|
221
222
|
} catch (error) {
|
|
222
|
-
if (
|
|
223
|
+
if (isEnoent(error)) return undefined;
|
|
223
224
|
throw error;
|
|
224
225
|
}
|
|
225
226
|
const newline = raw.indexOf("\n");
|
|
@@ -227,7 +228,7 @@ async function readJsonlParentSession(path: string): Promise<string | undefined>
|
|
|
227
228
|
if (line.length === 0) return undefined;
|
|
228
229
|
try {
|
|
229
230
|
const header: unknown = JSON.parse(line);
|
|
230
|
-
if (
|
|
231
|
+
if (!isRecord(header)) {
|
|
231
232
|
return undefined;
|
|
232
233
|
}
|
|
233
234
|
const parentSession = (header as { parentSession?: unknown }).parentSession;
|
|
@@ -268,13 +269,13 @@ async function findTrueVolumeParent(
|
|
|
268
269
|
try {
|
|
269
270
|
ledgerRaw = await readFile(join(volumeDirectory, CURRENT_SESSION_LEDGER), "utf8");
|
|
270
271
|
} catch (error) {
|
|
271
|
-
if (
|
|
272
|
+
if (isEnoent(error)) return undefined;
|
|
272
273
|
throw error;
|
|
273
274
|
}
|
|
274
275
|
let sessionFileField: string;
|
|
275
276
|
try {
|
|
276
277
|
const ledger: unknown = JSON.parse(ledgerRaw);
|
|
277
|
-
if (
|
|
278
|
+
if (!isRecord(ledger)) {
|
|
278
279
|
return undefined;
|
|
279
280
|
}
|
|
280
281
|
const sessionFile = (ledger as { sessionFile?: unknown }).sessionFile;
|
|
@@ -298,7 +299,7 @@ async function findTrueVolumeParent(
|
|
|
298
299
|
const info = await lstat(liveSession);
|
|
299
300
|
if (!info.isFile()) return undefined;
|
|
300
301
|
} catch (error) {
|
|
301
|
-
if (
|
|
302
|
+
if (isEnoent(error)) return undefined;
|
|
302
303
|
throw error;
|
|
303
304
|
}
|
|
304
305
|
|
|
@@ -413,7 +414,7 @@ async function readSessionFileField(path: string): Promise<string | undefined> {
|
|
|
413
414
|
try {
|
|
414
415
|
raw = await readFile(path, "utf8");
|
|
415
416
|
} catch (error) {
|
|
416
|
-
if (
|
|
417
|
+
if (isEnoent(error)) return undefined;
|
|
417
418
|
throw error;
|
|
418
419
|
}
|
|
419
420
|
let parsed: unknown;
|
|
@@ -422,12 +423,12 @@ async function readSessionFileField(path: string): Promise<string | undefined> {
|
|
|
422
423
|
} catch (error) {
|
|
423
424
|
throw new Error(
|
|
424
425
|
`book topology migration cannot read current-session pointer at ${path}: invalid JSON (${
|
|
425
|
-
|
|
426
|
+
errorText(error)
|
|
426
427
|
})`,
|
|
427
428
|
{ cause: error },
|
|
428
429
|
);
|
|
429
430
|
}
|
|
430
|
-
if (
|
|
431
|
+
if (!isRecord(parsed)) {
|
|
431
432
|
throw new Error(
|
|
432
433
|
`book topology migration cannot read current-session pointer at ${path}: expected a JSON object`,
|
|
433
434
|
);
|
|
@@ -480,7 +481,7 @@ async function mergeRewrittenCurrentSession(
|
|
|
480
481
|
srcStat = await stat(srcPath);
|
|
481
482
|
srcRaw = await readFile(srcPath, "utf8");
|
|
482
483
|
} catch (error) {
|
|
483
|
-
if (
|
|
484
|
+
if (isEnoent(error)) return;
|
|
484
485
|
throw error;
|
|
485
486
|
}
|
|
486
487
|
|
|
@@ -488,7 +489,7 @@ async function mergeRewrittenCurrentSession(
|
|
|
488
489
|
let nextSessionFile: string | undefined;
|
|
489
490
|
try {
|
|
490
491
|
const parsed: unknown = JSON.parse(srcRaw);
|
|
491
|
-
if (
|
|
492
|
+
if (isRecord(parsed)) {
|
|
492
493
|
const record = parsed as Record<string, unknown>;
|
|
493
494
|
if (typeof record.sessionFile === "string") {
|
|
494
495
|
const rewritten = rewritePathIntoDestination(
|
|
@@ -510,7 +511,7 @@ async function mergeRewrittenCurrentSession(
|
|
|
510
511
|
try {
|
|
511
512
|
destStat = await stat(destPath);
|
|
512
513
|
} catch (error) {
|
|
513
|
-
if (!
|
|
514
|
+
if (!isEnoent(error)) throw error;
|
|
514
515
|
}
|
|
515
516
|
await writeWinningCurrentSession(
|
|
516
517
|
destPath,
|
|
@@ -656,7 +657,7 @@ async function copyIssuesNonRunTree(source: string, destination: string): Promis
|
|
|
656
657
|
`book topology migration refuses to overwrite ${to} with ${from}`,
|
|
657
658
|
);
|
|
658
659
|
} catch (error) {
|
|
659
|
-
if (!
|
|
660
|
+
if (!isEnoent(error)) throw error;
|
|
660
661
|
}
|
|
661
662
|
await cp(from, to, { preserveTimestamps: true });
|
|
662
663
|
}
|
|
@@ -719,7 +720,7 @@ async function unlinkIfPresent(path: string): Promise<void> {
|
|
|
719
720
|
try {
|
|
720
721
|
await unlink(path);
|
|
721
722
|
} catch (error) {
|
|
722
|
-
if (!
|
|
723
|
+
if (!isEnoent(error)) throw error;
|
|
723
724
|
}
|
|
724
725
|
}
|
|
725
726
|
|
|
@@ -17,12 +17,13 @@ import {
|
|
|
17
17
|
import {
|
|
18
18
|
bookHistoricalRoots,
|
|
19
19
|
findPlacedMigratingRun,
|
|
20
|
-
isMigrationEnoent,
|
|
21
20
|
listMigrationBookKeys,
|
|
22
21
|
listMigrationDirents,
|
|
23
22
|
runRefFromBoundPath,
|
|
24
23
|
} from "./book-topology-migration-placement.ts";
|
|
25
24
|
|
|
25
|
+
import { isRecord, isEnoent } from "./unknown-value.ts";
|
|
26
|
+
|
|
26
27
|
const SITIAN_MIXED_VOLUME_PARTITIONS = [
|
|
27
28
|
"attendance",
|
|
28
29
|
"auditor",
|
|
@@ -32,10 +33,6 @@ const SITIAN_MIXED_VOLUME_PARTITIONS = [
|
|
|
32
33
|
|
|
33
34
|
const CURRENT_SESSION_LEDGER = "current-session.json";
|
|
34
35
|
|
|
35
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
36
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
36
|
function posixRelative(from: string, to: string): string {
|
|
40
37
|
return relative(from, to).split(sep).join("/");
|
|
41
38
|
}
|
|
@@ -98,7 +95,7 @@ async function readRegularBackupFile(path: string): Promise<string | undefined>
|
|
|
98
95
|
try {
|
|
99
96
|
info = await lstat(path);
|
|
100
97
|
} catch (error) {
|
|
101
|
-
if (
|
|
98
|
+
if (isEnoent(error)) return undefined;
|
|
102
99
|
throw error;
|
|
103
100
|
}
|
|
104
101
|
if (!info.isFile()) {
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
* - malformed → unbound with exact bytes + malformedRows entry
|
|
10
10
|
* - misplaced: any foreign jsonl whose kind is one of the three classes
|
|
11
11
|
*/
|
|
12
|
-
import { createHash } from "node:crypto";
|
|
13
12
|
import { appendFile, mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
14
13
|
import { dirname, join, relative, sep } from "node:path";
|
|
15
14
|
|
|
@@ -18,7 +17,6 @@ import {
|
|
|
18
17
|
findBookRunDirectory,
|
|
19
18
|
findPlacedMigratingRun,
|
|
20
19
|
findUniquePrincipalPlacedRun,
|
|
21
|
-
isMigrationEnoent,
|
|
22
20
|
isTicketNumberString,
|
|
23
21
|
listMigrationBookKeys,
|
|
24
22
|
listMigrationDirents,
|
|
@@ -36,6 +34,9 @@ import {
|
|
|
36
34
|
import { S4_SUBMISSION_LEDGER_KINDS } from "./sitian-appender.ts";
|
|
37
35
|
import { projectTicketProvenanceHeader } from "./ticket-provenance-contracts.ts";
|
|
38
36
|
|
|
37
|
+
import { sha256Hex } from "./sha256.ts";
|
|
38
|
+
import { isRecord, isEnoent } from "./unknown-value.ts";
|
|
39
|
+
|
|
39
40
|
const TICKET_PROVENANCE = "ticket-provenance";
|
|
40
41
|
const SUBMISSION_LEDGER = "submission-ledger";
|
|
41
42
|
const ATTEMPT_HISTORY = "attempt-history";
|
|
@@ -47,10 +48,6 @@ type JsonLine =
|
|
|
47
48
|
| { readonly ok: true; readonly value: Record<string, unknown>; readonly raw: string }
|
|
48
49
|
| { readonly ok: false; readonly raw: string };
|
|
49
50
|
|
|
50
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
51
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
51
|
function parseJsonlLine(raw: string): JsonLine {
|
|
55
52
|
try {
|
|
56
53
|
const value: unknown = JSON.parse(raw);
|
|
@@ -70,7 +67,7 @@ function lineSource(backupBooksDirectory: string, filePath: string, index: numbe
|
|
|
70
67
|
}
|
|
71
68
|
|
|
72
69
|
function stableKey(material: string): string {
|
|
73
|
-
return
|
|
70
|
+
return sha256Hex(material).slice(0, 32);
|
|
74
71
|
}
|
|
75
72
|
|
|
76
73
|
async function readJsonlLines(filePath: string): Promise<readonly string[]> {
|
|
@@ -78,7 +75,7 @@ async function readJsonlLines(filePath: string): Promise<readonly string[]> {
|
|
|
78
75
|
try {
|
|
79
76
|
text = await readFile(filePath, "utf8");
|
|
80
77
|
} catch (error) {
|
|
81
|
-
if (
|
|
78
|
+
if (isEnoent(error)) return [];
|
|
82
79
|
throw error;
|
|
83
80
|
}
|
|
84
81
|
if (text.length === 0) return [];
|
|
@@ -629,7 +626,7 @@ async function mergeOfferedIdentities(
|
|
|
629
626
|
await stat(from);
|
|
630
627
|
lines = await readJsonlLines(from);
|
|
631
628
|
} catch (error) {
|
|
632
|
-
if (
|
|
629
|
+
if (isEnoent(error)) return;
|
|
633
630
|
throw error;
|
|
634
631
|
}
|
|
635
632
|
const destFile = join(destDir, OFFERED_IDENTITIES);
|
|
@@ -704,7 +701,7 @@ async function migrateHomePartitionBook(
|
|
|
704
701
|
try {
|
|
705
702
|
await stat(recordsFile);
|
|
706
703
|
} catch (error) {
|
|
707
|
-
if (
|
|
704
|
+
if (isEnoent(error)) continue;
|
|
708
705
|
throw error;
|
|
709
706
|
}
|
|
710
707
|
await migrateJsonlFileByKind(context, bookKey, writes, recordsFile, TICKET_PROVENANCE, outcomes);
|
|
@@ -10,7 +10,6 @@ import { basename, dirname, join, relative, sep } from "node:path";
|
|
|
10
10
|
|
|
11
11
|
import {
|
|
12
12
|
destinationRunDirectory,
|
|
13
|
-
isMigrationEnoent,
|
|
14
13
|
isTicketNumberString,
|
|
15
14
|
listBackupRunLeaves,
|
|
16
15
|
listMigrationBookKeys,
|
|
@@ -32,6 +31,8 @@ import {
|
|
|
32
31
|
readBoardTicketNumber,
|
|
33
32
|
} from "./run-ticket-number.ts";
|
|
34
33
|
|
|
34
|
+
import { isEnoent } from "./unknown-value.ts";
|
|
35
|
+
|
|
35
36
|
const RUNS_PARTITION = "runs";
|
|
36
37
|
|
|
37
38
|
const RUN_LEAF =
|
|
@@ -62,7 +63,7 @@ async function pathExists(path: string): Promise<boolean> {
|
|
|
62
63
|
await stat(path);
|
|
63
64
|
return true;
|
|
64
65
|
} catch (error) {
|
|
65
|
-
if (
|
|
66
|
+
if (isEnoent(error)) return false;
|
|
66
67
|
throw error;
|
|
67
68
|
}
|
|
68
69
|
}
|
|
@@ -307,7 +308,7 @@ export async function relocateBoardBoundUnboundRunsInBook(
|
|
|
307
308
|
try {
|
|
308
309
|
entries = await readdir(unboundRuns, { withFileTypes: true });
|
|
309
310
|
} catch (error) {
|
|
310
|
-
if (
|
|
311
|
+
if (isEnoent(error)) return [];
|
|
311
312
|
throw error;
|
|
312
313
|
}
|
|
313
314
|
|
package/src/collector-config.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
1
|
import { readFile } from "node:fs/promises";
|
|
3
2
|
|
|
3
|
+
import { sha256Hex } from "./sha256.ts";
|
|
4
|
+
import { isRecord } from "./unknown-value.ts";
|
|
5
|
+
|
|
4
6
|
export const COLLECTOR_OWNER_PATTERN = /^[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?$/;
|
|
5
7
|
export const COLLECTOR_REPO_PATTERN = /^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,98}[A-Za-z0-9])?$/;
|
|
6
8
|
|
|
@@ -51,17 +53,13 @@ export function parseCollectorPrNumber(raw: unknown): number {
|
|
|
51
53
|
return value;
|
|
52
54
|
}
|
|
53
55
|
|
|
54
|
-
function record(value: unknown): value is Record<string, unknown> {
|
|
55
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
56
|
function canonicalManifest(requests: readonly CollectorRequestConfig[]): string {
|
|
59
57
|
return `${JSON.stringify({ requests: requests.map((request) => ({ id: request.id, body: request.requestBody })) })}\n`;
|
|
60
58
|
}
|
|
61
59
|
|
|
62
60
|
export function emptyCollectorManifest(): CollectorManifest {
|
|
63
61
|
const canonicalJson = canonicalManifest([]);
|
|
64
|
-
return { requests: [], canonicalJson, digest:
|
|
62
|
+
return { requests: [], canonicalJson, digest: sha256Hex(canonicalJson) };
|
|
65
63
|
}
|
|
66
64
|
|
|
67
65
|
/** Optional request configuration. It names requests, never expected observers. */
|
|
@@ -70,17 +68,17 @@ export async function loadCollectorManifest(path: string): Promise<CollectorMani
|
|
|
70
68
|
try { bytes = await readFile(path); } catch (error) { fail(`Collector request manifest is unreadable at ${path}`, error); }
|
|
71
69
|
let parsed: unknown;
|
|
72
70
|
try { parsed = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes)); } catch (error) { fail("Collector request manifest must be UTF-8 JSON", error); }
|
|
73
|
-
if (!
|
|
71
|
+
if (!isRecord(parsed)) fail("Collector request manifest must be an object");
|
|
74
72
|
const rawRequests = parsed.requests ?? [];
|
|
75
73
|
if (!Array.isArray(rawRequests)) fail("Collector request manifest requests must be an array");
|
|
76
74
|
const requests: CollectorRequestConfig[] = [];
|
|
77
75
|
const ids = new Set<string>();
|
|
78
76
|
for (const [index, item] of rawRequests.entries()) {
|
|
79
|
-
if (!
|
|
77
|
+
if (!isRecord(item) || typeof item.id !== "string" || item.id.length === 0 || typeof item.body !== "string" || item.body.trim() === "") fail(`Collector request manifest requests[${index}] is invalid`);
|
|
80
78
|
if (ids.has(item.id)) fail(`Collector request manifest has duplicate request id "${item.id}"`);
|
|
81
79
|
ids.add(item.id);
|
|
82
80
|
requests.push({ id: item.id, requestBody: item.body });
|
|
83
81
|
}
|
|
84
82
|
const canonicalJson = canonicalManifest(requests);
|
|
85
|
-
return { requests, canonicalJson, digest:
|
|
83
|
+
return { requests, canonicalJson, digest: sha256Hex(canonicalJson), sourcePath: path };
|
|
86
84
|
}
|
package/src/collector-role.ts
CHANGED
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
* #1088: code no longer observes/requests/merges GitHub findings — the LLM
|
|
4
4
|
* uses host CLI tools. Envelope owns host-surface + construction seatbelt.
|
|
5
5
|
*/
|
|
6
|
-
import type { RoleHost, HostContext
|
|
7
|
-
import
|
|
6
|
+
import type { RoleHost, HostContext } from "./host-contracts.ts";
|
|
7
|
+
import { registerFiledSubmissionTool } from "./filed-submission.ts";
|
|
8
|
+
import { roleSubmissionDeclaration } from "./role-submission-declarations.ts";
|
|
8
9
|
|
|
9
10
|
import {
|
|
10
11
|
emptyCollectorManifest,
|
|
@@ -17,8 +18,6 @@ import {
|
|
|
17
18
|
import {
|
|
18
19
|
COLLECTOR_OUTPUT_TOOL,
|
|
19
20
|
} from "./package-contracts/collector-output.ts";
|
|
20
|
-
import { collectorOutputArgsSchema } from "./collector-tool-schemas.ts";
|
|
21
|
-
|
|
22
21
|
export { COLLECTOR_OUTPUT_TOOL };
|
|
23
22
|
|
|
24
23
|
export const COLLECTOR_REQUIRED_TOOLS = [COLLECTOR_OUTPUT_TOOL] as const;
|
|
@@ -54,8 +53,6 @@ export const COLLECTOR_TRANSPORT_FLAGS = Object.freeze([
|
|
|
54
53
|
}),
|
|
55
54
|
] as const);
|
|
56
55
|
|
|
57
|
-
const outputSchema = collectorOutputArgsSchema;
|
|
58
|
-
type OutputParams = Static<typeof outputSchema>;
|
|
59
56
|
|
|
60
57
|
export type CollectorRoleDependencies = {
|
|
61
58
|
loadSoul(): Promise<string>;
|
|
@@ -164,28 +161,8 @@ export function createCollectorRoleRuntime(
|
|
|
164
161
|
if (toolsRegistered) return;
|
|
165
162
|
toolsRegistered = true;
|
|
166
163
|
|
|
167
|
-
pi
|
|
168
|
-
|
|
169
|
-
label: "通进司输出",
|
|
170
|
-
description: "提交通进司回执。",
|
|
171
|
-
promptSnippet: "提交通进司回执",
|
|
172
|
-
parameters: outputSchema,
|
|
173
|
-
async execute(
|
|
174
|
-
_toolCallId: string,
|
|
175
|
-
params: OutputParams,
|
|
176
|
-
_signal: AbortSignal | undefined,
|
|
177
|
-
_onUpdate: unknown,
|
|
178
|
-
_ctx: HostContext,
|
|
179
|
-
): Promise<HostToolResult<unknown>> {
|
|
180
|
-
const activation = getActivation();
|
|
181
|
-
if (activation === undefined) throw new Error("通进司未激活");
|
|
182
|
-
// #1088 / #836: record as submitted — runtime does not merge findings.
|
|
183
|
-
return {
|
|
184
|
-
content: [],
|
|
185
|
-
details: params,
|
|
186
|
-
terminate: true as const,
|
|
187
|
-
};
|
|
188
|
-
},
|
|
164
|
+
registerFiledSubmissionTool(pi, roleSubmissionDeclaration("collector"), {
|
|
165
|
+
readyError: () => (getActivation() === undefined ? "通进司未激活" : undefined),
|
|
189
166
|
});
|
|
190
167
|
},
|
|
191
168
|
};
|
|
@@ -8,6 +8,7 @@ import { officerConclusionReask } from "./gatekeeper-role.ts";
|
|
|
8
8
|
import { receivedDiscriminator } from "./submission-errors.ts";
|
|
9
9
|
import { coalesceSubmissionRows } from "./public-cli/terminal.ts";
|
|
10
10
|
import { readableGateItem } from "./readable-gate-item.ts";
|
|
11
|
+
import { isRecord } from "./unknown-value.ts";
|
|
11
12
|
|
|
12
13
|
export type ComplianceNoReceipt = NoReceiptLifecycleFacts & { status: "no-receipt"; usage?: Usage };
|
|
13
14
|
/**
|
|
@@ -63,7 +64,7 @@ function readListField(value: unknown): readonly unknown[] { return Array.isArra
|
|
|
63
64
|
|
|
64
65
|
/** Try to project a known three-state compliance decision; undefined when not converged/continue/escalate. */
|
|
65
66
|
export function tryReadComplianceCandidate(arguments_: unknown, usage?: Usage): ComplianceDecision | undefined {
|
|
66
|
-
if (
|
|
67
|
+
if (!isRecord(arguments_)) {
|
|
67
68
|
return undefined;
|
|
68
69
|
}
|
|
69
70
|
const args = arguments_ as Record<string, unknown>;
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { REVIEW_QUEUE_STATUSES, REVIEW_SUBMISSION_OUTPUT_TOOL_NAME } from "./review-submission.ts";
|
|
9
|
+
import { isRecord } from "./unknown-value.ts";
|
|
9
10
|
|
|
10
11
|
export const COUNTERSIGN_OUTPUT_TOOL_NAME = REVIEW_SUBMISSION_OUTPUT_TOOL_NAME;
|
|
11
12
|
|
|
@@ -25,7 +26,7 @@ export type CountersignVerdict =
|
|
|
25
26
|
};
|
|
26
27
|
|
|
27
28
|
export function validateRecordedCountersignOutput(verdict: unknown): CountersignVerdict {
|
|
28
|
-
if (
|
|
29
|
+
if (!isRecord(verdict)) {
|
|
29
30
|
throw new Error("Countersign verdict has no execution discriminator");
|
|
30
31
|
}
|
|
31
32
|
let status: unknown;
|
package/src/countersign-role.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { reviewSubmissionSchema } from "./review-submission.ts";
|
|
2
|
+
import { roleSubmissionDeclaration } from "./role-submission-declarations.ts";
|
|
2
3
|
import {
|
|
3
4
|
COUNTERSIGN_OUTPUT_TOOL_NAME,
|
|
4
5
|
validateRecordedCountersignOutput,
|
|
@@ -26,10 +27,4 @@ export type CountersignRuntimeDependencies = {
|
|
|
26
27
|
* 决定工具规格。生命周期装配(注册、activate、prompt 注入、singleton 检查、
|
|
27
28
|
* terminate)归注册信封 owner——src/role-runtime.ts(ADR 0018 / #572 R2 判词)。
|
|
28
29
|
*/
|
|
29
|
-
export const COUNTERSIGN_TOOL_SPEC =
|
|
30
|
-
name: COUNTERSIGN_OUTPUT_TOOL_NAME,
|
|
31
|
-
label: "给事中输出",
|
|
32
|
-
description: "给事中决议。",
|
|
33
|
-
promptSnippet: "给事中决议",
|
|
34
|
-
parameters: countersignVerdictSchema,
|
|
35
|
-
} as const;
|
|
30
|
+
export const COUNTERSIGN_TOOL_SPEC = roleSubmissionDeclaration("countersign");
|
package/src/diarist-contracts.ts
CHANGED
|
@@ -7,11 +7,16 @@
|
|
|
7
7
|
* #901: LLM submits bounds; the mechanical layer projects source bytes.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import { Type } from "typebox";
|
|
11
|
+
|
|
12
|
+
import { openToolObject } from "./open-tool-schema.ts";
|
|
13
|
+
import { withTerminatingOutputDeclarations } from "./package-contracts/terminating-infrastructure.ts";
|
|
10
14
|
import {
|
|
11
15
|
projectTicketProvenanceSessions,
|
|
12
16
|
type TicketProvenanceSession,
|
|
13
17
|
} from "./ticket-provenance-contracts.ts";
|
|
14
18
|
import { isSafePositiveTicketNumber } from "./run-ticket-number.ts";
|
|
19
|
+
import { isRecord } from "./unknown-value.ts";
|
|
15
20
|
|
|
16
21
|
export const DIARIST_OUTPUT_TOOL_NAME = "ak_diarist_output";
|
|
17
22
|
|
|
@@ -43,7 +48,7 @@ export type DiaristOutput =
|
|
|
43
48
|
};
|
|
44
49
|
|
|
45
50
|
export function validateRecordedDiaristOutput(value: unknown): DiaristOutput {
|
|
46
|
-
if (
|
|
51
|
+
if (!isRecord(value)) {
|
|
47
52
|
throw new Error("Diarist output has no execution discriminator");
|
|
48
53
|
}
|
|
49
54
|
let status: unknown;
|
|
@@ -78,7 +83,7 @@ export function projectDiaristTicketSessions(
|
|
|
78
83
|
if (!Array.isArray(raw)) return undefined;
|
|
79
84
|
const perTicket = new Map<number, TicketProvenanceSession[]>();
|
|
80
85
|
for (const entry of raw) {
|
|
81
|
-
if (
|
|
86
|
+
if (!isRecord(entry)) return undefined;
|
|
82
87
|
const { ticketNumber, sessions: rawSessions } = entry as Record<string, unknown>;
|
|
83
88
|
if (!isSafePositiveTicketNumber(ticketNumber)) return undefined;
|
|
84
89
|
const sessions = projectTicketProvenanceSessions(rawSessions);
|
|
@@ -87,3 +92,36 @@ export function projectDiaristTicketSessions(
|
|
|
87
92
|
}
|
|
88
93
|
return Array.from(perTicket, ([ticketNumber, sessions]) => ({ ticketNumber, sessions }));
|
|
89
94
|
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* 起居郎交卷形状。
|
|
98
|
+
* #901:交边界(sessions);正文与不可解析原字节由机械投影。
|
|
99
|
+
* status 的合法词(completed | escalate)写在 description,结算认这些词。
|
|
100
|
+
* sessions / ticketSessions 是投影所读的边界:卷路径或端点读不出时走既有 reask,不中止本轮。
|
|
101
|
+
* 声明只留字段名和语义说明,不留类型、嵌套、长度、必填。
|
|
102
|
+
*/
|
|
103
|
+
const DIARIST_SESSIONS_DESCRIPTION =
|
|
104
|
+
"对话边界。每卷含 path(会话卷绝对或可读路径)与 ranges(本卷本轮各区间)。每段区间含 from / to;起点与终点各写 id(原生 id)或 line(本轮行号),二选一。空列表=本轮无对话可划。端点无法指名时走 reask,不中止。" as const;
|
|
105
|
+
|
|
106
|
+
export const diaristOutputSchema = withTerminatingOutputDeclarations(
|
|
107
|
+
openToolObject(
|
|
108
|
+
Type.Object({
|
|
109
|
+
status: Type.Unknown({
|
|
110
|
+
description: "completed | escalate",
|
|
111
|
+
}),
|
|
112
|
+
ticketNumber: Type.Optional(
|
|
113
|
+
Type.Unknown({
|
|
114
|
+
description:
|
|
115
|
+
"本庭对象票号(正整数)或 null/省略=真无票;下游走 typed 键;认不出用 status=escalate,不洗成无录。机械层不重判。",
|
|
116
|
+
}),
|
|
117
|
+
),
|
|
118
|
+
reason: Type.Unknown({
|
|
119
|
+
description: "status 为 escalate 时:认不出本庭对象的原因",
|
|
120
|
+
}),
|
|
121
|
+
sessions: Type.Optional(Type.Unknown({ description: DIARIST_SESSIONS_DESCRIPTION })),
|
|
122
|
+
ticketSessions: Type.Unknown({
|
|
123
|
+
description: `多票庭逐票对话边界;每票含 ticketNumber(本条边界所归票号,正整数)与 sessions(${DIARIST_SESSIONS_DESCRIPTION})。一次交卷各票各自分录。与单票 sessions 二选一。`,
|
|
124
|
+
}),
|
|
125
|
+
}),
|
|
126
|
+
),
|
|
127
|
+
);
|
package/src/diarist-role.ts
CHANGED
|
@@ -1,53 +1,20 @@
|
|
|
1
1
|
import type { Static } from "typebox";
|
|
2
|
-
import { Type } from "typebox";
|
|
3
2
|
|
|
4
|
-
import { openToolObject } from "./open-tool-schema.ts";
|
|
5
|
-
import { withTerminatingOutputDeclarations } from "./package-contracts/terminating-infrastructure.ts";
|
|
6
3
|
import {
|
|
7
4
|
DIARIST_OUTPUT_TOOL_NAME,
|
|
5
|
+
diaristOutputSchema,
|
|
8
6
|
validateRecordedDiaristOutput,
|
|
9
7
|
type DiaristOutput,
|
|
10
8
|
} from "./diarist-contracts.ts";
|
|
9
|
+
import { roleSubmissionDeclaration } from "./role-submission-declarations.ts";
|
|
11
10
|
|
|
12
11
|
export {
|
|
13
12
|
DIARIST_OUTPUT_TOOL_NAME,
|
|
13
|
+
diaristOutputSchema,
|
|
14
14
|
} from "./diarist-contracts.ts";
|
|
15
15
|
export type { DiaristOutput };
|
|
16
16
|
export { validateRecordedDiaristOutput };
|
|
17
17
|
|
|
18
|
-
/**
|
|
19
|
-
* 起居郎交卷形状。
|
|
20
|
-
* #901:交边界(sessions);正文与不可解析原字节由机械投影。
|
|
21
|
-
* status 的合法词(completed | escalate)写在 description,结算认这些词。
|
|
22
|
-
* sessions / ticketSessions 是投影所读的边界:卷路径或端点读不出时走既有 reask,不中止本轮。
|
|
23
|
-
* 声明只留字段名和语义说明,不留类型、嵌套、长度、必填。
|
|
24
|
-
*/
|
|
25
|
-
const DIARIST_SESSIONS_DESCRIPTION =
|
|
26
|
-
"对话边界。每卷含 path(会话卷绝对或可读路径)与 ranges(本卷本轮各区间)。每段区间含 from / to;起点与终点各写 id(原生 id)或 line(本轮行号),二选一。空列表=本轮无对话可划。端点无法指名时走 reask,不中止。" as const;
|
|
27
|
-
|
|
28
|
-
export const diaristOutputSchema = withTerminatingOutputDeclarations(
|
|
29
|
-
openToolObject(
|
|
30
|
-
Type.Object({
|
|
31
|
-
status: Type.Unknown({
|
|
32
|
-
description: "completed | escalate",
|
|
33
|
-
}),
|
|
34
|
-
ticketNumber: Type.Optional(
|
|
35
|
-
Type.Unknown({
|
|
36
|
-
description:
|
|
37
|
-
"本庭对象票号(正整数)或 null/省略=真无票;下游走 typed 键;认不出用 status=escalate,不洗成无录。机械层不重判。",
|
|
38
|
-
}),
|
|
39
|
-
),
|
|
40
|
-
reason: Type.Unknown({
|
|
41
|
-
description: "status 为 escalate 时:认不出本庭对象的原因",
|
|
42
|
-
}),
|
|
43
|
-
sessions: Type.Optional(Type.Unknown({ description: DIARIST_SESSIONS_DESCRIPTION })),
|
|
44
|
-
ticketSessions: Type.Unknown({
|
|
45
|
-
description: `多票庭逐票对话边界;每票含 ticketNumber(本条边界所归票号,正整数)与 sessions(${DIARIST_SESSIONS_DESCRIPTION})。一次交卷各票各自分录。与单票 sessions 二选一。`,
|
|
46
|
-
}),
|
|
47
|
-
}),
|
|
48
|
-
),
|
|
49
|
-
);
|
|
50
|
-
|
|
51
18
|
export type DiaristOutputParameters = Static<typeof diaristOutputSchema>;
|
|
52
19
|
|
|
53
20
|
export type DiaristRuntimeDependencies = {
|
|
@@ -57,11 +24,4 @@ export type DiaristRuntimeDependencies = {
|
|
|
57
24
|
/**
|
|
58
25
|
* 决定工具规格。生命周期装配归注册信封 owner——src/role-runtime.ts(ADR 0018)。
|
|
59
26
|
*/
|
|
60
|
-
export const DIARIST_TOOL_SPEC =
|
|
61
|
-
name: DIARIST_OUTPUT_TOOL_NAME,
|
|
62
|
-
label: "起居郎输出",
|
|
63
|
-
description:
|
|
64
|
-
"起居郎交单票 sessions 或多票逐票 ticketSessions 边界;认不出本庭对象则 escalate。",
|
|
65
|
-
promptSnippet: "起居郎交边界",
|
|
66
|
-
parameters: diaristOutputSchema,
|
|
67
|
-
} as const;
|
|
27
|
+
export const DIARIST_TOOL_SPEC = roleSubmissionDeclaration("diarist");
|