@akagilnc/pi-workflow-roles 0.1.5593 → 0.1.5614
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 +1 -1
- package/README.zh-CN.md +1 -1
- package/dist/acp-host/production-host.js +521 -707
- package/dist/compliance-transport.js +2 -5
- package/dist/doctor-auditor.js +1 -1
- package/dist/gatekeeper-role.js +1 -1
- package/dist/headless-host/production-host.js +505 -691
- package/dist/merger-contracts.js +6 -2
- package/dist/migrate-book-topology.js +5142 -10735
- package/dist/navigator-public-session.js +4 -4
- package/dist/navigator-work-base.js +5 -30
- package/dist/package-contracts/worker-output.js +1 -6
- package/dist/packaged-role-registry.js +9 -6
- package/dist/pi/role-turn-host.js +10 -1
- package/dist/public-cli/instruction-seat-run.js +133 -38
- package/dist/public-cli/invocation.js +38 -74
- package/dist/public-cli/main.js +18155 -18235
- package/dist/public-cli/option-definitions.js +21 -2
- package/dist/public-cli/post-admission.js +25 -24
- package/dist/public-cli/run-lifecycle.js +4 -43
- package/dist/public-cli/turn-request.js +4 -9
- package/dist/public-role-summons.js +5 -3
- package/dist/role-run-placement.js +7 -1
- package/dist/role-run-relocation.js +3 -4
- package/package.json +1 -1
- package/scripts/build-package.mjs +2 -4
- package/src/audited-run-identity.ts +30 -0
- package/src/compliance-transport.ts +1 -4
- package/src/doctor-auditor.ts +1 -1
- package/src/gatekeeper-role.ts +1 -1
- package/src/host-contracts.ts +6 -4
- package/src/merger-contracts.ts +6 -2
- package/src/merger-role.ts +11 -1
- package/src/navigator-attendance.ts +2 -2
- package/src/navigator-public-session.ts +9 -5
- package/src/navigator-work-base.ts +19 -34
- package/src/notary-role.ts +12 -21
- package/src/package-contracts/worker-output.ts +0 -8
- package/src/packaged-role-registry.ts +8 -7
- package/src/pi/role-turn-host.ts +11 -1
- package/src/public-cli/instruction-seat-run.ts +162 -42
- package/src/public-cli/invocation.ts +55 -93
- package/src/public-cli/option-definitions.ts +22 -2
- package/src/public-cli/post-admission.ts +30 -24
- package/src/public-cli/run-lifecycle.ts +4 -56
- package/src/public-cli/turn-request.ts +9 -8
- package/src/public-role-summons.ts +17 -6
- package/src/role-envelope.ts +4 -0
- package/src/role-run-placement.ts +10 -1
- package/src/role-run-relocation.ts +3 -4
- package/src/role-runtime-dependencies.ts +0 -2
- package/src/role-runtime.ts +54 -47
- package/src/worker-role.ts +11 -78
- package/dist/auditor-dossier-tool.js +0 -47
- package/dist/package-contracts/fixer-packet.js +0 -77
- package/packets/fixer-prerequisites.json +0 -6
- package/src/auditor-dossier-tool.ts +0 -63
- package/src/package-contracts/fixer-packet.ts +0 -91
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Durable work subject and controlling authority for one navigator nest.
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Startup materials load these bytes from the nest session directory; the
|
|
4
|
+
* caller/summon prompt must not receive a package-injected path (#1166).
|
|
5
5
|
*/
|
|
6
6
|
import { existsSync, realpathSync } from "node:fs";
|
|
7
7
|
import { readFile } from "node:fs/promises";
|
|
@@ -12,6 +12,9 @@ import { isEnoent, isRecord } from "./unknown-value.ts";
|
|
|
12
12
|
|
|
13
13
|
export const NAVIGATOR_WORK_CONTEXT_BASENAME = "work-context.json";
|
|
14
14
|
|
|
15
|
+
/** Child-process / in-process locator for nest work-context bytes — not prompt material (#1166). */
|
|
16
|
+
export const AK_ROLE_NAVIGATOR_WORK_CONTEXT_ENV = "AK_ROLE_NAVIGATOR_WORK_CONTEXT" as const;
|
|
17
|
+
|
|
15
18
|
export type NavigatorWorkBase = {
|
|
16
19
|
readonly subject: string;
|
|
17
20
|
readonly authority: string;
|
|
@@ -81,38 +84,20 @@ export async function readNavigatorWorkBase(path: string): Promise<NavigatorWork
|
|
|
81
84
|
return { subject: record.subject, authority: record.authority };
|
|
82
85
|
}
|
|
83
86
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const path = record?.workContextPath;
|
|
99
|
-
if (typeof path !== "string" || path.trim() === "") return undefined;
|
|
100
|
-
return isNavigatorWorkContextFile(path) ? path : undefined;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/** Settlement JSON gains the nest pointer. Non-JSON prompts stay unchanged. */
|
|
104
|
-
export function attachWorkContextPointer(text: string, workContextPath: string): string {
|
|
105
|
-
const record = jsonObjectFromPrompt(text);
|
|
106
|
-
if (record === undefined) return text;
|
|
107
|
-
if (typeof record.workContextPath === "string" && record.workContextPath.trim() !== "") return text;
|
|
108
|
-
const head = text.trimStart().split("\n\n", 1)[0] ?? "";
|
|
109
|
-
const rest = text.trimStart().slice(head.length);
|
|
110
|
-
return `${JSON.stringify({ ...record, workContextPath })}${rest}`;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/** System-prompt base for one agent start. Absent or unreadable file yields undefined. */
|
|
114
|
-
export async function loadNavigatorWorkBaseSuffix(prompt: string): Promise<string | undefined> {
|
|
115
|
-
const path = workContextPathFromPrompt(prompt);
|
|
87
|
+
/** System-prompt base for one agent start. Prefer request locator, else nest session dir. */
|
|
88
|
+
export async function loadNavigatorWorkBaseSuffix(
|
|
89
|
+
sessionDir: string | undefined,
|
|
90
|
+
locatorPath?: string,
|
|
91
|
+
): Promise<string | undefined> {
|
|
92
|
+
const path =
|
|
93
|
+
typeof locatorPath === "string" && locatorPath.trim() !== ""
|
|
94
|
+
? locatorPath.trim()
|
|
95
|
+
: typeof process.env[AK_ROLE_NAVIGATOR_WORK_CONTEXT_ENV] === "string"
|
|
96
|
+
&& process.env[AK_ROLE_NAVIGATOR_WORK_CONTEXT_ENV].trim() !== ""
|
|
97
|
+
? process.env[AK_ROLE_NAVIGATOR_WORK_CONTEXT_ENV].trim()
|
|
98
|
+
: sessionDir !== undefined && sessionDir.trim() !== ""
|
|
99
|
+
? navigatorWorkContextFile(sessionDir)
|
|
100
|
+
: undefined;
|
|
116
101
|
if (path === undefined) return undefined;
|
|
117
102
|
const body = await readNavigatorWorkBase(path);
|
|
118
103
|
if (body === undefined) return undefined;
|
package/src/notary-role.ts
CHANGED
|
@@ -9,6 +9,10 @@ import { isSafePositiveTicketNumber } from "./run-ticket-number.ts";
|
|
|
9
9
|
* This module keeps evidence assembly + projection only.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
+
import {
|
|
13
|
+
auditedRunIdentityFromParts,
|
|
14
|
+
auditedRunIdentityMaterial,
|
|
15
|
+
} from "./audited-run-identity.ts";
|
|
12
16
|
import {
|
|
13
17
|
NOTARY_OUTPUT_TOOL_NAME,
|
|
14
18
|
NOTARY_SOURCE_RUN_FLAG,
|
|
@@ -53,25 +57,15 @@ export function readNotaryTicketFlag(flag: unknown): number | undefined {
|
|
|
53
57
|
return n;
|
|
54
58
|
}
|
|
55
59
|
|
|
56
|
-
/**
|
|
57
|
-
|
|
58
|
-
* Sole production projection for agent-start material + session custom entry.
|
|
59
|
-
*/
|
|
60
|
-
export function projectNotarySessionBound(input: {
|
|
61
|
-
readonly sourceRun: NotarySourceRunLocator;
|
|
62
|
-
readonly ticketNumber?: number;
|
|
63
|
-
}): {
|
|
60
|
+
/** Agent-start reading material: identity `<runId>@<席>` only — no directory path. */
|
|
61
|
+
export function projectNotaryAuditedRunIdentity(input: {
|
|
64
62
|
readonly sourceRun: NotarySourceRunLocator;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
...(input.ticketNumber === undefined ? {} : { ticketNumber: input.ticketNumber }),
|
|
70
|
-
};
|
|
63
|
+
}) {
|
|
64
|
+
return auditedRunIdentityMaterial(
|
|
65
|
+
auditedRunIdentityFromParts(input.sourceRun.runId, input.sourceRun.role),
|
|
66
|
+
);
|
|
71
67
|
}
|
|
72
68
|
|
|
73
|
-
export type NotarySessionBound = ReturnType<typeof projectNotarySessionBound>;
|
|
74
|
-
|
|
75
69
|
/**
|
|
76
70
|
* Session custom-entry type for typed notary bound (written by shared envelope).
|
|
77
71
|
* Role module only projects; lifecycle write is envelope-owned (ADR 0018).
|
|
@@ -102,7 +96,7 @@ export function projectNotaryBoundFromFlags(
|
|
|
102
96
|
}
|
|
103
97
|
|
|
104
98
|
/** Assemble systemPrompt body from base + soul only (NO embedded bound JSON).
|
|
105
|
-
*
|
|
99
|
+
* Audited-run identity travels separately as `readingMaterial`; adapters fold
|
|
106
100
|
* it into the provider-visible prompt at the send boundary. */
|
|
107
101
|
export function assembleNotaryAgentStartPrompt(input: {
|
|
108
102
|
readonly baseSystemPrompt: string;
|
|
@@ -172,11 +166,8 @@ export function createNotaryRoleRuntime(
|
|
|
172
166
|
baseSystemPrompt: event.systemPrompt,
|
|
173
167
|
soul: activation.soul,
|
|
174
168
|
}),
|
|
175
|
-
readingMaterial:
|
|
169
|
+
readingMaterial: projectNotaryAuditedRunIdentity({
|
|
176
170
|
sourceRun: activation.sourceRun,
|
|
177
|
-
...(activation.ticketNumber === undefined
|
|
178
|
-
? {}
|
|
179
|
-
: { ticketNumber: activation.ticketNumber }),
|
|
180
171
|
}),
|
|
181
172
|
};
|
|
182
173
|
});
|
|
@@ -13,26 +13,18 @@ import {
|
|
|
13
13
|
type FixerOutput,
|
|
14
14
|
type FixerPhase,
|
|
15
15
|
} from "./fixer-output.ts";
|
|
16
|
-
import { fixerPrerequisiteSchema, fixerPrerequisitesSchema, parseFixerPrerequisites, validateFixerPrerequisites } from "./fixer-packet.ts";
|
|
17
|
-
import type { FixerInvocationInput, FixerPrerequisite } from "./fixer-packet.ts";
|
|
18
16
|
import { withTerminatingOutputDeclarations } from "./terminating-infrastructure.ts";
|
|
19
17
|
|
|
20
18
|
export {
|
|
21
19
|
FIXER_OUTPUT_TOOL_NAME,
|
|
22
20
|
fixerOutputSchema,
|
|
23
21
|
validateFixerOutput,
|
|
24
|
-
fixerPrerequisiteSchema,
|
|
25
|
-
fixerPrerequisitesSchema,
|
|
26
|
-
parseFixerPrerequisites,
|
|
27
|
-
validateFixerPrerequisites,
|
|
28
22
|
};
|
|
29
23
|
export type {
|
|
30
24
|
FixerBlocker,
|
|
31
25
|
FixerClassResult,
|
|
32
26
|
FixerOutput,
|
|
33
27
|
FixerPhase,
|
|
34
|
-
FixerInvocationInput,
|
|
35
|
-
FixerPrerequisite,
|
|
36
28
|
};
|
|
37
29
|
|
|
38
30
|
export const CODER_OUTPUT_TOOL_NAME = "ak_coder_output";
|
|
@@ -115,10 +115,10 @@ export const PUBLIC_ROLE_RECORDS = [
|
|
|
115
115
|
reportPhase: true,
|
|
116
116
|
},
|
|
117
117
|
boardPlacement: "marshal",
|
|
118
|
+
/** #1168: dispatch is first message; navigator reads admitted instruction. */
|
|
119
|
+
navigatorSubject: "public-instruction",
|
|
118
120
|
activationFlags: [
|
|
119
|
-
{ field: "packetPath", flag: "ak-fix-packet", binds: "input" },
|
|
120
121
|
{ field: "phase", flag: "ak-fixer-phase", binds: "phase" },
|
|
121
|
-
{ field: "prerequisitesPath", flag: "ak-fixer-prerequisites" },
|
|
122
122
|
],
|
|
123
123
|
activationStage: "load-and-install",
|
|
124
124
|
sessionMaterials: [
|
|
@@ -145,8 +145,9 @@ export const PUBLIC_ROLE_RECORDS = [
|
|
|
145
145
|
artifactFace: {
|
|
146
146
|
reportPhase: true,
|
|
147
147
|
},
|
|
148
|
+
/** #1168: dispatch is first message; navigator reads admitted instruction. */
|
|
149
|
+
navigatorSubject: "public-instruction",
|
|
148
150
|
activationFlags: [
|
|
149
|
-
{ field: "taskPath", flag: "ak-coder-task", binds: "input" },
|
|
150
151
|
{ field: "phase", flag: "ak-coder-phase", binds: "phase" },
|
|
151
152
|
],
|
|
152
153
|
activationStage: "load-and-install",
|
|
@@ -389,7 +390,8 @@ export const PUBLIC_ROLE_RECORDS = [
|
|
|
389
390
|
presentSettled: "always",
|
|
390
391
|
summonResume: false,
|
|
391
392
|
admission: "instruction",
|
|
392
|
-
|
|
393
|
+
/** Structured --source-run only; instruction stays opaque caller/peer bytes (#1166). */
|
|
394
|
+
sameParent: "source-run",
|
|
393
395
|
/** Resume restores an optional source-run path onto the admitted face. */
|
|
394
396
|
resumeSourcePath: true,
|
|
395
397
|
/** 台院 is a review officer and inherits the gatekeeper model. */
|
|
@@ -402,11 +404,12 @@ export const PUBLIC_ROLE_RECORDS = [
|
|
|
402
404
|
/** Court reask replaces the initial prompt. */
|
|
403
405
|
reaskPrompt: true,
|
|
404
406
|
gateStageLabel: "台院",
|
|
407
|
+
/** Gate summon binds --source-run; identity is startup material (#1166). */
|
|
408
|
+
gateSummon: "source-run",
|
|
405
409
|
activationFlags: [
|
|
406
410
|
{
|
|
407
411
|
field: "sourceRun",
|
|
408
412
|
from: "sourceRunPath",
|
|
409
|
-
fallback: "gate-pointer",
|
|
410
413
|
flag: "ak-inspector-source-run",
|
|
411
414
|
binds: "input",
|
|
412
415
|
},
|
|
@@ -553,7 +556,6 @@ export function packagedModelParent(role: string): PackagedRole | undefined {
|
|
|
553
556
|
* One seat's admitted → activation copy.
|
|
554
557
|
* `field` is the activation key. `from` is the admitted path when it differs.
|
|
555
558
|
* `text` writes a number as decimal text on the activation object.
|
|
556
|
-
* `fallback: "gate-pointer"` is the inspector instruction pointer when sourceRunPath is blank.
|
|
557
559
|
* `flag` omitted: the value stays on the activation object and is not a host flag
|
|
558
560
|
* (secretariat and countersign ticketNumber).
|
|
559
561
|
*/
|
|
@@ -561,7 +563,6 @@ export type PackagedActivationFlag = {
|
|
|
561
563
|
readonly field: string;
|
|
562
564
|
readonly from?: string;
|
|
563
565
|
readonly text?: true;
|
|
564
|
-
readonly fallback?: "gate-pointer";
|
|
565
566
|
readonly flag?: string;
|
|
566
567
|
readonly binds?: "input" | "phase";
|
|
567
568
|
};
|
package/src/pi/role-turn-host.ts
CHANGED
|
@@ -429,7 +429,7 @@ export function createPiRoleTurnHost(config: PiRoleTurnHostConfig): RoleTurnHost
|
|
|
429
429
|
if (request.deliveryRequestLimit === undefined) delete env[RECEIPT_DELIVERY_LIMIT_ENV];
|
|
430
430
|
else env[RECEIPT_DELIVERY_LIMIT_ENV] = String(request.deliveryRequestLimit);
|
|
431
431
|
applyEngineChildEnv(env, request.engine);
|
|
432
|
-
// Nested auditor
|
|
432
|
+
// Nested auditor binds the audited source-run for identity / soul selection.
|
|
433
433
|
if (
|
|
434
434
|
typeof process.env.AK_ROLE_AUDITOR_SOURCE_RUN === "string"
|
|
435
435
|
&& process.env.AK_ROLE_AUDITOR_SOURCE_RUN.trim() !== ""
|
|
@@ -443,6 +443,16 @@ export function createPiRoleTurnHost(config: PiRoleTurnHostConfig): RoleTurnHost
|
|
|
443
443
|
) {
|
|
444
444
|
env.AK_ROLE_AUDITOR_SUBJECT = process.env.AK_ROLE_AUDITOR_SUBJECT;
|
|
445
445
|
}
|
|
446
|
+
// Navigator nest work-context locator for startup materials (#1166) —
|
|
447
|
+
// child-process scoped only from this turn request; never parent process.env.
|
|
448
|
+
if (
|
|
449
|
+
typeof request.navigatorWorkContextPath === "string"
|
|
450
|
+
&& request.navigatorWorkContextPath.trim() !== ""
|
|
451
|
+
) {
|
|
452
|
+
env.AK_ROLE_NAVIGATOR_WORK_CONTEXT = request.navigatorWorkContextPath.trim();
|
|
453
|
+
} else {
|
|
454
|
+
delete env.AK_ROLE_NAVIGATOR_WORK_CONTEXT;
|
|
455
|
+
}
|
|
446
456
|
if (
|
|
447
457
|
config.recordLaunchedRolePackageIdentity !== undefined &&
|
|
448
458
|
config.observeLaunchedRolePackageIdentity !== undefined
|
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
* starts two ordinary single-axis runs here.
|
|
5
5
|
*/
|
|
6
6
|
import { dirname, resolve } from "node:path";
|
|
7
|
-
import { isUnboundRunDirectory } from "../role-run-placement.ts";
|
|
8
|
-
import { AUDITOR_DOSSIER_PROMPT } from "../compliance-transport.ts";
|
|
7
|
+
import { isUnboundRunDirectory, sessionFileOf } from "../role-run-placement.ts";
|
|
9
8
|
import { bookDirectOfficerRunPointer, readDirectOfficerRunPointer } from "../archivist-record-pointer.ts";
|
|
10
9
|
import { createPiDoctorAuditor } from "../doctor-auditor.ts";
|
|
11
10
|
|
|
@@ -42,6 +41,7 @@ import { CliUsageError } from "./cli-errors.ts";
|
|
|
42
41
|
import {
|
|
43
42
|
admitPublicRole,
|
|
44
43
|
bindAdmittedTicketNumber,
|
|
44
|
+
appendCallerFileFlagPaths,
|
|
45
45
|
buildInstructionTransportPrompt,
|
|
46
46
|
materializeCountersignInvocation,
|
|
47
47
|
persistAdmittedSourceRunPath,
|
|
@@ -72,7 +72,6 @@ import {
|
|
|
72
72
|
buildAutoResumeContinuationPrompt,
|
|
73
73
|
loadResumablePublicRole,
|
|
74
74
|
markRunAdmitted,
|
|
75
|
-
parentRunPathFromGatePointerInstruction,
|
|
76
75
|
readCurrentCourt,
|
|
77
76
|
type PublicResumeRequest,
|
|
78
77
|
type RunWriterLease,
|
|
@@ -291,14 +290,80 @@ export function buildInstructionSeatTurnRequest(
|
|
|
291
290
|
);
|
|
292
291
|
}
|
|
293
292
|
|
|
294
|
-
|
|
293
|
+
/**
|
|
294
|
+
* Direct review-seat call: reconnect ledger peer-body delivery (ADR 0085 / #1166).
|
|
295
|
+
* Gate summons already ride gateReviewInstruction; direct --source-run must not
|
|
296
|
+
* leave a blank fixed-kickoff.
|
|
297
|
+
*/
|
|
298
|
+
async function loadLedgerPeerBody(
|
|
299
|
+
sourceRunDirectory: string,
|
|
300
|
+
projectRoot: string,
|
|
301
|
+
home: string,
|
|
302
|
+
): Promise<string | undefined> {
|
|
303
|
+
const runId = runIdFromRunDirectory(sourceRunDirectory);
|
|
304
|
+
if (runId === undefined) return undefined;
|
|
305
|
+
// Bind to the already-resolved source directory — never re-discover by runId
|
|
306
|
+
// alone (another book may lawfully share the same id; #637 / #1166).
|
|
307
|
+
const rows = await readRecordedSubmissionRows(projectRoot, runId, {
|
|
308
|
+
home,
|
|
309
|
+
sessionParent: sessionFileOf(sourceRunDirectory),
|
|
310
|
+
});
|
|
311
|
+
// ADR 0085 / #1166 J10: ledger already keeps original words for every class —
|
|
312
|
+
// present the latest row as-is. Never filter current manuscript by accepted /
|
|
313
|
+
// terminal outcome kind (that resurrects a prior sealed draft).
|
|
314
|
+
const latest = rows.at(-1);
|
|
315
|
+
if (latest === undefined) return undefined;
|
|
316
|
+
return readableGateItem(latest.accepted);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* One delivery rule for review-seat dialogue on new turns and same-parent resume
|
|
321
|
+
* (#1166 / ADR 0085 / ADR 0087): explicit reask → non-empty caller dispatch →
|
|
322
|
+
* source-only ledger peer body. Identity stays in startup materials.
|
|
323
|
+
*/
|
|
324
|
+
async function resolveReviewSeatDialogueBody(input: {
|
|
325
|
+
readonly reask?: string;
|
|
326
|
+
readonly callerInstruction?: string;
|
|
327
|
+
readonly sourceRunPath?: string;
|
|
328
|
+
readonly projectRoot: string;
|
|
329
|
+
readonly home: string;
|
|
330
|
+
}): Promise<string | undefined> {
|
|
331
|
+
const reask = input.reask;
|
|
332
|
+
if (reask !== undefined && reask.length > 0) return reask;
|
|
333
|
+
const caller = input.callerInstruction ?? "";
|
|
334
|
+
if (caller.length > 0) return caller;
|
|
335
|
+
const sourceRunPath = input.sourceRunPath?.trim() ?? "";
|
|
336
|
+
if (sourceRunPath === "") return undefined;
|
|
337
|
+
return await loadLedgerPeerBody(sourceRunPath, input.projectRoot, input.home);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function admittedSourceRunPath(admitted: AdmittedRoleInvocation): string {
|
|
341
|
+
return "sourceRunPath" in admitted
|
|
342
|
+
&& typeof (admitted as { sourceRunPath?: unknown }).sourceRunPath === "string"
|
|
343
|
+
? (admitted as { sourceRunPath: string }).sourceRunPath.trim()
|
|
344
|
+
: "";
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
async function resolveInitialPrompt(
|
|
295
348
|
admitted: AdmittedRoleInvocation,
|
|
296
349
|
env: InstructionSeatRunEnv,
|
|
297
|
-
): string {
|
|
350
|
+
): Promise<string> {
|
|
298
351
|
const record = roleRecord(admitted.role);
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
352
|
+
if ("reaskPrompt" in record && record.reaskPrompt === true) {
|
|
353
|
+
const sourceRunPath = admittedSourceRunPath(admitted);
|
|
354
|
+
const reask = env.reviewReask ?? env.gateReviewInstruction;
|
|
355
|
+
const body = await resolveReviewSeatDialogueBody({
|
|
356
|
+
...(reask === undefined ? {} : { reask }),
|
|
357
|
+
callerInstruction: admitted.instruction,
|
|
358
|
+
...(sourceRunPath === "" ? {} : { sourceRunPath }),
|
|
359
|
+
projectRoot: admitted.projectRoot,
|
|
360
|
+
home: env.home,
|
|
361
|
+
});
|
|
362
|
+
// #1166 J11: merge existing file-flag delivery — never early-return body alone
|
|
363
|
+
// when caller attach paths were admitted. Gate with no file flags stays body-only.
|
|
364
|
+
if (body !== undefined) {
|
|
365
|
+
return appendCallerFileFlagPaths(body, admitted.attachments);
|
|
366
|
+
}
|
|
302
367
|
}
|
|
303
368
|
return buildInstructionTransportPrompt(admitted);
|
|
304
369
|
}
|
|
@@ -417,6 +482,7 @@ async function dispatchAdmitted(
|
|
|
417
482
|
if (activeEnv.correlationId !== undefined && activeEnv.correlationId.trim() !== "") {
|
|
418
483
|
await recordAdmittedCorrelation(admitted, activeEnv.correlationId);
|
|
419
484
|
}
|
|
485
|
+
const initialPromptText = await resolveInitialPrompt(admitted, activeEnv);
|
|
420
486
|
const auto = "inCallAutoResume" in record && record.inCallAutoResume === true;
|
|
421
487
|
if (auto) {
|
|
422
488
|
return await runPostAdmissionResumable({
|
|
@@ -425,7 +491,10 @@ async function dispatchAdmitted(
|
|
|
425
491
|
io: turnIo,
|
|
426
492
|
buildInitialRequest: () => buildInstructionSeatTurnRequest(
|
|
427
493
|
admitted,
|
|
428
|
-
roleTurnOptions(activeEnv, admitted, {
|
|
494
|
+
roleTurnOptions(activeEnv, admitted, {
|
|
495
|
+
kind: "initial",
|
|
496
|
+
prompt: initialPromptText,
|
|
497
|
+
}),
|
|
429
498
|
),
|
|
430
499
|
buildResumeRequest: () => buildInstructionSeatTurnRequest(
|
|
431
500
|
admitted,
|
|
@@ -444,7 +513,10 @@ async function dispatchAdmitted(
|
|
|
444
513
|
io: turnIo,
|
|
445
514
|
request: buildInstructionSeatTurnRequest(
|
|
446
515
|
admitted,
|
|
447
|
-
roleTurnOptions(activeEnv, admitted, {
|
|
516
|
+
roleTurnOptions(activeEnv, admitted, {
|
|
517
|
+
kind: "initial",
|
|
518
|
+
prompt: initialPromptText,
|
|
519
|
+
}),
|
|
448
520
|
),
|
|
449
521
|
adapters,
|
|
450
522
|
...(activeEnv.engine === undefined ? {} : { effectiveEngine: activeEnv.engine }),
|
|
@@ -580,14 +652,28 @@ function resumeSameParentInstructionSeat(input: {
|
|
|
580
652
|
});
|
|
581
653
|
}
|
|
582
654
|
|
|
583
|
-
/**
|
|
584
|
-
|
|
655
|
+
/**
|
|
656
|
+
* Same delivery rule as resolveInitialPrompt for same-parent resume summons.
|
|
657
|
+
* Reask / explicit caller text / source-only ledger peer — one authority.
|
|
658
|
+
*/
|
|
659
|
+
async function sameParentDialogue(
|
|
585
660
|
env: InstructionSeatRunEnv,
|
|
586
661
|
fallback: { readonly instruction: string; readonly instructionEmpty: boolean },
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
662
|
+
sourceRunPath: string,
|
|
663
|
+
projectRoot: string,
|
|
664
|
+
): Promise<{ readonly instruction: string; readonly instructionEmpty: boolean }> {
|
|
665
|
+
const reask = env.reviewReask ?? env.gateReviewInstruction;
|
|
666
|
+
const body = await resolveReviewSeatDialogueBody({
|
|
667
|
+
...(reask === undefined ? {} : { reask }),
|
|
668
|
+
callerInstruction: fallback.instruction,
|
|
669
|
+
sourceRunPath,
|
|
670
|
+
projectRoot,
|
|
671
|
+
home: env.home,
|
|
672
|
+
});
|
|
673
|
+
if (body !== undefined) {
|
|
674
|
+
return { instruction: body, instructionEmpty: false };
|
|
675
|
+
}
|
|
676
|
+
return fallback;
|
|
591
677
|
}
|
|
592
678
|
|
|
593
679
|
/**
|
|
@@ -618,6 +704,9 @@ async function runCountersignBody(
|
|
|
618
704
|
sourceRunPath: gateParentRunPath,
|
|
619
705
|
instruction: resumeInstruction,
|
|
620
706
|
instructionEmpty: resumeInstruction.length === 0,
|
|
707
|
+
// #1166 J11: same-parent resume delivers this call's file-flag paths
|
|
708
|
+
// through the shared summons → appendCallerFileFlagPaths rule.
|
|
709
|
+
attachmentPaths: parsed.attachmentPaths ?? [],
|
|
621
710
|
},
|
|
622
711
|
});
|
|
623
712
|
if (resumed != null) return resumed;
|
|
@@ -652,10 +741,14 @@ async function runCountersignBody(
|
|
|
652
741
|
await persistAdmittedSourceRunPath(admitted, gateParentRunPath);
|
|
653
742
|
admitted = { ...admitted, sourceRunPath: gateParentRunPath };
|
|
654
743
|
}
|
|
744
|
+
// #1166 J11: review-body branch must merge the same file-flag delivery as
|
|
745
|
+
// resolveInitialPrompt / resumeTurnRequestProjectionOptions — never body alone.
|
|
746
|
+
const reviewBody = env.reviewReask ?? env.gateReviewInstruction;
|
|
655
747
|
const turnProjection = roleTurnOptions(env, admitted, {
|
|
656
748
|
kind: "initial",
|
|
657
|
-
prompt:
|
|
658
|
-
|
|
749
|
+
prompt: reviewBody !== undefined
|
|
750
|
+
? appendCallerFileFlagPaths(reviewBody, admitted.attachments)
|
|
751
|
+
: buildInstructionTransportPrompt(admitted),
|
|
659
752
|
});
|
|
660
753
|
const turnRequest = buildInstructionSeatTurnRequest(admitted, turnProjection);
|
|
661
754
|
const result = await runPostAdmissionOneShot({
|
|
@@ -746,10 +839,15 @@ export async function runPublicInstructionSeat(
|
|
|
746
839
|
if (auditorSource === undefined) return { exitCode: 2 };
|
|
747
840
|
const sourceDirectory = auditorSource;
|
|
748
841
|
const summons: SameTicketSummonsMaterials = {
|
|
749
|
-
...
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
842
|
+
...(await sameParentDialogue(
|
|
843
|
+
env,
|
|
844
|
+
{
|
|
845
|
+
instruction: parsed.instruction ?? "",
|
|
846
|
+
instructionEmpty: (parsed.instruction ?? "").length === 0,
|
|
847
|
+
},
|
|
848
|
+
sourceDirectory,
|
|
849
|
+
projectRoot,
|
|
850
|
+
)),
|
|
753
851
|
attachmentPaths: parsed.attachmentPaths ?? [],
|
|
754
852
|
};
|
|
755
853
|
const resumed = await withAuditorSoulEnv({
|
|
@@ -767,15 +865,34 @@ export async function runPublicInstructionSeat(
|
|
|
767
865
|
if (resumed != null) return resumed;
|
|
768
866
|
}
|
|
769
867
|
|
|
770
|
-
if (record.sameParent === "
|
|
771
|
-
|
|
772
|
-
if (
|
|
868
|
+
if (record.sameParent === "source-run") {
|
|
869
|
+
// #1166: structured --source-run only. Instruction bytes stay opaque caller/peer text.
|
|
870
|
+
if (parsed.sourceRun !== undefined) {
|
|
871
|
+
let parentRunPath: string;
|
|
872
|
+
try {
|
|
873
|
+
parentRunPath = (await resolveNotarySourceRunLocator({
|
|
874
|
+
projectRoot,
|
|
875
|
+
sourceRun: parsed.sourceRun,
|
|
876
|
+
home: env.home,
|
|
877
|
+
})).runDirectory;
|
|
878
|
+
} catch (error) {
|
|
879
|
+
if (error instanceof NotarySourceRunError) {
|
|
880
|
+
presentStructuralRejection(new CliUsageError(error.message, { cause: error }), io);
|
|
881
|
+
return { exitCode: 2 };
|
|
882
|
+
}
|
|
883
|
+
throw error;
|
|
884
|
+
}
|
|
773
885
|
const summons: SameTicketSummonsMaterials = {
|
|
774
886
|
sourceRunPath: parentRunPath,
|
|
775
|
-
...
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
887
|
+
...(await sameParentDialogue(
|
|
888
|
+
env,
|
|
889
|
+
{
|
|
890
|
+
instruction: parsed.instruction ?? "",
|
|
891
|
+
instructionEmpty: (parsed.instruction ?? "").length === 0,
|
|
892
|
+
},
|
|
893
|
+
parentRunPath,
|
|
894
|
+
projectRoot,
|
|
895
|
+
)),
|
|
779
896
|
attachmentPaths: parsed.attachmentPaths ?? [],
|
|
780
897
|
};
|
|
781
898
|
const resumed = await resumeSameParentInstructionSeat({
|
|
@@ -805,13 +922,15 @@ export async function runPublicInstructionSeat(
|
|
|
805
922
|
}
|
|
806
923
|
throw error;
|
|
807
924
|
}
|
|
808
|
-
const resumeInstruction = env.reviewReask ?? env.gateReviewInstruction;
|
|
809
925
|
const summons: SameTicketSummonsMaterials = {
|
|
810
926
|
sourceRunPath: source.runDirectory,
|
|
811
927
|
sourceRun: source,
|
|
812
|
-
...(
|
|
813
|
-
|
|
814
|
-
|
|
928
|
+
...(await sameParentDialogue(
|
|
929
|
+
env,
|
|
930
|
+
{ instruction: "", instructionEmpty: true },
|
|
931
|
+
source.runDirectory,
|
|
932
|
+
projectRoot,
|
|
933
|
+
)),
|
|
815
934
|
};
|
|
816
935
|
resolvedNotarySource = source;
|
|
817
936
|
const resumed = await resumeSameParentInstructionSeat({
|
|
@@ -843,16 +962,18 @@ export async function runPublicInstructionSeat(
|
|
|
843
962
|
throw error;
|
|
844
963
|
}
|
|
845
964
|
|
|
846
|
-
if (record.sameParent === "
|
|
847
|
-
const parentRunPath =
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
965
|
+
if (record.sameParent === "source-run" && parsed.sourceRun !== undefined) {
|
|
966
|
+
const parentRunPath = (await resolveNotarySourceRunLocator({
|
|
967
|
+
projectRoot,
|
|
968
|
+
sourceRun: parsed.sourceRun,
|
|
969
|
+
home: env.home,
|
|
970
|
+
})).runDirectory;
|
|
971
|
+
await persistAdmittedSourceRunPath(admitted, parentRunPath);
|
|
972
|
+
admitted = { ...admitted, sourceRunPath: parentRunPath } as AdmittedRoleInvocation;
|
|
853
973
|
}
|
|
854
974
|
if (record.sameParent === "subject-source" && auditorSource !== undefined) {
|
|
855
975
|
await persistAdmittedSourceRunPath(admitted, auditorSource, auditorSubject);
|
|
976
|
+
admitted = { ...admitted, sourceRunPath: auditorSource } as AdmittedRoleInvocation;
|
|
856
977
|
}
|
|
857
978
|
|
|
858
979
|
const runAdmitted = async (): Promise<SeatRunResult> => {
|
|
@@ -1247,8 +1368,7 @@ async function auditSubmittedRole(
|
|
|
1247
1368
|
summonAuditor: async (subject, sourceRunDirectory, signal, reask, submission) => {
|
|
1248
1369
|
const summoned = await summonPublicRole({
|
|
1249
1370
|
role: "auditor",
|
|
1250
|
-
argv: ["--subject", subject, "--source-run", sourceRunDirectory,
|
|
1251
|
-
`${AUDITOR_DOSSIER_PROMPT}${sourceRunDirectory}`],
|
|
1371
|
+
argv: ["--subject", subject, "--source-run", sourceRunDirectory],
|
|
1252
1372
|
cwd: admitted.projectRoot, home: env.home, packageRoot: env.packageRoot,
|
|
1253
1373
|
principalAuthority: env.principalAuthority,
|
|
1254
1374
|
correlationId: admitted.runId,
|