@akagilnc/pi-workflow-roles 0.1.4980 → 0.1.4992
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 +438 -456
- package/dist/analyst-gate-cycles-read.js +16 -11
- package/dist/analyst-metric-families/gate-cycles.js +2 -2
- package/dist/audit-escalation.js +4 -4
- package/dist/compliance-transport.js +2 -2
- package/dist/countersign-contracts.js +6 -5
- package/dist/doctor-evidence.js +2 -1
- package/dist/gatekeeper-role.js +20 -41
- package/dist/headless-host/production-host.js +438 -456
- package/dist/inspector-contracts.js +3 -2
- package/dist/migrate-book-topology.js +59 -54
- package/dist/navigator-invocation-identity.js +6 -4
- package/dist/notary-contracts.js +3 -19
- package/dist/package-contracts/auditor-output.js +4 -19
- package/dist/package-contracts/judge-output.js +6 -5
- package/dist/package-contracts/terminating-tools.js +9 -3
- package/dist/packaged-role-registry.js +10 -12
- package/dist/public-cli/countersign-run.js +1 -1
- package/dist/public-cli/main.js +90 -86
- package/dist/public-cli/option-definitions.js +2 -2
- package/dist/public-cli/settlement.js +11 -11
- package/dist/review-submission.js +20 -0
- package/dist/submission-errors.js +2 -2
- package/dist/submission-ledger.js +14 -2
- package/package.json +1 -1
- package/souls/doctor-auditor.md +1 -1
- package/souls/fixer-auditor.md +4 -4
- package/souls/gate-output-guide.md +2 -2
- package/souls/inspector.md +1 -1
- package/souls/judge-auditor.md +2 -2
- package/souls/notary.md +1 -1
- package/souls/quality-law.md +1 -1
- package/souls/secretariat.md +4 -5
- package/src/analyst-gate-cycles-read.ts +17 -9
- package/src/analyst-metric-families/gate-cycles.ts +2 -2
- package/src/audit-escalation.ts +8 -8
- package/src/auditor-role.ts +1 -1
- package/src/compliance-transport.ts +7 -7
- package/src/countersign-contracts.ts +10 -8
- package/src/countersign-role.ts +6 -35
- package/src/doctor-evidence.ts +2 -1
- package/src/doctor-role.ts +1 -2
- package/src/gatekeeper-role.ts +30 -55
- package/src/host-contracts.ts +4 -3
- package/src/inspector-contracts.ts +7 -6
- package/src/inspector-role.ts +3 -20
- package/src/judge-role.ts +29 -49
- package/src/navigator-invocation-identity.ts +16 -4
- package/src/notary-contracts.ts +8 -26
- package/src/notary-role.ts +1 -1
- package/src/package-contracts/auditor-output.ts +6 -27
- package/src/package-contracts/judge-output.ts +10 -8
- package/src/package-contracts/terminating-tools.ts +9 -3
- package/src/packaged-role-registry.ts +12 -13
- package/src/pi/adapter.ts +6 -5
- package/src/public-cli/countersign-run.ts +1 -1
- package/src/public-cli/option-definitions.ts +2 -2
- package/src/public-cli/settlement.ts +13 -14
- package/src/review-submission.ts +29 -0
- package/src/role-envelope.ts +17 -9
- package/src/role-runtime.ts +32 -15
- package/src/submission-errors.ts +6 -6
- package/src/{gatekeeper-pass-envelope.ts → submission-gate.ts} +29 -16
- package/src/submission-ledger.ts +13 -3
- package/src/ticket-trajectory.ts +9 -4
- package/src/worker-role.ts +16 -2
|
@@ -81,7 +81,7 @@ function optionalDispatchReason(raw) {
|
|
|
81
81
|
return raw;
|
|
82
82
|
}
|
|
83
83
|
function isGateTerminatingToolName(toolName) {
|
|
84
|
-
return DISPATCH_TOOLS.has(toolName) || OFFICER_TOOL_TO_FACE[toolName] !== undefined;
|
|
84
|
+
return toolName === "ak_submission_output" || DISPATCH_TOOLS.has(toolName) || OFFICER_TOOL_TO_FACE[toolName] !== undefined;
|
|
85
85
|
}
|
|
86
86
|
/**
|
|
87
87
|
* toolCallIds whose paired toolResult is an accepted receipt (`isError === false`).
|
|
@@ -176,7 +176,7 @@ function extractAllAcceptedGateToolCalls(rows) {
|
|
|
176
176
|
}
|
|
177
177
|
return out;
|
|
178
178
|
}
|
|
179
|
-
function projectAcceptedGateCall(filePath, rows, call) {
|
|
179
|
+
function projectAcceptedGateCall(filePath, rows, call, pointerOfficer) {
|
|
180
180
|
// Continuous memory volumes carry many summons; span only this binding's interval.
|
|
181
181
|
const span = requireAcceptedGateSpan(intervalRowsForGateCall(rows, call.rowIndex), filePath);
|
|
182
182
|
const status = readAcceptedGateStatus(call.args);
|
|
@@ -208,7 +208,9 @@ function projectAcceptedGateCall(filePath, rows, call) {
|
|
|
208
208
|
...bindingFields,
|
|
209
209
|
};
|
|
210
210
|
}
|
|
211
|
-
const officer =
|
|
211
|
+
const officer = call.toolName === "ak_submission_output"
|
|
212
|
+
? pointerOfficer
|
|
213
|
+
: OFFICER_TOOL_TO_FACE[call.toolName];
|
|
212
214
|
if (officer === undefined) {
|
|
213
215
|
// isGateTerminatingToolName already screened; keep loud if tables drift.
|
|
214
216
|
throw new Error(`accepted gate receipt has unknown officer tool ${call.toolName} in ${filePath}`);
|
|
@@ -225,7 +227,7 @@ function projectAcceptedGateCall(filePath, rows, call) {
|
|
|
225
227
|
...bindingFields,
|
|
226
228
|
};
|
|
227
229
|
}
|
|
228
|
-
async function classifyAuditorVolume(filePath) {
|
|
230
|
+
async function classifyAuditorVolume(filePath, pointerOfficer) {
|
|
229
231
|
// Canonical JSONL errors propagate — failure honesty (never wash to fewer rounds).
|
|
230
232
|
const rows = await readLedgerSessionJsonl(filePath);
|
|
231
233
|
const accepted = extractAllAcceptedGateToolCalls(rows);
|
|
@@ -234,7 +236,9 @@ async function classifyAuditorVolume(filePath) {
|
|
|
234
236
|
return [];
|
|
235
237
|
const volumes = [];
|
|
236
238
|
for (const call of accepted) {
|
|
237
|
-
const projected =
|
|
239
|
+
const projected = call.toolName === "ak_submission_output" && pointerOfficer === undefined
|
|
240
|
+
? undefined // Shared tool alone carries no officer identity; a typed pointer does.
|
|
241
|
+
: projectAcceptedGateCall(filePath, rows, call, pointerOfficer);
|
|
238
242
|
if (projected !== undefined)
|
|
239
243
|
volumes.push(projected);
|
|
240
244
|
}
|
|
@@ -330,7 +334,9 @@ async function resolveOfficerSessionFromPointerFile(pointerPath) {
|
|
|
330
334
|
if (typeof sessionFile !== "string" || sessionFile.trim() === "") {
|
|
331
335
|
throw new Error(`direct officer run pointer missing sessionFile in ${pointerPath}`);
|
|
332
336
|
}
|
|
333
|
-
|
|
337
|
+
const officer = raw.officer === "inspector" || raw.officer === "notary"
|
|
338
|
+
? raw.officer : undefined;
|
|
339
|
+
return { sessionFile, ...(officer === undefined ? {} : { officer }) };
|
|
334
340
|
}
|
|
335
341
|
/**
|
|
336
342
|
* Read and pair gate-cycle rounds from one or more auditor-roles directories.
|
|
@@ -368,17 +374,16 @@ export async function readAnalystGateCyclesFromAuditorRoles(auditorRolesDirector
|
|
|
368
374
|
for (const name of names) {
|
|
369
375
|
const path = join(directory, name);
|
|
370
376
|
const fromPointer = name.endsWith(".pointer.json");
|
|
371
|
-
const
|
|
377
|
+
const pointer = fromPointer
|
|
372
378
|
? await resolveOfficerSessionFromPointerFile(path)
|
|
373
|
-
:
|
|
374
|
-
|
|
375
|
-
continue;
|
|
379
|
+
: undefined;
|
|
380
|
+
const sessionPath = pointer?.sessionFile ?? path;
|
|
376
381
|
if (fromPointer) {
|
|
377
382
|
if (classifiedOfficerSessions.has(sessionPath))
|
|
378
383
|
continue;
|
|
379
384
|
classifiedOfficerSessions.add(sessionPath);
|
|
380
385
|
}
|
|
381
|
-
const classified = await classifyAuditorVolume(sessionPath);
|
|
386
|
+
const classified = await classifyAuditorVolume(sessionPath, pointer?.officer);
|
|
382
387
|
for (const volume of classified) {
|
|
383
388
|
if (options.parentSessionFile !== undefined &&
|
|
384
389
|
volume.parentSessionFile !== undefined &&
|
|
@@ -31,9 +31,9 @@ function emptyAccum() {
|
|
|
31
31
|
function absorbRound(accum, round) {
|
|
32
32
|
accum.rounds += 1;
|
|
33
33
|
accum.wallSum += round.officerWallMs;
|
|
34
|
-
if (round.status === "bounce")
|
|
34
|
+
if (round.status === "bounce" || round.status === "continue")
|
|
35
35
|
accum.bounceCount += 1;
|
|
36
|
-
if (round.status === "pass")
|
|
36
|
+
if (round.status === "pass" || round.status === "converged")
|
|
37
37
|
accum.passCount += 1;
|
|
38
38
|
}
|
|
39
39
|
function finishOfficer(officer, accum) {
|
package/dist/audit-escalation.js
CHANGED
|
@@ -89,8 +89,8 @@ export function isAuditEscalationResult(value) {
|
|
|
89
89
|
*/
|
|
90
90
|
export async function disposeComplianceDecision(decision, handlers, deliveredOutput) {
|
|
91
91
|
switch (decision.status) {
|
|
92
|
-
case "
|
|
93
|
-
return await handlers.
|
|
92
|
+
case "converged":
|
|
93
|
+
return await handlers.converged(decision.usage);
|
|
94
94
|
case "no-receipt":
|
|
95
95
|
// The parent candidate remains accepted, but its parallel audit leg is a
|
|
96
96
|
// public typed fact and must not be collapsed into an ordinary pass.
|
|
@@ -104,8 +104,8 @@ export async function disposeComplianceDecision(decision, handlers, deliveredOut
|
|
|
104
104
|
throw new Error("Compliance received projection handler is unavailable");
|
|
105
105
|
}
|
|
106
106
|
return await handlers.received(decision, decision.usage === undefined ? {} : { usage: decision.usage });
|
|
107
|
-
case "
|
|
108
|
-
return await handlers.
|
|
107
|
+
case "continue":
|
|
108
|
+
return await handlers.continue(decision.violations);
|
|
109
109
|
case "escalate":
|
|
110
110
|
return await handlers.escalate(projectAuditEscalation(decision, deliveredOutput));
|
|
111
111
|
case "transport_failure":
|
|
@@ -21,8 +21,8 @@ function tryReadComplianceCandidate(arguments_, usage) {
|
|
|
21
21
|
}
|
|
22
22
|
const args = arguments_;
|
|
23
23
|
const status = args.status;
|
|
24
|
-
if (status === "
|
|
25
|
-
if (status === "
|
|
24
|
+
if (status === "converged") return { status, receipt: arguments_, ...usage === void 0 ? {} : { usage } };
|
|
25
|
+
if (status === "continue") return { status, violations: readListField(args.violations), receipt: arguments_, ...usage === void 0 ? {} : { usage } };
|
|
26
26
|
if (status === "escalate") {
|
|
27
27
|
return {
|
|
28
28
|
status,
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
import { REVIEW_SUBMISSION_OUTPUT_TOOL_NAME } from "./review-submission.js";
|
|
2
|
+
const COUNTERSIGN_OUTPUT_TOOL_NAME = REVIEW_SUBMISSION_OUTPUT_TOOL_NAME;
|
|
2
3
|
function validateRecordedCountersignOutput(verdict) {
|
|
3
4
|
if (verdict === null || typeof verdict !== "object" || Array.isArray(verdict)) {
|
|
4
5
|
throw new Error("Countersign verdict has no execution discriminator");
|
|
5
6
|
}
|
|
6
|
-
let
|
|
7
|
+
let status;
|
|
7
8
|
try {
|
|
8
|
-
|
|
9
|
+
status = verdict.status;
|
|
9
10
|
} catch {
|
|
10
11
|
throw new Error("Countersign verdict has no execution discriminator");
|
|
11
12
|
}
|
|
12
|
-
if (typeof
|
|
13
|
+
if (typeof status !== "string") {
|
|
13
14
|
throw new Error("Countersign verdict has no execution discriminator");
|
|
14
15
|
}
|
|
15
|
-
if (["converged", "continue", "escalate"].includes(
|
|
16
|
+
if (["converged", "continue", "escalate"].includes(status)) {
|
|
16
17
|
return verdict;
|
|
17
18
|
}
|
|
18
19
|
throw new Error("Countersign verdict has no execution discriminator");
|
package/dist/doctor-evidence.js
CHANGED
|
@@ -59,6 +59,8 @@ function deriveSession(content, id) {
|
|
|
59
59
|
let accepted, observedCommit, turns = 0, calls = 0, tokens = 0;
|
|
60
60
|
const statuses = [], commits = [];
|
|
61
61
|
for (const row of rows) {
|
|
62
|
+
if (row.type === "custom" && row.customType === "ak-role-submission-closure" && record(row.data) && row.data.isError === false && typeof row.data.toolName === "string" && isTerminatingToolName(row.data.toolName))
|
|
63
|
+
accepted = row;
|
|
62
64
|
const message = record(row.message) ? row.message : undefined;
|
|
63
65
|
if (message?.role === "assistant") {
|
|
64
66
|
for (const part of Array.isArray(message.content) ? message.content : [])
|
|
@@ -81,7 +83,6 @@ function deriveSession(content, id) {
|
|
|
81
83
|
continue;
|
|
82
84
|
throw error;
|
|
83
85
|
}
|
|
84
|
-
accepted = row;
|
|
85
86
|
const facts = acceptedFacts(message.toolName, details);
|
|
86
87
|
if (facts.commit && facts.commit !== observedCommit) {
|
|
87
88
|
commits.push({ source: id, commit: facts.commit });
|
package/dist/gatekeeper-role.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { auditorRunDirectory } from "./auditor-dossier-tool.js";
|
|
2
|
-
import {
|
|
2
|
+
import { packagedGateStageLabel } from "./packaged-role-registry.js";
|
|
3
3
|
import { GatekeeperDecisionError } from "./submission-errors.js";
|
|
4
4
|
import { INSPECTOR_OUTPUT_TOOL_NAME } from "./inspector-contracts.js";
|
|
5
|
+
import { REVIEW_SUBMISSION_OUTPUT_TOOL_NAME } from "./review-submission.js";
|
|
5
6
|
import { GATEKEEPER_OUTPUT_TOOL_NAME, gatekeeperDecisionSchema, gatekeeperOutputSchema, } from "./package-contracts/gatekeeper-output.js";
|
|
6
7
|
import { runIdFromRunDirectory } from "./run-terminal-artifacts.js";
|
|
7
8
|
export const INSPECTOR_OUTPUT_TOOL = INSPECTOR_OUTPUT_TOOL_NAME;
|
|
8
|
-
export const NOTARY_OUTPUT_TOOL =
|
|
9
|
+
export const NOTARY_OUTPUT_TOOL = REVIEW_SUBMISSION_OUTPUT_TOOL_NAME;
|
|
9
10
|
function gateSeatLabel(stage) {
|
|
10
11
|
return packagedGateStageLabel(stage) ?? stage;
|
|
11
12
|
}
|
|
@@ -67,17 +68,17 @@ function readRecord(value) {
|
|
|
67
68
|
}
|
|
68
69
|
/**
|
|
69
70
|
* Read only the conclusion field for queueing (#753).
|
|
70
|
-
*
|
|
71
|
+
* converged | continue | escalate → queue signal + raw receipt.
|
|
71
72
|
* Anything else accepted → needs_reask (resume speaker), never unreadable/parent-stand.
|
|
72
73
|
* `fallbackStatus` is the terminal outcome.status when the receipt body has no status key
|
|
73
74
|
* (keeps missing-args sentinel intact as the receipt).
|
|
74
75
|
*/
|
|
75
|
-
/** Map
|
|
76
|
-
function
|
|
76
|
+
/** Map the shared review verdict onto the gate queue words (#1028). */
|
|
77
|
+
function reviewQueueStatus(status) {
|
|
77
78
|
if (status === "converged")
|
|
78
|
-
return "
|
|
79
|
+
return "converged";
|
|
79
80
|
if (status === "continue")
|
|
80
|
-
return "
|
|
81
|
+
return "continue";
|
|
81
82
|
if (status === "escalate")
|
|
82
83
|
return "escalate";
|
|
83
84
|
return undefined;
|
|
@@ -85,31 +86,14 @@ function gateStatusFromCountersign(status) {
|
|
|
85
86
|
function projectOfficerDecision(officer, decision, fallbackStatus) {
|
|
86
87
|
const receipt = retainedReceipt(decision);
|
|
87
88
|
const record = readRecord(decision);
|
|
88
|
-
// 给事中: only countersignStatus, strict three-word map; never generic status,
|
|
89
|
-
// never unmapped raw word, never fallbackStatus (#969 / ADR 0040/0055).
|
|
90
|
-
if (packagedGateDecision(officer) === "countersign-status") {
|
|
91
|
-
const countersignStatus = record !== undefined && typeof record.countersignStatus === "string"
|
|
92
|
-
? record.countersignStatus
|
|
93
|
-
: undefined;
|
|
94
|
-
const status = typeof countersignStatus === "string"
|
|
95
|
-
? gateStatusFromCountersign(countersignStatus)
|
|
96
|
-
: undefined;
|
|
97
|
-
if (status === "pass") {
|
|
98
|
-
return { status: "pass", officer, receipt };
|
|
99
|
-
}
|
|
100
|
-
if (status === "bounce" || status === "escalate") {
|
|
101
|
-
return { status, officer, receipt };
|
|
102
|
-
}
|
|
103
|
-
return { status: "needs_reask", officer, receipt };
|
|
104
|
-
}
|
|
105
|
-
// inspector / notary / auditor: shared gate words on generic status.
|
|
106
89
|
const status = (record !== undefined && typeof record.status === "string" ? record.status : undefined)
|
|
107
90
|
?? fallbackStatus;
|
|
108
|
-
|
|
109
|
-
|
|
91
|
+
const queueStatus = typeof status === "string" ? reviewQueueStatus(status) : undefined;
|
|
92
|
+
if (queueStatus === "converged") {
|
|
93
|
+
return { status: "converged", officer, receipt };
|
|
110
94
|
}
|
|
111
|
-
if (
|
|
112
|
-
return { status, officer, receipt };
|
|
95
|
+
if (queueStatus === "continue" || queueStatus === "escalate") {
|
|
96
|
+
return { status: queueStatus, officer, receipt };
|
|
113
97
|
}
|
|
114
98
|
return { status: "needs_reask", officer, receipt };
|
|
115
99
|
}
|
|
@@ -161,8 +145,8 @@ export function officerRunIdFromSummoned(summoned) {
|
|
|
161
145
|
return undefined;
|
|
162
146
|
}
|
|
163
147
|
function withOfficerRunId(result, summoned) {
|
|
164
|
-
if (result.status !== "
|
|
165
|
-
&& result.status !== "
|
|
148
|
+
if (result.status !== "converged"
|
|
149
|
+
&& result.status !== "continue"
|
|
166
150
|
&& result.status !== "escalate"
|
|
167
151
|
&& result.status !== "needs_reask") {
|
|
168
152
|
return result;
|
|
@@ -233,23 +217,18 @@ function projectOfficerTerminal(officer, summoned) {
|
|
|
233
217
|
}, summoned);
|
|
234
218
|
}
|
|
235
219
|
/**
|
|
236
|
-
* Plain-language re-ask when the officer conclusion is not
|
|
220
|
+
* Plain-language re-ask when the officer conclusion is not converged|continue|escalate.
|
|
237
221
|
* Not a packaged engine handbook line (#755 exception for 读不出三态).
|
|
238
|
-
*
|
|
239
|
-
* field and words so reask does not invite non-contract values (#969 / ADR 0055).
|
|
222
|
+
* Every review officer uses the same `status` field and three queue words (#1028).
|
|
240
223
|
*/
|
|
241
|
-
export const OFFICER_CONCLUSION_REASK = "
|
|
242
|
-
/** 给事中 re-ask: countersignStatus converged|continue|escalate only (#969). */
|
|
243
|
-
export const COUNTERSIGN_CONCLUSION_REASK = "上次交卷的 countersignStatus 不是 converged、continue、escalate 三态之一。请重新输出,countersignStatus 写明其一;封驳或上呈的话就是给对方看的原文。";
|
|
224
|
+
export const OFFICER_CONCLUSION_REASK = "上次交卷的 status 不是 converged、continue、escalate 三态之一。请重新输出,status 写明其一;continue 或 escalate 的话就是给对方看的原文。";
|
|
244
225
|
/** Pick the re-ask line for the officer under review. */
|
|
245
226
|
export function officerConclusionReask(officer) {
|
|
246
|
-
return
|
|
247
|
-
? COUNTERSIGN_CONCLUSION_REASK
|
|
248
|
-
: OFFICER_CONCLUSION_REASK;
|
|
227
|
+
return OFFICER_CONCLUSION_REASK;
|
|
249
228
|
}
|
|
250
229
|
/**
|
|
251
230
|
* Summon (via injected seam) + project. Default summonGateOfficer drive lives
|
|
252
|
-
* on the shared envelope (`
|
|
231
|
+
* on the shared envelope (`submission-gate.ts`, ADR 0018 / #675) —
|
|
253
232
|
* role module keeps projection only.
|
|
254
233
|
*/
|
|
255
234
|
export async function projectGatekeeperRun(options) {
|