@akagilnc/pi-workflow-roles 0.1.3565 → 0.1.3572
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 +4 -1
- package/README.zh-CN.md +1 -1
- package/dist/acp-host/production-host.js +755 -60
- package/dist/diarist-contracts.js +72 -0
- package/dist/package-contracts/terminating-tools.js +20 -2
- package/dist/packaged-role-registry.js +20 -0
- package/dist/public-cli/main.js +533 -634
- package/dist/public-cli/registry.js +4 -1
- package/extensions/role-runtime.ts +1 -0
- package/package.json +1 -1
- package/resources/diarist-collect.md +6 -10
- package/souls/diarist.md +9 -0
- package/src/acp-host/production-host.ts +1 -0
- package/src/acp-host/role-envelope.ts +2 -1
- package/src/diarist-contracts.ts +88 -0
- package/src/diarist-role.ts +60 -0
- package/src/diarist.ts +253 -179
- package/src/host-contracts.ts +6 -1
- package/src/package-contracts/terminating-tools.ts +22 -2
- package/src/packaged-role-registry.ts +20 -0
- package/src/pi/role-turn-host.ts +8 -0
- package/src/public-cli/cli.ts +29 -0
- package/src/public-cli/countersign-run.ts +9 -129
- package/src/public-cli/diarist-run.ts +312 -0
- package/src/public-cli/invocation.ts +23 -2
- package/src/public-cli/option-definitions.ts +18 -0
- package/src/public-cli/post-admission.ts +2 -2
- package/src/public-cli/registry.ts +3 -0
- package/src/public-cli/run-lifecycle.ts +31 -3
- package/src/public-cli/settlement.ts +50 -2
- package/src/public-cli/terminal.ts +2 -1
- package/src/role-runtime.ts +117 -6
- package/src/ticket-provenance-contracts.ts +1 -0
- package/src/ticket-provenance.ts +0 -23
- package/src/diarist-llm-collector.ts +0 -324
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public 起居郎 (diarist) terminating receipt contracts — ADR 0075 `diarist-is-role`.
|
|
3
|
+
* Lawful explicit release: completed, with empty or nonempty selections.
|
|
4
|
+
* Machine facts about the volume come from the mechanical sitian seam, never
|
|
5
|
+
* from model self-report (锚定宪法); this module owns the receipt shape only.
|
|
6
|
+
*/
|
|
7
|
+
export const DIARIST_OUTPUT_TOOL_NAME = "ak_diarist_output";
|
|
8
|
+
export const DIARIST_ACCEPTED_TEXT = "起居郎回执已接受";
|
|
9
|
+
/** Internal transport: frozen candidate-catalog path for this turn's ticket. */
|
|
10
|
+
export const DIARIST_SOURCES_FLAG = {
|
|
11
|
+
name: "ak-diarist-sources",
|
|
12
|
+
definition: {
|
|
13
|
+
description: "Frozen per-ticket source catalog the diarist selects from",
|
|
14
|
+
type: "string",
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
export function validateRecordedDiaristOutput(value) {
|
|
18
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
19
|
+
throw new Error("Diarist output has no execution discriminator");
|
|
20
|
+
}
|
|
21
|
+
let status;
|
|
22
|
+
try {
|
|
23
|
+
status = value.status;
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
throw new Error("Diarist output has no execution discriminator");
|
|
27
|
+
}
|
|
28
|
+
if (status === "completed") {
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
throw new Error("Diarist output has no execution discriminator");
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Lenient projection of submitted selections (第 0 条: shape is not an admission
|
|
35
|
+
* gate). Rows that carry no usable candidateIndex are dropped from the commit,
|
|
36
|
+
* never bounced back at the role.
|
|
37
|
+
*/
|
|
38
|
+
export function projectDiaristSelections(value) {
|
|
39
|
+
const rows = value?.selections;
|
|
40
|
+
if (!Array.isArray(rows))
|
|
41
|
+
return [];
|
|
42
|
+
const out = [];
|
|
43
|
+
for (const row of rows) {
|
|
44
|
+
if (row === null || typeof row !== "object" || Array.isArray(row))
|
|
45
|
+
continue;
|
|
46
|
+
const record = row;
|
|
47
|
+
const index = record.candidateIndex;
|
|
48
|
+
if (typeof index !== "number" || !Number.isInteger(index) || index < 0)
|
|
49
|
+
continue;
|
|
50
|
+
const quotes = Array.isArray(record.quotes)
|
|
51
|
+
? record.quotes.filter((q) => typeof q === "string" && q.length > 0)
|
|
52
|
+
: [];
|
|
53
|
+
out.push({
|
|
54
|
+
candidateIndex: index,
|
|
55
|
+
quotes,
|
|
56
|
+
...(typeof record.note === "string" ? { note: record.note } : {}),
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
return out;
|
|
60
|
+
}
|
|
61
|
+
/** Machine-facing facts from an accepted receipt. Submitted rows retained as-is. */
|
|
62
|
+
export function diaristDecisiveFacts(output) {
|
|
63
|
+
const facts = { status: output.status };
|
|
64
|
+
const selections = output.selections;
|
|
65
|
+
if (Array.isArray(selections))
|
|
66
|
+
facts.selections = selections;
|
|
67
|
+
// Mechanical sitian facts recorded by the envelope at accept time.
|
|
68
|
+
const sitian = output.sitian;
|
|
69
|
+
if (sitian !== undefined)
|
|
70
|
+
facts.sitian = sitian;
|
|
71
|
+
return facts;
|
|
72
|
+
}
|
|
@@ -15,8 +15,9 @@ import { NOTARY_ACCEPTED_TEXT, NOTARY_OUTPUT_TOOL_NAME, validateRecordedNotaryOu
|
|
|
15
15
|
import { COUNTERSIGN_ACCEPTED_TEXT, COUNTERSIGN_OUTPUT_TOOL_NAME, validateRecordedCountersignOutput } from "../countersign-contracts.js";
|
|
16
16
|
import { GLEANER_LEFT_ACCEPTED_TEXT, GLEANER_LEFT_OUTPUT_TOOL_NAME, validateRecordedGleanerLeftOutput } from "../gleaner-left-contracts.js";
|
|
17
17
|
import { INSPECTOR_ACCEPTED_TEXT, INSPECTOR_OUTPUT_TOOL_NAME, validateRecordedInspectorOutput } from "../inspector-contracts.js";
|
|
18
|
+
import { DIARIST_ACCEPTED_TEXT, DIARIST_OUTPUT_TOOL_NAME, validateRecordedDiaristOutput } from "../diarist-contracts.js";
|
|
18
19
|
import { CODER_ACCEPTED_TEXT, CODER_OUTPUT_TOOL_NAME, FIXER_ACCEPTED_TEXT, FIXER_OUTPUT_TOOL_NAME, validateAcceptedWorkerDetails, } from "./worker-output.js";
|
|
19
|
-
export { CODER_ACCEPTED_TEXT, CODER_OUTPUT_TOOL_NAME, COLLECTOR_ACCEPTED_TEXT, COLLECTOR_OUTPUT_TOOL, FIXER_ACCEPTED_TEXT, FIXER_OUTPUT_TOOL_NAME, JUDGE_ACCEPTED_TEXT, JUDGE_OUTPUT_TOOL_NAME, REVIEWER_ACCEPTED_TEXT, REVIEWER_OUTPUT_TOOL_NAME, MERGER_ACCEPTED_TEXT, MERGER_OUTPUT_TOOL_NAME, validateAcceptedCollectorReceipt, validateAcceptedJudgeDetails, projectReviewerIntentToReceipt, validateReviewerIntent, validateRuntimeReviewerReceipt, validateAcceptedWorkerDetails, validateDoctorSubmissionShape, validateRecordedDoctorOutput, validateMergerOutput, validateRecordedNotaryOutput, validateRecordedCountersignOutput, validateRecordedGleanerLeftOutput, validateRecordedInspectorOutput, validateRecordedGatekeeperOutput, validateRecordedNavigatorOutput, };
|
|
20
|
+
export { CODER_ACCEPTED_TEXT, CODER_OUTPUT_TOOL_NAME, COLLECTOR_ACCEPTED_TEXT, COLLECTOR_OUTPUT_TOOL, FIXER_ACCEPTED_TEXT, FIXER_OUTPUT_TOOL_NAME, JUDGE_ACCEPTED_TEXT, JUDGE_OUTPUT_TOOL_NAME, REVIEWER_ACCEPTED_TEXT, REVIEWER_OUTPUT_TOOL_NAME, MERGER_ACCEPTED_TEXT, MERGER_OUTPUT_TOOL_NAME, validateAcceptedCollectorReceipt, validateAcceptedJudgeDetails, projectReviewerIntentToReceipt, validateReviewerIntent, validateRuntimeReviewerReceipt, validateAcceptedWorkerDetails, validateDoctorSubmissionShape, validateRecordedDoctorOutput, validateMergerOutput, validateRecordedNotaryOutput, validateRecordedCountersignOutput, validateRecordedGleanerLeftOutput, validateRecordedInspectorOutput, validateRecordedGatekeeperOutput, validateRecordedNavigatorOutput, validateRecordedDiaristOutput, };
|
|
20
21
|
export const TERMINATING_TOOL_NAMES = [
|
|
21
22
|
CODER_OUTPUT_TOOL_NAME,
|
|
22
23
|
FIXER_OUTPUT_TOOL_NAME,
|
|
@@ -31,6 +32,7 @@ export const TERMINATING_TOOL_NAMES = [
|
|
|
31
32
|
INSPECTOR_OUTPUT_TOOL_NAME,
|
|
32
33
|
GATEKEEPER_OUTPUT_TOOL_NAME,
|
|
33
34
|
NAVIGATOR_OUTPUT_TOOL_NAME,
|
|
35
|
+
DIARIST_OUTPUT_TOOL_NAME,
|
|
34
36
|
];
|
|
35
37
|
export function isTerminatingToolName(name) {
|
|
36
38
|
return TERMINATING_TOOL_NAMES.includes(name);
|
|
@@ -63,6 +65,8 @@ export function acceptedTextFor(toolName) {
|
|
|
63
65
|
return GATEKEEPER_ACCEPTED_TEXT;
|
|
64
66
|
case NAVIGATOR_OUTPUT_TOOL_NAME:
|
|
65
67
|
return NAVIGATOR_ACCEPTED_TEXT;
|
|
68
|
+
case DIARIST_OUTPUT_TOOL_NAME:
|
|
69
|
+
return DIARIST_ACCEPTED_TEXT;
|
|
66
70
|
}
|
|
67
71
|
}
|
|
68
72
|
export class AcceptedDetailsContractError extends CorrectableSubmissionError {
|
|
@@ -114,6 +118,7 @@ export function validateAcceptedDetails(toolName, details) {
|
|
|
114
118
|
[INSPECTOR_OUTPUT_TOOL_NAME]: ["pass", "bounce"],
|
|
115
119
|
[GATEKEEPER_OUTPUT_TOOL_NAME]: ["dispatch", "pass"],
|
|
116
120
|
[NAVIGATOR_OUTPUT_TOOL_NAME]: ["advice"],
|
|
121
|
+
[DIARIST_OUTPUT_TOOL_NAME]: ["completed"],
|
|
117
122
|
};
|
|
118
123
|
const collectorDiscriminator = toolName === COLLECTOR_OUTPUT_TOOL && Array.isArray(candidate?.groups);
|
|
119
124
|
const baseDiscriminator = discriminator;
|
|
@@ -151,6 +156,8 @@ export function validateAcceptedDetails(toolName, details) {
|
|
|
151
156
|
return validateRecordedGatekeeperOutput(details);
|
|
152
157
|
case NAVIGATOR_OUTPUT_TOOL_NAME:
|
|
153
158
|
return validateRecordedNavigatorOutput(details);
|
|
159
|
+
case DIARIST_OUTPUT_TOOL_NAME:
|
|
160
|
+
return validateRecordedDiaristOutput(details);
|
|
154
161
|
}
|
|
155
162
|
}
|
|
156
163
|
catch (error) {
|
|
@@ -177,6 +184,16 @@ export function validateAcceptedLifecycle(toolName, argumentsValue, detailsValue
|
|
|
177
184
|
throw new Error("accepted tool lifecycle details mismatch");
|
|
178
185
|
return details;
|
|
179
186
|
}
|
|
187
|
+
if (toolName === DIARIST_OUTPUT_TOOL_NAME) {
|
|
188
|
+
// Envelope-owned mechanical sitian facts are runtime-bound on details only
|
|
189
|
+
// (same shape as the Doctor runtime cost); the submitted arguments carry the
|
|
190
|
+
// role's own selections. Machine facts never come from model self-report.
|
|
191
|
+
const { sitian: _mechanical, ...submitted } = details;
|
|
192
|
+
const testimony = validateAcceptedDetails(toolName, argumentsValue);
|
|
193
|
+
if (!deepEqual(testimony, submitted))
|
|
194
|
+
throw new Error("accepted tool lifecycle details mismatch");
|
|
195
|
+
return details;
|
|
196
|
+
}
|
|
180
197
|
const argumentsDetails = validateAcceptedDetails(toolName, argumentsValue);
|
|
181
198
|
if (!deepEqual(argumentsDetails, details))
|
|
182
199
|
throw new Error("accepted tool lifecycle details mismatch");
|
|
@@ -192,7 +209,8 @@ export function acceptedFacts(toolName, details) {
|
|
|
192
209
|
case GLEANER_LEFT_OUTPUT_TOOL_NAME:
|
|
193
210
|
case INSPECTOR_OUTPUT_TOOL_NAME:
|
|
194
211
|
case GATEKEEPER_OUTPUT_TOOL_NAME:
|
|
195
|
-
case NAVIGATOR_OUTPUT_TOOL_NAME:
|
|
212
|
+
case NAVIGATOR_OUTPUT_TOOL_NAME:
|
|
213
|
+
case DIARIST_OUTPUT_TOOL_NAME: return { status: details.status };
|
|
196
214
|
case JUDGE_OUTPUT_TOOL_NAME: return { status: details.judgeStatus };
|
|
197
215
|
case COUNTERSIGN_OUTPUT_TOOL_NAME: return { status: details.countersignStatus };
|
|
198
216
|
case MERGER_OUTPUT_TOOL_NAME: {
|
|
@@ -10,6 +10,10 @@ import { NOTARY_OUTPUT_TOOL_NAME } from "./notary-contracts.js";
|
|
|
10
10
|
import { COUNTERSIGN_OUTPUT_TOOL_NAME } from "./countersign-contracts.js";
|
|
11
11
|
import { GLEANER_LEFT_OUTPUT_TOOL_NAME } from "./gleaner-left-contracts.js";
|
|
12
12
|
import { INSPECTOR_OUTPUT_TOOL_NAME } from "./inspector-contracts.js";
|
|
13
|
+
import {
|
|
14
|
+
DIARIST_OUTPUT_TOOL_NAME,
|
|
15
|
+
DIARIST_SOURCES_FLAG
|
|
16
|
+
} from "./diarist-contracts.js";
|
|
13
17
|
const NOTARY_SESSION_MATERIALS = [
|
|
14
18
|
"CLAUDE.md",
|
|
15
19
|
"souls/notary.md",
|
|
@@ -175,6 +179,22 @@ const PUBLIC_ROLE_RECORDS = [
|
|
|
175
179
|
phaseFlag: void 0,
|
|
176
180
|
activationStage: "load-and-install",
|
|
177
181
|
sessionMaterials: ["CLAUDE.md", "souls/navigator.md"]
|
|
182
|
+
},
|
|
183
|
+
// #708 / ADR 0075 `diarist-is-role`: 起居郎 is a seat like any other. The
|
|
184
|
+
// frozen source catalog rides the shared input-flag seam; it is absent for a
|
|
185
|
+
// true-unbound summons (no ticket → no diary).
|
|
186
|
+
{
|
|
187
|
+
role: "diarist",
|
|
188
|
+
phases: [null],
|
|
189
|
+
outputTool: DIARIST_OUTPUT_TOOL_NAME,
|
|
190
|
+
inputFlag: DIARIST_SOURCES_FLAG.name,
|
|
191
|
+
phaseFlag: void 0,
|
|
192
|
+
activationStage: "load-and-install",
|
|
193
|
+
sessionMaterials: [
|
|
194
|
+
"CLAUDE.md",
|
|
195
|
+
"souls/diarist.md",
|
|
196
|
+
"resources/diarist-collect.md"
|
|
197
|
+
]
|
|
178
198
|
}
|
|
179
199
|
];
|
|
180
200
|
const PACKAGED_ROLE_REGISTRY = PUBLIC_ROLE_RECORDS.map(({ sessionMaterials: _omit, ...metadata }) => metadata);
|