@akagilnc/pi-workflow-roles 0.1.3716 → 0.1.3722
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 +53 -35
- package/dist/auditor-dossier-tool.js +15 -9
- package/dist/gatekeeper-role.js +13 -10
- package/dist/public-cli/inspector-run.js +2 -2
- package/dist/public-cli/instruction-seat-run.js +1 -1
- package/dist/public-cli/main.js +1 -0
- package/dist/public-cli/notary-run.js +2 -2
- package/dist/public-role-summons.js +10 -6
- package/package.json +1 -1
- package/souls/countersign.md +8 -11
- package/src/auditor-dossier-tool.ts +26 -14
- package/src/gatekeeper-role.ts +32 -12
- package/src/public-cli/inspector-run.ts +3 -3
- package/src/public-cli/instruction-seat-run.ts +2 -2
- package/src/public-cli/notary-run.ts +3 -3
- package/src/public-role-summons.ts +26 -14
|
@@ -502,6 +502,19 @@ var init_collector_github = __esm({
|
|
|
502
502
|
}
|
|
503
503
|
});
|
|
504
504
|
|
|
505
|
+
// src/readable-gate-item.ts
|
|
506
|
+
function readableGateItem(value) {
|
|
507
|
+
return typeof value === "string" ? value : JSON.stringify(value);
|
|
508
|
+
}
|
|
509
|
+
function joinReadableGateItems(items, separator = "; ") {
|
|
510
|
+
return items.map(readableGateItem).join(separator);
|
|
511
|
+
}
|
|
512
|
+
var init_readable_gate_item = __esm({
|
|
513
|
+
"src/readable-gate-item.ts"() {
|
|
514
|
+
"use strict";
|
|
515
|
+
}
|
|
516
|
+
});
|
|
517
|
+
|
|
505
518
|
// src/auditor-dossier-tool.ts
|
|
506
519
|
var auditor_dossier_tool_exports = {};
|
|
507
520
|
__export(auditor_dossier_tool_exports, {
|
|
@@ -512,6 +525,7 @@ __export(auditor_dossier_tool_exports, {
|
|
|
512
525
|
createAuditorDossierTool: () => createAuditorDossierTool,
|
|
513
526
|
gateSubmissionCandidatePath: () => gateSubmissionCandidatePath,
|
|
514
527
|
persistGateSubmissionCandidate: () => persistGateSubmissionCandidate,
|
|
528
|
+
readLatestSubmissionArguments: () => readLatestSubmissionArguments,
|
|
515
529
|
readLatestToolCallLeaf: () => readLatestToolCallLeaf
|
|
516
530
|
});
|
|
517
531
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
@@ -543,16 +557,20 @@ function readLatestToolCallLeaf(context) {
|
|
|
543
557
|
function gateSubmissionCandidatePath(runDirectory) {
|
|
544
558
|
return join(runDirectory, "artifacts", GATE_SUBMISSION_CANDIDATE_FILE);
|
|
545
559
|
}
|
|
546
|
-
function
|
|
547
|
-
const
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
];
|
|
551
|
-
const candidate = input.submissionCandidatePath?.trim();
|
|
552
|
-
if (candidate !== void 0 && candidate.length > 0) {
|
|
553
|
-
lines.push(`\u4EA4\u5377\u5019\u9009\uFF08\u51BB\u7ED3\u5FEB\u7167\uFF09\uFF1A${candidate}`);
|
|
560
|
+
function readLatestSubmissionArguments(context) {
|
|
561
|
+
const leaf = readLatestToolCallLeaf(context);
|
|
562
|
+
if (!isRecord2(leaf) || !isRecord2(leaf.message) || !Array.isArray(leaf.message.content)) {
|
|
563
|
+
return void 0;
|
|
554
564
|
}
|
|
555
|
-
|
|
565
|
+
for (const part of leaf.message.content) {
|
|
566
|
+
if (isRecord2(part) && part.type === "toolCall" && "arguments" in part) {
|
|
567
|
+
return part.arguments;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
return void 0;
|
|
571
|
+
}
|
|
572
|
+
function buildGateOfficerReviewInstruction(input) {
|
|
573
|
+
return readableGateItem(input.submission);
|
|
556
574
|
}
|
|
557
575
|
function persistGateSubmissionCandidate(runDirectory, context) {
|
|
558
576
|
const leaf = readLatestToolCallLeaf(context);
|
|
@@ -596,6 +614,7 @@ var AUDITOR_DOSSIER_TOOL_NAME, GATE_SUBMISSION_CANDIDATE_FILE;
|
|
|
596
614
|
var init_auditor_dossier_tool = __esm({
|
|
597
615
|
"src/auditor-dossier-tool.ts"() {
|
|
598
616
|
"use strict";
|
|
617
|
+
init_readable_gate_item();
|
|
599
618
|
AUDITOR_DOSSIER_TOOL_NAME = "ak_get_run_dossier";
|
|
600
619
|
GATE_SUBMISSION_CANDIDATE_FILE = "gate-submission-candidate.json";
|
|
601
620
|
}
|
|
@@ -2235,19 +2254,6 @@ var init_reviewer_output = __esm({
|
|
|
2235
2254
|
}
|
|
2236
2255
|
});
|
|
2237
2256
|
|
|
2238
|
-
// src/readable-gate-item.ts
|
|
2239
|
-
function readableGateItem(value) {
|
|
2240
|
-
return typeof value === "string" ? value : JSON.stringify(value);
|
|
2241
|
-
}
|
|
2242
|
-
function joinReadableGateItems(items, separator = "; ") {
|
|
2243
|
-
return items.map(readableGateItem).join(separator);
|
|
2244
|
-
}
|
|
2245
|
-
var init_readable_gate_item = __esm({
|
|
2246
|
-
"src/readable-gate-item.ts"() {
|
|
2247
|
-
"use strict";
|
|
2248
|
-
}
|
|
2249
|
-
});
|
|
2250
|
-
|
|
2251
2257
|
// src/audit-escalation.ts
|
|
2252
2258
|
function buildAuditEscalationResult(decision, deliveredOutput) {
|
|
2253
2259
|
const auditOwned = {
|
|
@@ -16929,8 +16935,11 @@ async function summonPublicRole(options) {
|
|
|
16929
16935
|
...options.signal === void 0 ? {} : { signal: options.signal },
|
|
16930
16936
|
// #753: reask rides the existing notary same-ticket resume summons.instruction.
|
|
16931
16937
|
...options.reviewReask === void 0 ? {} : { reviewReask: options.reviewReask },
|
|
16932
|
-
// #
|
|
16933
|
-
...options.gateReviewInstruction === void 0 ? {} : { gateReviewInstruction: options.gateReviewInstruction }
|
|
16938
|
+
// #786: verbatim submission body on same-parent resume (not conclusion re-ask).
|
|
16939
|
+
...options.gateReviewInstruction === void 0 ? {} : { gateReviewInstruction: options.gateReviewInstruction },
|
|
16940
|
+
// Offline test injects — same faces as public CLI env (production leaves unset).
|
|
16941
|
+
...options.roleTurnHost === void 0 ? {} : { roleTurnHost: options.roleTurnHost },
|
|
16942
|
+
...options.createRunId === void 0 ? {} : { createRunId: options.createRunId }
|
|
16934
16943
|
};
|
|
16935
16944
|
const captured = options.io === void 0 ? createCapturingIo() : void 0;
|
|
16936
16945
|
const io = options.io ?? captured.io;
|
|
@@ -17027,11 +17036,10 @@ async function summonGateOfficer(options) {
|
|
|
17027
17036
|
home = homeFromRunDirectory2(options.sourceRunDirectory);
|
|
17028
17037
|
}
|
|
17029
17038
|
let gateReviewInstruction;
|
|
17030
|
-
if (options.reask === void 0) {
|
|
17039
|
+
if (options.reask === void 0 && options.submission !== void 0) {
|
|
17031
17040
|
const { buildGateOfficerReviewInstruction: buildGateOfficerReviewInstruction2 } = await Promise.resolve().then(() => (init_auditor_dossier_tool(), auditor_dossier_tool_exports));
|
|
17032
17041
|
gateReviewInstruction = buildGateOfficerReviewInstruction2({
|
|
17033
|
-
|
|
17034
|
-
...options.submissionCandidatePath === void 0 ? {} : { submissionCandidatePath: options.submissionCandidatePath }
|
|
17042
|
+
submission: options.submission
|
|
17035
17043
|
});
|
|
17036
17044
|
}
|
|
17037
17045
|
const common = {
|
|
@@ -17041,7 +17049,9 @@ async function summonGateOfficer(options) {
|
|
|
17041
17049
|
...options.io === void 0 ? {} : { io: options.io },
|
|
17042
17050
|
...options.signal === void 0 ? {} : { signal: options.signal },
|
|
17043
17051
|
...options.reask === void 0 ? {} : { reviewReask: options.reask },
|
|
17044
|
-
...gateReviewInstruction === void 0 ? {} : { gateReviewInstruction }
|
|
17052
|
+
...gateReviewInstruction === void 0 ? {} : { gateReviewInstruction },
|
|
17053
|
+
...options.roleTurnHost === void 0 ? {} : { roleTurnHost: options.roleTurnHost },
|
|
17054
|
+
...options.createRunId === void 0 ? {} : { createRunId: options.createRunId }
|
|
17045
17055
|
};
|
|
17046
17056
|
if (options.officer === "notary") {
|
|
17047
17057
|
return summonPublicRole({
|
|
@@ -18670,13 +18680,11 @@ async function projectGatekeeperRun(options) {
|
|
|
18670
18680
|
}
|
|
18671
18681
|
};
|
|
18672
18682
|
}
|
|
18673
|
-
|
|
18674
|
-
|
|
18675
|
-
options.context
|
|
18676
|
-
);
|
|
18683
|
+
persistGateSubmissionCandidate(runDirectory, options.context);
|
|
18684
|
+
const submission = readLatestSubmissionArguments(options.context);
|
|
18677
18685
|
let summoned;
|
|
18678
18686
|
try {
|
|
18679
|
-
const summon = options.summonOfficer ?? (async (nextOfficer, sourceRunDirectory, officerSignal, reask) => {
|
|
18687
|
+
const summon = options.summonOfficer ?? (async (nextOfficer, sourceRunDirectory, officerSignal, reask, nextSubmission) => {
|
|
18680
18688
|
const { summonGateOfficer: summonGateOfficer2 } = await Promise.resolve().then(() => (init_public_role_summons(), public_role_summons_exports));
|
|
18681
18689
|
return summonGateOfficer2({
|
|
18682
18690
|
officer: nextOfficer,
|
|
@@ -18684,10 +18692,20 @@ async function projectGatekeeperRun(options) {
|
|
|
18684
18692
|
cwd: options.context.cwd ?? process.cwd(),
|
|
18685
18693
|
...officerSignal === void 0 ? {} : { signal: officerSignal },
|
|
18686
18694
|
...reask === void 0 ? {} : { reask },
|
|
18687
|
-
...
|
|
18695
|
+
...nextSubmission === void 0 ? {} : { submission: nextSubmission },
|
|
18696
|
+
...options.home === void 0 ? {} : { home: options.home },
|
|
18697
|
+
...options.packageRoot === void 0 ? {} : { packageRoot: options.packageRoot },
|
|
18698
|
+
...options.roleTurnHost === void 0 ? {} : { roleTurnHost: options.roleTurnHost },
|
|
18699
|
+
...options.createRunId === void 0 ? {} : { createRunId: options.createRunId }
|
|
18688
18700
|
});
|
|
18689
18701
|
});
|
|
18690
|
-
summoned = await summon(
|
|
18702
|
+
summoned = await summon(
|
|
18703
|
+
officer,
|
|
18704
|
+
runDirectory,
|
|
18705
|
+
options.signal,
|
|
18706
|
+
options.reask,
|
|
18707
|
+
submission
|
|
18708
|
+
);
|
|
18691
18709
|
} catch (error) {
|
|
18692
18710
|
return {
|
|
18693
18711
|
officer,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
import { readableGateItem } from "./readable-gate-item.js";
|
|
3
4
|
import { Type } from "typebox";
|
|
4
5
|
const AUDITOR_DOSSIER_TOOL_NAME = "ak_get_run_dossier";
|
|
5
6
|
const GATE_SUBMISSION_CANDIDATE_FILE = "gate-submission-candidate.json";
|
|
@@ -29,16 +30,20 @@ function readLatestToolCallLeaf(context) {
|
|
|
29
30
|
function gateSubmissionCandidatePath(runDirectory) {
|
|
30
31
|
return join(runDirectory, "artifacts", GATE_SUBMISSION_CANDIDATE_FILE);
|
|
31
32
|
}
|
|
32
|
-
function
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
function readLatestSubmissionArguments(context) {
|
|
34
|
+
const leaf = readLatestToolCallLeaf(context);
|
|
35
|
+
if (!isRecord(leaf) || !isRecord(leaf.message) || !Array.isArray(leaf.message.content)) {
|
|
36
|
+
return void 0;
|
|
37
|
+
}
|
|
38
|
+
for (const part of leaf.message.content) {
|
|
39
|
+
if (isRecord(part) && part.type === "toolCall" && "arguments" in part) {
|
|
40
|
+
return part.arguments;
|
|
41
|
+
}
|
|
40
42
|
}
|
|
41
|
-
return
|
|
43
|
+
return void 0;
|
|
44
|
+
}
|
|
45
|
+
function buildGateOfficerReviewInstruction(input) {
|
|
46
|
+
return readableGateItem(input.submission);
|
|
42
47
|
}
|
|
43
48
|
function persistGateSubmissionCandidate(runDirectory, context) {
|
|
44
49
|
const leaf = readLatestToolCallLeaf(context);
|
|
@@ -86,5 +91,6 @@ export {
|
|
|
86
91
|
createAuditorDossierTool,
|
|
87
92
|
gateSubmissionCandidatePath,
|
|
88
93
|
persistGateSubmissionCandidate,
|
|
94
|
+
readLatestSubmissionArguments,
|
|
89
95
|
readLatestToolCallLeaf
|
|
90
96
|
};
|
package/dist/gatekeeper-role.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { auditorRunDirectory, persistGateSubmissionCandidate, } from "./auditor-dossier-tool.js";
|
|
1
|
+
import { auditorRunDirectory, persistGateSubmissionCandidate, readLatestSubmissionArguments, } from "./auditor-dossier-tool.js";
|
|
2
2
|
import { GatekeeperDecisionError } from "./submission-errors.js";
|
|
3
3
|
import { INSPECTOR_OUTPUT_TOOL_NAME } from "./inspector-contracts.js";
|
|
4
4
|
import { GATEKEEPER_OUTPUT_TOOL_NAME, gatekeeperDecisionSchema, gatekeeperOutputSchema, } from "./package-contracts/gatekeeper-output.js";
|
|
@@ -173,14 +173,15 @@ export async function projectGatekeeperRun(options) {
|
|
|
173
173
|
},
|
|
174
174
|
};
|
|
175
175
|
}
|
|
176
|
-
//
|
|
177
|
-
//
|
|
178
|
-
//
|
|
179
|
-
|
|
176
|
+
// #632: Grok session.jsonl is header-only — freeze the in-memory tool-call leaf
|
|
177
|
+
// as a run artifact so dossier exploration still resolves. LLM→LLM resume does
|
|
178
|
+
// not ride this path: submission body goes verbatim on gateReviewInstruction (#786).
|
|
179
|
+
persistGateSubmissionCandidate(runDirectory, options.context);
|
|
180
|
+
const submission = readLatestSubmissionArguments(options.context);
|
|
180
181
|
let summoned;
|
|
181
182
|
try {
|
|
182
183
|
const summon = options.summonOfficer
|
|
183
|
-
?? (async (nextOfficer, sourceRunDirectory, officerSignal, reask) => {
|
|
184
|
+
?? (async (nextOfficer, sourceRunDirectory, officerSignal, reask, nextSubmission) => {
|
|
184
185
|
const { summonGateOfficer } = await import("./public-role-summons.js");
|
|
185
186
|
return summonGateOfficer({
|
|
186
187
|
officer: nextOfficer,
|
|
@@ -188,12 +189,14 @@ export async function projectGatekeeperRun(options) {
|
|
|
188
189
|
cwd: options.context.cwd ?? process.cwd(),
|
|
189
190
|
...(officerSignal === undefined ? {} : { signal: officerSignal }),
|
|
190
191
|
...(reask === undefined ? {} : { reask }),
|
|
191
|
-
...(
|
|
192
|
-
|
|
193
|
-
|
|
192
|
+
...(nextSubmission === undefined ? {} : { submission: nextSubmission }),
|
|
193
|
+
...(options.home === undefined ? {} : { home: options.home }),
|
|
194
|
+
...(options.packageRoot === undefined ? {} : { packageRoot: options.packageRoot }),
|
|
195
|
+
...(options.roleTurnHost === undefined ? {} : { roleTurnHost: options.roleTurnHost }),
|
|
196
|
+
...(options.createRunId === undefined ? {} : { createRunId: options.createRunId }),
|
|
194
197
|
});
|
|
195
198
|
});
|
|
196
|
-
summoned = await summon(officer, runDirectory, options.signal, options.reask);
|
|
199
|
+
summoned = await summon(officer, runDirectory, options.signal, options.reask, submission);
|
|
197
200
|
}
|
|
198
201
|
catch (error) {
|
|
199
202
|
return {
|
|
@@ -31,7 +31,7 @@ export async function runPublicInspector(argv, env, io, parseInspectorArgv) {
|
|
|
31
31
|
// No bare catch→fresh: lookup/resume failures surface; only true absence mints new.
|
|
32
32
|
const projectRoot = parsed.project ?? env.cwd;
|
|
33
33
|
// #747: parentRunPath is the pure 卷宗指针 path only — never reask/materials text.
|
|
34
|
-
// #753: gate re-ask /
|
|
34
|
+
// #753/#786: gate re-ask / verbatim submission body ride summons.instruction on resume.
|
|
35
35
|
const parentRunPath = parentRunPathFromGatePointerInstruction(parsed.instruction);
|
|
36
36
|
if (parentRunPath !== undefined) {
|
|
37
37
|
const resumeInstruction = env.reviewReask ?? env.gateReviewInstruction;
|
|
@@ -57,7 +57,7 @@ export async function runPublicInspector(argv, env, io, parseInspectorArgv) {
|
|
|
57
57
|
return resumed;
|
|
58
58
|
// Reask without a prior same-parent run cannot deliver the plain-language ask
|
|
59
59
|
// on a fresh mint without inventing a second prompt path — fail loud (#753).
|
|
60
|
-
// gateReviewInstruction alone is resume-only; fresh mint keeps argv 卷宗指针.
|
|
60
|
+
// gateReviewInstruction (verbatim body) alone is resume-only; fresh mint keeps argv 卷宗指针.
|
|
61
61
|
if (env.reviewReask !== undefined) {
|
|
62
62
|
presentStructuralRejection(new CliUsageError("inspector review reask requires a prior same-parent run to resume"), io);
|
|
63
63
|
return { exitCode: 2 };
|
|
@@ -150,7 +150,7 @@ export async function runPublicInstructionSeat(argv, env, io, role, parseArgv) {
|
|
|
150
150
|
return { exitCode: 2 };
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
|
-
// #756: auditor reask /
|
|
153
|
+
// #756/#786: auditor reask / verbatim submission body ride summons.instruction on resume.
|
|
154
154
|
const resumeInstruction = env.reviewReask ?? env.gateReviewInstruction;
|
|
155
155
|
const summons = {
|
|
156
156
|
...(resumeInstruction === undefined
|
package/dist/public-cli/main.js
CHANGED
|
@@ -21973,6 +21973,7 @@ var init_method_skill = __esm({
|
|
|
21973
21973
|
var init_auditor_dossier_tool = __esm({
|
|
21974
21974
|
"src/auditor-dossier-tool.ts"() {
|
|
21975
21975
|
"use strict";
|
|
21976
|
+
init_readable_gate_item();
|
|
21976
21977
|
init_build();
|
|
21977
21978
|
}
|
|
21978
21979
|
});
|
|
@@ -52,7 +52,7 @@ export async function runPublicNotary(argv, env, io, parseNotaryArgv) {
|
|
|
52
52
|
throw error;
|
|
53
53
|
}
|
|
54
54
|
// #747: officer resume key is this parent source-run path (not ticket number).
|
|
55
|
-
// #753: gate re-ask and
|
|
55
|
+
// #753/#786: gate re-ask and verbatim submission body share summons.instruction
|
|
56
56
|
// (reask wins when both present; no parallel stack).
|
|
57
57
|
{
|
|
58
58
|
const resumeInstruction = env.reviewReask ?? env.gateReviewInstruction;
|
|
@@ -76,7 +76,7 @@ export async function runPublicNotary(argv, env, io, parseNotaryArgv) {
|
|
|
76
76
|
return resumed;
|
|
77
77
|
// Reask without a prior same-parent run cannot deliver the plain-language ask
|
|
78
78
|
// on a fresh mint without inventing a second prompt path — fail loud (#753).
|
|
79
|
-
// gateReviewInstruction alone is resume-only
|
|
79
|
+
// gateReviewInstruction (verbatim body) alone is resume-only; fresh mint ignores it.
|
|
80
80
|
if (env.reviewReask !== undefined) {
|
|
81
81
|
presentStructuralRejection(new CliUsageError("notary review reask requires a prior same-parent run to resume"), io);
|
|
82
82
|
return { exitCode: 2 };
|
|
@@ -165,8 +165,11 @@ async function summonPublicRole(options) {
|
|
|
165
165
|
...options.signal === void 0 ? {} : { signal: options.signal },
|
|
166
166
|
// #753: reask rides the existing notary same-ticket resume summons.instruction.
|
|
167
167
|
...options.reviewReask === void 0 ? {} : { reviewReask: options.reviewReask },
|
|
168
|
-
// #
|
|
169
|
-
...options.gateReviewInstruction === void 0 ? {} : { gateReviewInstruction: options.gateReviewInstruction }
|
|
168
|
+
// #786: verbatim submission body on same-parent resume (not conclusion re-ask).
|
|
169
|
+
...options.gateReviewInstruction === void 0 ? {} : { gateReviewInstruction: options.gateReviewInstruction },
|
|
170
|
+
// Offline test injects — same faces as public CLI env (production leaves unset).
|
|
171
|
+
...options.roleTurnHost === void 0 ? {} : { roleTurnHost: options.roleTurnHost },
|
|
172
|
+
...options.createRunId === void 0 ? {} : { createRunId: options.createRunId }
|
|
170
173
|
};
|
|
171
174
|
const captured = options.io === void 0 ? createCapturingIo() : void 0;
|
|
172
175
|
const io = options.io ?? captured.io;
|
|
@@ -263,11 +266,10 @@ async function summonGateOfficer(options) {
|
|
|
263
266
|
home = homeFromRunDirectory(options.sourceRunDirectory);
|
|
264
267
|
}
|
|
265
268
|
let gateReviewInstruction;
|
|
266
|
-
if (options.reask === void 0) {
|
|
269
|
+
if (options.reask === void 0 && options.submission !== void 0) {
|
|
267
270
|
const { buildGateOfficerReviewInstruction } = await import("./auditor-dossier-tool.js");
|
|
268
271
|
gateReviewInstruction = buildGateOfficerReviewInstruction({
|
|
269
|
-
|
|
270
|
-
...options.submissionCandidatePath === void 0 ? {} : { submissionCandidatePath: options.submissionCandidatePath }
|
|
272
|
+
submission: options.submission
|
|
271
273
|
});
|
|
272
274
|
}
|
|
273
275
|
const common = {
|
|
@@ -277,7 +279,9 @@ async function summonGateOfficer(options) {
|
|
|
277
279
|
...options.io === void 0 ? {} : { io: options.io },
|
|
278
280
|
...options.signal === void 0 ? {} : { signal: options.signal },
|
|
279
281
|
...options.reask === void 0 ? {} : { reviewReask: options.reask },
|
|
280
|
-
...gateReviewInstruction === void 0 ? {} : { gateReviewInstruction }
|
|
282
|
+
...gateReviewInstruction === void 0 ? {} : { gateReviewInstruction },
|
|
283
|
+
...options.roleTurnHost === void 0 ? {} : { roleTurnHost: options.roleTurnHost },
|
|
284
|
+
...options.createRunId === void 0 ? {} : { createRunId: options.createRunId }
|
|
281
285
|
};
|
|
282
286
|
if (options.officer === "notary") {
|
|
283
287
|
return summonPublicRole({
|
package/package.json
CHANGED
package/souls/countersign.md
CHANGED
|
@@ -5,16 +5,15 @@
|
|
|
5
5
|
|
|
6
6
|
## 审读步骤
|
|
7
7
|
|
|
8
|
-
**一、立法。**
|
|
9
|
-
1
|
|
10
|
-
2 第一法源立法(最高法):该票起居录与陛下原话,全局宪法;
|
|
11
|
-
3 第二发源立法:
|
|
12
|
-
适用 ADR——由你自行检索,按票面触及的席位、接缝、术语在 docs/adr 与 CONTEXT.md 查全,票面引没引都算——并逐键列出其决策键;仓级 CLAUDE.md、质量法、审刑院法典;
|
|
13
|
-
既有契约:CONTEXT.md 词表、被改动接缝的现行行为、相关票与在飞分支。
|
|
8
|
+
**一、立法。** 先为本票立「适用法」;后面每一步对着它问,未立法不得往下走。适用法三部分:
|
|
9
|
+
1 第一法源立法(最高法):该票起居录,全局宪法,仓内治理文件;
|
|
14
10
|
|
|
15
|
-
|
|
11
|
+
2 第二发源立法:
|
|
12
|
+
适用 ADR——由你自行检索,按票面触及的席位、接缝、术语在 docs/adr 与 CONTEXT.md 查全,票面引没引都算——并逐键列出其决策键;质量法、审刑院法典;
|
|
16
13
|
|
|
17
|
-
|
|
14
|
+
3 第二法源合法性检查:判断第二法源 以及 输入的 prombt等 对比第一法源是否有超出或不足,曲解。如有,除非有陛下原话批准,否则直接封驳 要求改正或陛下批准。
|
|
15
|
+
|
|
16
|
+
**二、相抵。** 票面,相关票与在飞分支与法源有无抵触。
|
|
18
17
|
|
|
19
18
|
**三、缺失。** 法源要求的,票面有没有漏:适用 ADR 未被引用即缺失,引用须写 `docs/adr/...md` 路径;ADR 每个决策键须有落点或明写「由 #x 承接」;验收面须覆盖票面每条主张;前置产物、决定、答复须在;承重主张的源头不存在、不支持、已过时,同为缺失。
|
|
20
19
|
|
|
@@ -39,9 +38,7 @@
|
|
|
39
38
|
|
|
40
39
|
- 署(converged)——四步无碍、五问皆有据可答,具备开工资格;
|
|
41
40
|
- 封驳(continue)——存在必须退回重议的问题;写明退给谁、缺什么、属哪一步;
|
|
42
|
-
- 上呈(escalate
|
|
41
|
+
- 上呈(escalate)——无法正常暑/封驳时。上呈求助
|
|
43
42
|
|
|
44
43
|
|
|
45
44
|
主张必须附证据或法的具体条目。finding 提类别,同类一次说全(审刑院法典·审官纪律)。
|
|
46
|
-
|
|
47
|
-
交卷后由符宝郎内闸核旨。无法解决的上抛陛下。
|
|
@@ -3,6 +3,7 @@ import { dirname, join, resolve } from "node:path";
|
|
|
3
3
|
|
|
4
4
|
import type { AgentToolResult, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
5
5
|
import type { HostContext } from "./host-contracts.ts";
|
|
6
|
+
import { readableGateItem } from "./readable-gate-item.ts";
|
|
6
7
|
import { Type } from "typebox";
|
|
7
8
|
|
|
8
9
|
export const AUDITOR_DOSSIER_TOOL_NAME = "ak_get_run_dossier" as const;
|
|
@@ -63,24 +64,35 @@ export function gateSubmissionCandidatePath(runDirectory: string): string {
|
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
/**
|
|
66
|
-
*
|
|
67
|
-
*
|
|
67
|
+
* Arguments of the latest assistant toolCall leaf — the in-flight 交卷 body.
|
|
68
|
+
* Transport assembly only: does not interpret field contents (#786).
|
|
69
|
+
*/
|
|
70
|
+
export function readLatestSubmissionArguments(
|
|
71
|
+
context: GateSubmissionSessionContext,
|
|
72
|
+
): unknown | undefined {
|
|
73
|
+
const leaf = readLatestToolCallLeaf(context);
|
|
74
|
+
if (!isRecord(leaf) || !isRecord(leaf.message) || !Array.isArray(leaf.message.content)) {
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
for (const part of leaf.message.content) {
|
|
78
|
+
if (isRecord(part) && part.type === "toolCall" && "arguments" in part) {
|
|
79
|
+
return part.arguments;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Verbatim parent-submission body for gate-officer same-parent resume (#786).
|
|
68
87
|
* Three pairs share this face: countersign↔notary, judge↔auditor, worker↔inspector.
|
|
69
|
-
* Code
|
|
88
|
+
* Code relays bytes; it does not parse, judge, or rewrite the submission.
|
|
89
|
+
* Symmetric with bounce direction (officer receipt → parent via readableGateItem).
|
|
90
|
+
* No path/pointer substitute — argv 卷宗指针 stays on the code-summons face (ADR 0079).
|
|
70
91
|
*/
|
|
71
92
|
export function buildGateOfficerReviewInstruction(input: {
|
|
72
|
-
readonly
|
|
73
|
-
readonly submissionCandidatePath?: string;
|
|
93
|
+
readonly submission: unknown;
|
|
74
94
|
}): string {
|
|
75
|
-
|
|
76
|
-
"本轮父席交卷待审。",
|
|
77
|
-
`来源 run:${input.sourceRunDirectory}`,
|
|
78
|
-
];
|
|
79
|
-
const candidate = input.submissionCandidatePath?.trim();
|
|
80
|
-
if (candidate !== undefined && candidate.length > 0) {
|
|
81
|
-
lines.push(`交卷候选(冻结快照):${candidate}`);
|
|
82
|
-
}
|
|
83
|
-
return lines.join("\n");
|
|
95
|
+
return readableGateItem(input.submission);
|
|
84
96
|
}
|
|
85
97
|
|
|
86
98
|
/**
|
package/src/gatekeeper-role.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { HostContext } from "./host-contracts.ts";
|
|
|
4
4
|
import {
|
|
5
5
|
auditorRunDirectory,
|
|
6
6
|
persistGateSubmissionCandidate,
|
|
7
|
+
readLatestSubmissionArguments,
|
|
7
8
|
} from "./auditor-dossier-tool.ts";
|
|
8
9
|
import type { NoReceiptLifecycleFacts } from "./receipt-delivery-policy.ts";
|
|
9
10
|
import { GatekeeperDecisionError } from "./submission-errors.ts";
|
|
@@ -89,6 +90,11 @@ export type GateOfficerSummon = (
|
|
|
89
90
|
* conclusion (#753 / #756). Hosted as same-ticket resume instruction.
|
|
90
91
|
*/
|
|
91
92
|
reask?: string,
|
|
93
|
+
/**
|
|
94
|
+
* In-flight parent 交卷 body (tool-call arguments). Production default relays
|
|
95
|
+
* it verbatim on same-parent officer resume (#786).
|
|
96
|
+
*/
|
|
97
|
+
submission?: unknown,
|
|
92
98
|
) => Promise<PublicSummonResult>;
|
|
93
99
|
|
|
94
100
|
export type RunGatekeeperOptions = {
|
|
@@ -106,6 +112,14 @@ export type RunGatekeeperOptions = {
|
|
|
106
112
|
* activation path (#675); inject only in offline tracers.
|
|
107
113
|
*/
|
|
108
114
|
readonly summonOfficer?: GateOfficerSummon;
|
|
115
|
+
/**
|
|
116
|
+
* Offline test injects forwarded through the production default summonGateOfficer
|
|
117
|
+
* path (same faces as public CLI). Production leaves these unset.
|
|
118
|
+
*/
|
|
119
|
+
readonly home?: string;
|
|
120
|
+
readonly packageRoot?: string;
|
|
121
|
+
readonly roleTurnHost?: import("./host-contracts.ts").RoleTurnHost;
|
|
122
|
+
readonly createRunId?: () => string;
|
|
109
123
|
};
|
|
110
124
|
|
|
111
125
|
export type GatekeeperPassHostActions = {
|
|
@@ -299,18 +313,16 @@ export async function projectGatekeeperRun(
|
|
|
299
313
|
},
|
|
300
314
|
};
|
|
301
315
|
}
|
|
302
|
-
//
|
|
303
|
-
//
|
|
304
|
-
//
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
options.context,
|
|
308
|
-
);
|
|
316
|
+
// #632: Grok session.jsonl is header-only — freeze the in-memory tool-call leaf
|
|
317
|
+
// as a run artifact so dossier exploration still resolves. LLM→LLM resume does
|
|
318
|
+
// not ride this path: submission body goes verbatim on gateReviewInstruction (#786).
|
|
319
|
+
persistGateSubmissionCandidate(runDirectory, options.context);
|
|
320
|
+
const submission = readLatestSubmissionArguments(options.context);
|
|
309
321
|
let summoned: PublicSummonResult;
|
|
310
322
|
try {
|
|
311
323
|
const summon =
|
|
312
324
|
options.summonOfficer
|
|
313
|
-
?? (async (nextOfficer, sourceRunDirectory, officerSignal, reask) => {
|
|
325
|
+
?? (async (nextOfficer, sourceRunDirectory, officerSignal, reask, nextSubmission) => {
|
|
314
326
|
const { summonGateOfficer } = await import("./public-role-summons.ts");
|
|
315
327
|
return summonGateOfficer({
|
|
316
328
|
officer: nextOfficer,
|
|
@@ -318,12 +330,20 @@ export async function projectGatekeeperRun(
|
|
|
318
330
|
cwd: options.context.cwd ?? process.cwd(),
|
|
319
331
|
...(officerSignal === undefined ? {} : { signal: officerSignal }),
|
|
320
332
|
...(reask === undefined ? {} : { reask }),
|
|
321
|
-
...(
|
|
322
|
-
|
|
323
|
-
|
|
333
|
+
...(nextSubmission === undefined ? {} : { submission: nextSubmission }),
|
|
334
|
+
...(options.home === undefined ? {} : { home: options.home }),
|
|
335
|
+
...(options.packageRoot === undefined ? {} : { packageRoot: options.packageRoot }),
|
|
336
|
+
...(options.roleTurnHost === undefined ? {} : { roleTurnHost: options.roleTurnHost }),
|
|
337
|
+
...(options.createRunId === undefined ? {} : { createRunId: options.createRunId }),
|
|
324
338
|
});
|
|
325
339
|
});
|
|
326
|
-
summoned = await summon(
|
|
340
|
+
summoned = await summon(
|
|
341
|
+
officer,
|
|
342
|
+
runDirectory,
|
|
343
|
+
options.signal,
|
|
344
|
+
options.reask,
|
|
345
|
+
submission,
|
|
346
|
+
);
|
|
327
347
|
} catch (error) {
|
|
328
348
|
return {
|
|
329
349
|
officer,
|
|
@@ -51,7 +51,7 @@ export type InspectorRunEnv = PostAdmissionEnv & {
|
|
|
51
51
|
*/
|
|
52
52
|
reviewReask?: string;
|
|
53
53
|
/**
|
|
54
|
-
* #
|
|
54
|
+
* #786 same-parent re-summons: verbatim parent-submission body.
|
|
55
55
|
* Rides summons.instruction when reviewReask is absent. Fresh mint keeps argv 卷宗指针.
|
|
56
56
|
*/
|
|
57
57
|
gateReviewInstruction?: string;
|
|
@@ -99,7 +99,7 @@ export async function runPublicInspector(
|
|
|
99
99
|
// No bare catch→fresh: lookup/resume failures surface; only true absence mints new.
|
|
100
100
|
const projectRoot = parsed.project ?? env.cwd;
|
|
101
101
|
// #747: parentRunPath is the pure 卷宗指针 path only — never reask/materials text.
|
|
102
|
-
// #753: gate re-ask /
|
|
102
|
+
// #753/#786: gate re-ask / verbatim submission body ride summons.instruction on resume.
|
|
103
103
|
const parentRunPath = parentRunPathFromGatePointerInstruction(parsed.instruction);
|
|
104
104
|
if (parentRunPath !== undefined) {
|
|
105
105
|
const resumeInstruction = env.reviewReask ?? env.gateReviewInstruction;
|
|
@@ -129,7 +129,7 @@ export async function runPublicInspector(
|
|
|
129
129
|
if (resumed !== undefined) return resumed;
|
|
130
130
|
// Reask without a prior same-parent run cannot deliver the plain-language ask
|
|
131
131
|
// on a fresh mint without inventing a second prompt path — fail loud (#753).
|
|
132
|
-
// gateReviewInstruction alone is resume-only; fresh mint keeps argv 卷宗指针.
|
|
132
|
+
// gateReviewInstruction (verbatim body) alone is resume-only; fresh mint keeps argv 卷宗指针.
|
|
133
133
|
if (env.reviewReask !== undefined) {
|
|
134
134
|
presentStructuralRejection(
|
|
135
135
|
new CliUsageError(
|
|
@@ -70,7 +70,7 @@ export type InstructionSeatRunEnv = PostAdmissionEnv & {
|
|
|
70
70
|
*/
|
|
71
71
|
reviewReask?: string;
|
|
72
72
|
/**
|
|
73
|
-
* #
|
|
73
|
+
* #786 same-parent re-summons: verbatim parent-submission body.
|
|
74
74
|
* Rides summons.instruction when reviewReask is absent. Fresh mint keeps argv instruction.
|
|
75
75
|
*/
|
|
76
76
|
gateReviewInstruction?: string;
|
|
@@ -294,7 +294,7 @@ export async function runPublicInstructionSeat(
|
|
|
294
294
|
}
|
|
295
295
|
}
|
|
296
296
|
|
|
297
|
-
// #756: auditor reask /
|
|
297
|
+
// #756/#786: auditor reask / verbatim submission body ride summons.instruction on resume.
|
|
298
298
|
const resumeInstruction = env.reviewReask ?? env.gateReviewInstruction;
|
|
299
299
|
const summons: SameTicketSummonsMaterials = {
|
|
300
300
|
...(resumeInstruction === undefined
|
|
@@ -53,7 +53,7 @@ export type NotaryRunEnv = PostAdmissionEnv & {
|
|
|
53
53
|
*/
|
|
54
54
|
reviewReask?: string;
|
|
55
55
|
/**
|
|
56
|
-
* #
|
|
56
|
+
* #786 same-parent re-summons: verbatim parent-submission body.
|
|
57
57
|
* Rides summons.instruction when reviewReask is absent. Fresh mint ignores it.
|
|
58
58
|
*/
|
|
59
59
|
gateReviewInstruction?: string;
|
|
@@ -120,7 +120,7 @@ export async function runPublicNotary(
|
|
|
120
120
|
throw error;
|
|
121
121
|
}
|
|
122
122
|
// #747: officer resume key is this parent source-run path (not ticket number).
|
|
123
|
-
// #753: gate re-ask and
|
|
123
|
+
// #753/#786: gate re-ask and verbatim submission body share summons.instruction
|
|
124
124
|
// (reask wins when both present; no parallel stack).
|
|
125
125
|
{
|
|
126
126
|
const resumeInstruction = env.reviewReask ?? env.gateReviewInstruction;
|
|
@@ -148,7 +148,7 @@ export async function runPublicNotary(
|
|
|
148
148
|
if (resumed !== undefined) return resumed;
|
|
149
149
|
// Reask without a prior same-parent run cannot deliver the plain-language ask
|
|
150
150
|
// on a fresh mint without inventing a second prompt path — fail loud (#753).
|
|
151
|
-
// gateReviewInstruction alone is resume-only
|
|
151
|
+
// gateReviewInstruction (verbatim body) alone is resume-only; fresh mint ignores it.
|
|
152
152
|
if (env.reviewReask !== undefined) {
|
|
153
153
|
presentStructuralRejection(
|
|
154
154
|
new CliUsageError(
|
|
@@ -60,12 +60,18 @@ export type PublicSummonRequest = {
|
|
|
60
60
|
*/
|
|
61
61
|
readonly reviewReask?: string;
|
|
62
62
|
/**
|
|
63
|
-
* #
|
|
64
|
-
* new parent submission (source run + optional gate-submission-candidate).
|
|
63
|
+
* #786 same-parent re-summons: verbatim parent-submission body for the gate officer.
|
|
65
64
|
* Rides summons.instruction when reviewReask is absent. Fresh mint ignores it.
|
|
66
|
-
* Never folded into argv / parent-run lookup keys.
|
|
65
|
+
* Never folded into argv / parent-run lookup keys (ADR 0079 卷宗指针 stays pure).
|
|
67
66
|
*/
|
|
68
67
|
readonly gateReviewInstruction?: string;
|
|
68
|
+
/**
|
|
69
|
+
* Offline test inject — same face as public CLI env.roleTurnHost. Production
|
|
70
|
+
* summons leave this unset and use the seat-resolved host.
|
|
71
|
+
*/
|
|
72
|
+
readonly roleTurnHost?: RoleTurnHost;
|
|
73
|
+
/** Offline test inject for deterministic run ids (same face as public CLI). */
|
|
74
|
+
readonly createRunId?: () => string;
|
|
69
75
|
};
|
|
70
76
|
|
|
71
77
|
export type PublicSummonResult = {
|
|
@@ -293,10 +299,13 @@ export async function summonPublicRole(
|
|
|
293
299
|
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
294
300
|
// #753: reask rides the existing notary same-ticket resume summons.instruction.
|
|
295
301
|
...(options.reviewReask === undefined ? {} : { reviewReask: options.reviewReask }),
|
|
296
|
-
// #
|
|
302
|
+
// #786: verbatim submission body on same-parent resume (not conclusion re-ask).
|
|
297
303
|
...(options.gateReviewInstruction === undefined
|
|
298
304
|
? {}
|
|
299
305
|
: { gateReviewInstruction: options.gateReviewInstruction }),
|
|
306
|
+
// Offline test injects — same faces as public CLI env (production leaves unset).
|
|
307
|
+
...(options.roleTurnHost === undefined ? {} : { roleTurnHost: options.roleTurnHost }),
|
|
308
|
+
...(options.createRunId === undefined ? {} : { createRunId: options.createRunId }),
|
|
300
309
|
};
|
|
301
310
|
const captured = options.io === undefined ? createCapturingIo() : undefined;
|
|
302
311
|
const io = options.io ?? captured!.io;
|
|
@@ -412,10 +421,14 @@ export async function summonGateOfficer(options: {
|
|
|
412
421
|
*/
|
|
413
422
|
readonly reask?: string;
|
|
414
423
|
/**
|
|
415
|
-
*
|
|
416
|
-
*
|
|
424
|
+
* In-flight parent 交卷 body (tool-call arguments). Relayed verbatim on resume
|
|
425
|
+
* when reask is absent (#786). Never a path pointer substitute.
|
|
417
426
|
*/
|
|
418
|
-
readonly
|
|
427
|
+
readonly submission?: unknown;
|
|
428
|
+
/** Offline test inject — forwarded to summonPublicRole. */
|
|
429
|
+
readonly roleTurnHost?: RoleTurnHost;
|
|
430
|
+
/** Offline test inject — forwarded to summonPublicRole. */
|
|
431
|
+
readonly createRunId?: () => string;
|
|
419
432
|
}): Promise<PublicSummonResult> {
|
|
420
433
|
let home = options.home;
|
|
421
434
|
if (home === undefined) {
|
|
@@ -423,16 +436,13 @@ export async function summonGateOfficer(options: {
|
|
|
423
436
|
// Hard path resolve: fail loud — never fall through to packageMachineHome (#604 / #675).
|
|
424
437
|
home = homeFromRunDirectory(options.sourceRunDirectory);
|
|
425
438
|
}
|
|
426
|
-
// Conclusion re-ask keeps sole ownership of reviewReask. New-submission
|
|
427
|
-
//
|
|
439
|
+
// Conclusion re-ask keeps sole ownership of reviewReask. New-submission body
|
|
440
|
+
// rides a separate field so first mint never fails the "reask requires prior" gate.
|
|
428
441
|
let gateReviewInstruction: string | undefined;
|
|
429
|
-
if (options.reask === undefined) {
|
|
442
|
+
if (options.reask === undefined && options.submission !== undefined) {
|
|
430
443
|
const { buildGateOfficerReviewInstruction } = await import("./auditor-dossier-tool.ts");
|
|
431
444
|
gateReviewInstruction = buildGateOfficerReviewInstruction({
|
|
432
|
-
|
|
433
|
-
...(options.submissionCandidatePath === undefined
|
|
434
|
-
? {}
|
|
435
|
-
: { submissionCandidatePath: options.submissionCandidatePath }),
|
|
445
|
+
submission: options.submission,
|
|
436
446
|
});
|
|
437
447
|
}
|
|
438
448
|
const common = {
|
|
@@ -445,6 +455,8 @@ export async function summonGateOfficer(options: {
|
|
|
445
455
|
...(gateReviewInstruction === undefined
|
|
446
456
|
? {}
|
|
447
457
|
: { gateReviewInstruction }),
|
|
458
|
+
...(options.roleTurnHost === undefined ? {} : { roleTurnHost: options.roleTurnHost }),
|
|
459
|
+
...(options.createRunId === undefined ? {} : { createRunId: options.createRunId }),
|
|
448
460
|
} as const;
|
|
449
461
|
if (options.officer === "notary") {
|
|
450
462
|
// #753: reask rides summonPublicRole → runPublicNotary summons.instruction
|