@akagilnc/pi-workflow-roles 0.1.5598 → 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/dist/acp-host/production-host.js +406 -366
- 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 +370 -330
- package/dist/migrate-book-topology.js +301 -291
- package/dist/navigator-public-session.js +4 -4
- package/dist/navigator-work-base.js +5 -30
- package/dist/packaged-role-registry.js +4 -2
- 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 +23 -26
- package/dist/public-cli/main.js +250 -179
- package/dist/public-cli/option-definitions.js +19 -0
- package/dist/public-cli/post-admission.js +23 -22
- package/dist/public-cli/run-lifecycle.js +2 -14
- 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/package.json +1 -1
- package/scripts/build-package.mjs +2 -3
- 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 -1
- 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/packaged-role-registry.ts +4 -4
- 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 +35 -26
- package/src/public-cli/option-definitions.ts +20 -0
- package/src/public-cli/post-admission.ts +28 -22
- package/src/public-cli/run-lifecycle.ts +2 -17
- 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-runtime.ts +54 -31
- package/dist/auditor-dossier-tool.js +0 -47
- package/src/auditor-dossier-tool.ts +0 -63
|
@@ -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,
|
|
@@ -183,6 +183,8 @@ export type AdmittedNavigatorInvocation = AdmittedRoleInvocationBase & {
|
|
|
183
183
|
|
|
184
184
|
export type AdmittedAuditorInvocation = AdmittedRoleInvocationBase & {
|
|
185
185
|
readonly role: "auditor";
|
|
186
|
+
/** Audited source-run directory (#1166 identity / ADR 0085 peer-body load). */
|
|
187
|
+
readonly sourceRunPath?: string;
|
|
186
188
|
};
|
|
187
189
|
|
|
188
190
|
export type AdmittedDiaristInvocation = AdmittedRoleInvocationBase & {
|
|
@@ -1817,10 +1819,32 @@ function admittedTransportPromptKind(
|
|
|
1817
1819
|
return "instruction";
|
|
1818
1820
|
}
|
|
1819
1821
|
|
|
1822
|
+
/** Append opaque caller file-flag paths after dialogue (#1165 / #1166 J11 / #1168). */
|
|
1823
|
+
export function appendCallerFileFlagPaths(
|
|
1824
|
+
body: string,
|
|
1825
|
+
attachments: readonly { readonly path: string }[],
|
|
1826
|
+
requestManifestPath?: string,
|
|
1827
|
+
prerequisitesPath?: string,
|
|
1828
|
+
): string {
|
|
1829
|
+
const flaggedPaths = [
|
|
1830
|
+
...attachments.map((attachment) => `--attach ${attachment.path}`),
|
|
1831
|
+
...(requestManifestPath === undefined
|
|
1832
|
+
? []
|
|
1833
|
+
: [`--request-manifest ${requestManifestPath}`]),
|
|
1834
|
+
...(prerequisitesPath === undefined
|
|
1835
|
+
? []
|
|
1836
|
+
: [`--prerequisites ${prerequisitesPath}`]),
|
|
1837
|
+
];
|
|
1838
|
+
if (flaggedPaths.length === 0) return body;
|
|
1839
|
+
// ADR 0087 / #1165 / #1166 J13: after caller words, only necessary file flags
|
|
1840
|
+
// and original paths — no package-authored title or list wrapper.
|
|
1841
|
+
return [body, "", ...flaggedPaths].join("\n");
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1820
1844
|
/**
|
|
1821
1845
|
* One initial prompt transport. The registry `transportPrompt` leaf selects
|
|
1822
|
-
* a fixed kickoff, a bound baseline, or
|
|
1823
|
-
*
|
|
1846
|
+
* a fixed kickoff, a bound baseline, or skill args. Absent means the caller
|
|
1847
|
+
* instruction plus caller file-flag paths (ADR 0087).
|
|
1824
1848
|
* Engine / outsourcing material rides startup readingMaterial (#1167), not here.
|
|
1825
1849
|
*/
|
|
1826
1850
|
export function buildInstructionTransportPrompt(
|
|
@@ -1828,10 +1852,9 @@ export function buildInstructionTransportPrompt(
|
|
|
1828
1852
|
): string {
|
|
1829
1853
|
const kind = admittedTransportPromptKind(admitted);
|
|
1830
1854
|
if (kind === "fixed-kickoff") {
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
return admitted.sourceRunPath;
|
|
1855
|
+
// #1166 / ADR 0087: audited-run identity rides startup materials; dialogue
|
|
1856
|
+
// prompt is peer body / reask only — never a package-computed directory path.
|
|
1857
|
+
return "";
|
|
1835
1858
|
}
|
|
1836
1859
|
if (kind === "baseline") {
|
|
1837
1860
|
if (admitted.baseRevision === undefined) {
|
|
@@ -1863,26 +1886,12 @@ export function buildInstructionTransportPrompt(
|
|
|
1863
1886
|
}
|
|
1864
1887
|
return lines.join("\n");
|
|
1865
1888
|
}
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
? []
|
|
1873
|
-
: [`--request-manifest ${admitted.requestManifestPath}`]),
|
|
1874
|
-
...(admitted.prerequisitesPath === undefined
|
|
1875
|
-
? []
|
|
1876
|
-
: [`--prerequisites ${admitted.prerequisitesPath}`]),
|
|
1877
|
-
];
|
|
1878
|
-
if (flaggedPaths.length > 0) {
|
|
1879
|
-
lines.push("");
|
|
1880
|
-
lines.push("已受理附件:");
|
|
1881
|
-
for (const entry of flaggedPaths) {
|
|
1882
|
-
lines.push(`- ${entry}`);
|
|
1883
|
-
}
|
|
1884
|
-
}
|
|
1885
|
-
return lines.join("\n");
|
|
1889
|
+
return appendCallerFileFlagPaths(
|
|
1890
|
+
admitted.instruction,
|
|
1891
|
+
admitted.attachments,
|
|
1892
|
+
admitted.requestManifestPath,
|
|
1893
|
+
admitted.prerequisitesPath,
|
|
1894
|
+
);
|
|
1886
1895
|
}
|
|
1887
1896
|
|
|
1888
1897
|
export type AdmitCountersignInvocationOptions = {
|
|
@@ -612,6 +612,25 @@ const NOTARY_OPTIONS = [
|
|
|
612
612
|
},
|
|
613
613
|
] as const satisfies readonly PublicOptionDefinition[];
|
|
614
614
|
|
|
615
|
+
/** 台院: optional --source-run binds the audited leg; gate summons always pass it (#1166). */
|
|
616
|
+
const INSPECTOR_OPTIONS = [
|
|
617
|
+
...projectAndAttach("inspector"),
|
|
618
|
+
{
|
|
619
|
+
id: "source-run",
|
|
620
|
+
owner: "inspector",
|
|
621
|
+
canonical: "--source-run",
|
|
622
|
+
aliases: [],
|
|
623
|
+
valueMetavar: "runId@role|path",
|
|
624
|
+
required: false,
|
|
625
|
+
repeatable: false,
|
|
626
|
+
form: "option",
|
|
627
|
+
description: {
|
|
628
|
+
en: "Optional audited source-run locator (runId@role or path). Gate summons always supply it; identity rides startup materials.",
|
|
629
|
+
zh: "可选被审腿定位符(runId@role 或路径)。闸传召必带;身份在启动材料里。",
|
|
630
|
+
},
|
|
631
|
+
},
|
|
632
|
+
] as const satisfies readonly PublicOptionDefinition[];
|
|
633
|
+
|
|
615
634
|
const MERGER_OPTIONS = [
|
|
616
635
|
// Merger project face: worktree whose Git materials are handed to the role.
|
|
617
636
|
{
|
|
@@ -779,6 +798,7 @@ const SEAT_OPTION_ROWS: Partial<
|
|
|
779
798
|
merger: MERGER_OPTIONS,
|
|
780
799
|
notary: NOTARY_OPTIONS,
|
|
781
800
|
auditor: AUDITOR_OPTIONS,
|
|
801
|
+
inspector: INSPECTOR_OPTIONS,
|
|
782
802
|
};
|
|
783
803
|
|
|
784
804
|
function seatOptionRows(role: PublicCallableRole): readonly PublicOptionDefinition[] {
|
|
@@ -19,8 +19,8 @@ import {
|
|
|
19
19
|
import { CliUsageError } from "./cli-errors.ts";
|
|
20
20
|
import { projectPublicTurnAxes, type RoleTurnRequestProjectionOptions } from "./turn-request.ts";
|
|
21
21
|
import {
|
|
22
|
+
appendCallerFileFlagPaths,
|
|
22
23
|
bindAdmittedTicketNumber,
|
|
23
|
-
buildInstructionTransportPrompt,
|
|
24
24
|
relocateAdmittedRunToTicket,
|
|
25
25
|
} from "./invocation.ts";
|
|
26
26
|
import { readRecordedSubmissionRows } from "../submission-ledger.ts";
|
|
@@ -326,6 +326,11 @@ export type PostAdmissionEnv = {
|
|
|
326
326
|
boundTicketNumber?: number;
|
|
327
327
|
/** Station child role run (#840): omit automatic navigator attendance. */
|
|
328
328
|
stationChild?: boolean;
|
|
329
|
+
/**
|
|
330
|
+
* Navigator nest work-context locator (#1166). Request-scoped; never folded
|
|
331
|
+
* into dialogue. Child spawn may mirror onto child env only.
|
|
332
|
+
*/
|
|
333
|
+
navigatorWorkContextPath?: string;
|
|
329
334
|
};
|
|
330
335
|
|
|
331
336
|
/**
|
|
@@ -1458,8 +1463,8 @@ export async function dispatchPostAdmissionTurn<
|
|
|
1458
1463
|
* Shared resume continuation projection (#471 / #600 / #633 / #637 / #755 / #879):
|
|
1459
1464
|
* seat-table model/engine/timeout axes, restored correlation, and either
|
|
1460
1465
|
* - manual resume (no same-ticket summons): caller message bytes, or
|
|
1461
|
-
* - same-ticket summons (审核循环续话): caller/peer words + optional
|
|
1462
|
-
*
|
|
1466
|
+
* - same-ticket summons (审核循环续话): caller/peer words + optional caller file-flag
|
|
1467
|
+
* paths only — no「请重读」、no code-authored content substitute,
|
|
1463
1468
|
* no engine handbook packaging (#750/#755/#879).
|
|
1464
1469
|
* Caller message wins as prompt base when supplied (bytes unchanged, including
|
|
1465
1470
|
* blank/whitespace); else summons instruction (parent payload or reask).
|
|
@@ -1477,22 +1482,17 @@ export function resumeTurnRequestProjectionOptions(
|
|
|
1477
1482
|
readonly attachments: readonly { path: string }[];
|
|
1478
1483
|
},
|
|
1479
1484
|
): RoleTurnRequestProjectionOptions {
|
|
1480
|
-
// #879: officer dialogue
|
|
1481
|
-
//
|
|
1482
|
-
// Binding pointer stays on summons sourceRunPath / activation / attachments.
|
|
1485
|
+
// #879: officer dialogue is caller/peer words; #1166 J11 merges caller file-flag
|
|
1486
|
+
// paths when present. Gate with no file flags stays body-only (ADR 0085).
|
|
1483
1487
|
const officerDialogue = isStationChildOfficerDialogue(admitted.role, env);
|
|
1488
|
+
const fileFlags = summonsPrepared?.attachments ?? [];
|
|
1484
1489
|
let prompt: string;
|
|
1485
1490
|
if (request.message !== undefined) {
|
|
1486
1491
|
if (summonsPrepared !== undefined) {
|
|
1487
|
-
// #755: same-ticket review / open-court — caller words.
|
|
1488
|
-
|
|
1489
|
-
prompt = officerDialogue
|
|
1492
|
+
// #755: same-ticket review / open-court — caller words + caller file flags.
|
|
1493
|
+
prompt = officerDialogue && fileFlags.length === 0
|
|
1490
1494
|
? request.message
|
|
1491
|
-
:
|
|
1492
|
-
instruction: request.message,
|
|
1493
|
-
instructionEmpty: false,
|
|
1494
|
-
attachments: summonsPrepared.attachments,
|
|
1495
|
-
});
|
|
1495
|
+
: appendCallerFileFlagPaths(request.message, fileFlags);
|
|
1496
1496
|
} else if (request.summons !== undefined) {
|
|
1497
1497
|
// #755: same-ticket summons without prepared materials — caller words only.
|
|
1498
1498
|
prompt = request.message;
|
|
@@ -1500,13 +1500,11 @@ export function resumeTurnRequestProjectionOptions(
|
|
|
1500
1500
|
prompt = request.message;
|
|
1501
1501
|
}
|
|
1502
1502
|
} else if (summonsPrepared !== undefined) {
|
|
1503
|
-
|
|
1504
|
-
//
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
? summonsPrepared.instruction
|
|
1509
|
-
: buildInstructionTransportPrompt(summonsPrepared);
|
|
1503
|
+
const body = summonsPrepared.instruction;
|
|
1504
|
+
// No file flags: body alone (gate peer words). With flags: merge delivery.
|
|
1505
|
+
prompt = officerDialogue && fileFlags.length === 0
|
|
1506
|
+
? body
|
|
1507
|
+
: appendCallerFileFlagPaths(body, fileFlags);
|
|
1510
1508
|
} else if (request.summons !== undefined) {
|
|
1511
1509
|
// #879: same-ticket summons with no instruction (e.g. notary source-run binding
|
|
1512
1510
|
// only). Pointer is activation/sourceRun material — not dialogue content.
|
|
@@ -1527,6 +1525,10 @@ export function resumeTurnRequestProjectionOptions(
|
|
|
1527
1525
|
...(env.stationChild === undefined ? {} : { stationChild: env.stationChild }),
|
|
1528
1526
|
// #1132: one configured ceiling, already resolved by the caller (#422).
|
|
1529
1527
|
deliveryRequestLimit: deliveryLimitFromConfig(env.autoResumeLimit),
|
|
1528
|
+
...(env.navigatorWorkContextPath === undefined
|
|
1529
|
+
|| env.navigatorWorkContextPath.trim() === ""
|
|
1530
|
+
? {}
|
|
1531
|
+
: { navigatorWorkContextPath: env.navigatorWorkContextPath }),
|
|
1530
1532
|
};
|
|
1531
1533
|
}
|
|
1532
1534
|
|
|
@@ -1547,6 +1549,10 @@ export function roleTurnOptions(
|
|
|
1547
1549
|
...(env.stationChild === undefined ? {} : { stationChild: env.stationChild }),
|
|
1548
1550
|
// #1132: one configured ceiling, already resolved by the caller (#422).
|
|
1549
1551
|
deliveryRequestLimit: deliveryLimitFromConfig(env.autoResumeLimit),
|
|
1552
|
+
...(env.navigatorWorkContextPath === undefined
|
|
1553
|
+
|| env.navigatorWorkContextPath.trim() === ""
|
|
1554
|
+
? {}
|
|
1555
|
+
: { navigatorWorkContextPath: env.navigatorWorkContextPath }),
|
|
1550
1556
|
};
|
|
1551
1557
|
}
|
|
1552
1558
|
|
|
@@ -1668,7 +1674,7 @@ export async function prepareSummonsResumeMaterials(
|
|
|
1668
1674
|
* validation, turn builder, and adapters stay on the seat.
|
|
1669
1675
|
*
|
|
1670
1676
|
* Court handling (#637): public manual resume reads only the open court's
|
|
1671
|
-
* settlement identity; internal re-summons
|
|
1677
|
+
* settlement identity; internal re-summons passes caller file-flag paths as-is.
|
|
1672
1678
|
*/
|
|
1673
1679
|
export async function runPostAdmissionSeatResume<
|
|
1674
1680
|
A extends AdmittedRoleInvocation,
|
|
@@ -885,21 +885,9 @@ export async function findRunDirectoryById(
|
|
|
885
885
|
);
|
|
886
886
|
}
|
|
887
887
|
|
|
888
|
-
/** Code-owned gate inspector summons prefix (public-role-summons / #747). */
|
|
889
|
-
export const GATE_DOSSIER_POINTER_PREFIX = "卷宗指针:" as const;
|
|
890
|
-
|
|
891
|
-
/** Parent path from a code-owned inspector 卷宗指针 instruction; else undefined. */
|
|
892
|
-
export function parentRunPathFromGatePointerInstruction(
|
|
893
|
-
instruction: string,
|
|
894
|
-
): string | undefined {
|
|
895
|
-
if (!instruction.startsWith(GATE_DOSSIER_POINTER_PREFIX)) return undefined;
|
|
896
|
-
const path = instruction.slice(GATE_DOSSIER_POINTER_PREFIX.length).trim();
|
|
897
|
-
return path === "" ? undefined : path;
|
|
898
|
-
}
|
|
899
|
-
|
|
900
888
|
/**
|
|
901
|
-
* Parent-run binding on a retained officer run (#747).
|
|
902
|
-
*
|
|
889
|
+
* Parent-run binding on a retained officer run (#747 / #1166).
|
|
890
|
+
* Typed sourceRunPath only — instruction bytes are never a path protocol.
|
|
903
891
|
* Missing page → undefined; damage / non-ENOENT IO propagates.
|
|
904
892
|
*/
|
|
905
893
|
export async function readRunParentPath(
|
|
@@ -910,9 +898,6 @@ export async function readRunParentPath(
|
|
|
910
898
|
if (typeof record.sourceRunPath === "string" && record.sourceRunPath.trim() !== "") {
|
|
911
899
|
return record.sourceRunPath;
|
|
912
900
|
}
|
|
913
|
-
if (typeof record.instruction === "string") {
|
|
914
|
-
return parentRunPathFromGatePointerInstruction(record.instruction);
|
|
915
|
-
}
|
|
916
901
|
return undefined;
|
|
917
902
|
}
|
|
918
903
|
|
|
@@ -17,7 +17,6 @@ import {
|
|
|
17
17
|
import type { SeatModelConfig } from "./config.ts";
|
|
18
18
|
import type { AdmittedRoleInvocation } from "./invocation.ts";
|
|
19
19
|
import { installedMethodSkillPath } from "./machine-method-skills.ts";
|
|
20
|
-
import { parentRunPathFromGatePointerInstruction } from "./run-lifecycle.ts";
|
|
21
20
|
import type { PublicThinkingLevel } from "./registry.ts";
|
|
22
21
|
|
|
23
22
|
/** Structural model shape shared by the seam so seat/env sources fit. */
|
|
@@ -77,6 +76,11 @@ export type RoleTurnRequestProjectionOptions = {
|
|
|
77
76
|
* execution seam count with the same configured number.
|
|
78
77
|
*/
|
|
79
78
|
readonly deliveryRequestLimit?: number;
|
|
79
|
+
/**
|
|
80
|
+
* Navigator nest work-context locator (#1166). Request-scoped internal path —
|
|
81
|
+
* not dialogue content.
|
|
82
|
+
*/
|
|
83
|
+
readonly navigatorWorkContextPath?: string;
|
|
80
84
|
};
|
|
81
85
|
|
|
82
86
|
export type AdmittedTurnInvocation = {
|
|
@@ -127,6 +131,10 @@ export function projectRoleTurnRequest(
|
|
|
127
131
|
...(options.deliveryRequestLimit === undefined
|
|
128
132
|
? {}
|
|
129
133
|
: { deliveryRequestLimit: options.deliveryRequestLimit }),
|
|
134
|
+
...(options.navigatorWorkContextPath === undefined
|
|
135
|
+
|| options.navigatorWorkContextPath.trim() === ""
|
|
136
|
+
? {}
|
|
137
|
+
: { navigatorWorkContextPath: options.navigatorWorkContextPath }),
|
|
130
138
|
};
|
|
131
139
|
}
|
|
132
140
|
|
|
@@ -163,13 +171,6 @@ function activationForAdmitted(admitted: AdmittedRoleInvocation): RoleTurnActiva
|
|
|
163
171
|
const activation: Record<string, unknown> = { role: admitted.role };
|
|
164
172
|
for (const spec of packagedRoleActivationFlags(admitted.role)) {
|
|
165
173
|
let value = readAdmittedPath(admitted, spec.from ?? spec.field);
|
|
166
|
-
if (spec.fallback === "gate-pointer") {
|
|
167
|
-
const trimmed = typeof value === "string" ? value.trim() : "";
|
|
168
|
-
value = trimmed !== ""
|
|
169
|
-
? trimmed
|
|
170
|
-
: parentRunPathFromGatePointerInstruction(admitted.instruction);
|
|
171
|
-
if (typeof value !== "string" || value === "") continue;
|
|
172
|
-
}
|
|
173
174
|
if (value === undefined) continue;
|
|
174
175
|
if (spec.text === true) {
|
|
175
176
|
if (typeof value !== "number") continue;
|