@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
|
@@ -65,11 +65,6 @@ import {
|
|
|
65
65
|
type CollectorRepository,
|
|
66
66
|
} from "../collector-config.ts";
|
|
67
67
|
import { ownerRepoFromGitHubRemoteUrl } from "./github-remote.ts";
|
|
68
|
-
import {
|
|
69
|
-
FixerPacketValidationError,
|
|
70
|
-
parseFixerPrerequisites,
|
|
71
|
-
type FixerPrerequisite,
|
|
72
|
-
} from "../package-contracts/fixer-packet.ts";
|
|
73
68
|
import type { FixerPhase } from "../package-contracts/fixer-output.ts";
|
|
74
69
|
import { createProductionMergerGitState } from "../merger-git-state.ts";
|
|
75
70
|
import type { MergerGitState } from "../merger-git-state.ts";
|
|
@@ -188,6 +183,8 @@ export type AdmittedNavigatorInvocation = AdmittedRoleInvocationBase & {
|
|
|
188
183
|
|
|
189
184
|
export type AdmittedAuditorInvocation = AdmittedRoleInvocationBase & {
|
|
190
185
|
readonly role: "auditor";
|
|
186
|
+
/** Audited source-run directory (#1166 identity / ADR 0085 peer-body load). */
|
|
187
|
+
readonly sourceRunPath?: string;
|
|
191
188
|
};
|
|
192
189
|
|
|
193
190
|
export type AdmittedDiaristInvocation = AdmittedRoleInvocationBase & {
|
|
@@ -204,20 +201,14 @@ export type AdmittedCoderInvocation = AdmittedRoleInvocationBase & {
|
|
|
204
201
|
readonly role: "coder";
|
|
205
202
|
/** Explicit plan or default apply — preserved through admission and continuation. */
|
|
206
203
|
readonly phase: CoderPhase;
|
|
207
|
-
/** Durable task file path consumed by internal --ak-coder-task. */
|
|
208
|
-
readonly taskPath: string;
|
|
209
204
|
};
|
|
210
205
|
|
|
211
206
|
export type AdmittedFixerInvocation = AdmittedRoleInvocationBase & {
|
|
212
207
|
readonly role: "fixer";
|
|
213
208
|
/** Explicit plan or default apply — preserved through admission and continuation. */
|
|
214
209
|
readonly phase: FixerPhase;
|
|
215
|
-
/**
|
|
216
|
-
readonly packetPath: string;
|
|
217
|
-
/** Optional durable prerequisites JSON path for --ak-fixer-prerequisites. */
|
|
210
|
+
/** Optional caller --prerequisites path as-is (#1168; package does not read it). */
|
|
218
211
|
readonly prerequisitesPath?: string;
|
|
219
|
-
/** Structurally validated prerequisite declarations frozen at admission. */
|
|
220
|
-
readonly prerequisites: readonly FixerPrerequisite[];
|
|
221
212
|
};
|
|
222
213
|
|
|
223
214
|
export type AdmittedCollectorInvocation = AdmittedRoleInvocationBase & {
|
|
@@ -622,15 +613,13 @@ export async function relocateAdmittedRunToTicket(
|
|
|
622
613
|
admittedRecord,
|
|
623
614
|
[
|
|
624
615
|
"runDirectory",
|
|
625
|
-
"taskPath",
|
|
626
|
-
"packetPath",
|
|
627
|
-
"prerequisitesPath",
|
|
628
616
|
"mergerInputPath",
|
|
629
617
|
],
|
|
630
618
|
oldRunDirectory,
|
|
631
619
|
target.runDirectory,
|
|
632
620
|
);
|
|
633
|
-
// #1165: caller
|
|
621
|
+
// #1165/#1168: caller file-flag paths stay as given. Obsolete copy fields
|
|
622
|
+
// (taskPath/packetPath) are not rewritten — stock volumes keep their bytes.
|
|
634
623
|
(admitted as { principal: DurablePrincipal }).principal = principal;
|
|
635
624
|
|
|
636
625
|
// current.json projects host.original from this run directory. Ownership is
|
|
@@ -876,7 +865,8 @@ function assignPublicSeatOption(
|
|
|
876
865
|
fields.authorityRefs.push(requireAuthorityRef(value));
|
|
877
866
|
return;
|
|
878
867
|
case "prerequisites":
|
|
879
|
-
|
|
868
|
+
// #1168: same opaque file-flag rule as --attach.
|
|
869
|
+
fields.prerequisitesPath = requireProvidedOptionValue(taken.def.canonical, value);
|
|
880
870
|
return;
|
|
881
871
|
case "pr":
|
|
882
872
|
fields.prNumber = parsePositivePrOption(value);
|
|
@@ -1324,16 +1314,13 @@ export async function admitPublicRole(
|
|
|
1324
1314
|
if (!record.phases.some((item) => item === phase)) {
|
|
1325
1315
|
throw new CliUsageError("coder phase must be plan or apply");
|
|
1326
1316
|
}
|
|
1317
|
+
// #1168: dispatch text is the first message only — no task.md copy.
|
|
1327
1318
|
return admitStandardMaterialInvocation("coder", {
|
|
1328
1319
|
...shared,
|
|
1329
1320
|
instruction,
|
|
1330
1321
|
attachmentPaths,
|
|
1331
1322
|
...project,
|
|
1332
|
-
placedFields: async (
|
|
1333
|
-
const taskPath = join(placed.runDirectory, "task.md");
|
|
1334
|
-
await writeFile(taskPath, instruction, "utf8");
|
|
1335
|
-
return { phase, taskPath };
|
|
1336
|
-
},
|
|
1323
|
+
placedFields: async () => ({ phase }),
|
|
1337
1324
|
});
|
|
1338
1325
|
}
|
|
1339
1326
|
case "worker-packet": {
|
|
@@ -1344,53 +1331,18 @@ export async function admitPublicRole(
|
|
|
1344
1331
|
if (!record.phases.some((item) => item === phase)) {
|
|
1345
1332
|
throw new CliUsageError("fixer phase must be plan or apply");
|
|
1346
1333
|
}
|
|
1347
|
-
|
|
1348
|
-
let prerequisitesSource: string | undefined;
|
|
1349
|
-
if (parsed.prerequisitesPath !== undefined) {
|
|
1350
|
-
const absolutePrereq = isAbsolute(parsed.prerequisitesPath)
|
|
1351
|
-
? parsed.prerequisitesPath
|
|
1352
|
-
: resolve(parsed.prerequisitesPath);
|
|
1353
|
-
try {
|
|
1354
|
-
prerequisitesSource = await readFile(absolutePrereq, "utf8");
|
|
1355
|
-
} catch (error) {
|
|
1356
|
-
throw new CliUsageError(
|
|
1357
|
-
`fixer prerequisites path is unreadable: ${parsed.prerequisitesPath}`,
|
|
1358
|
-
{ cause: error },
|
|
1359
|
-
);
|
|
1360
|
-
}
|
|
1361
|
-
try {
|
|
1362
|
-
prerequisites = parseFixerPrerequisites(prerequisitesSource);
|
|
1363
|
-
} catch (error) {
|
|
1364
|
-
if (error instanceof FixerPacketValidationError) {
|
|
1365
|
-
throw new CliUsageError(error.message, { cause: error });
|
|
1366
|
-
}
|
|
1367
|
-
throw error;
|
|
1368
|
-
}
|
|
1369
|
-
}
|
|
1334
|
+
// #1168: dispatch once as first message; --prerequisites path as-is.
|
|
1370
1335
|
return admitStandardMaterialInvocation("fixer", {
|
|
1371
1336
|
...shared,
|
|
1372
1337
|
instruction,
|
|
1373
1338
|
attachmentPaths,
|
|
1374
1339
|
...project,
|
|
1375
|
-
placedFields: async (
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
`${JSON.stringify(prerequisites, null, 2)}\n`,
|
|
1382
|
-
"utf8",
|
|
1383
|
-
);
|
|
1384
|
-
}
|
|
1385
|
-
const packetPath = join(placed.runDirectory, "fix-packet.md");
|
|
1386
|
-
await writeFile(packetPath, instruction, "utf8");
|
|
1387
|
-
return {
|
|
1388
|
-
phase,
|
|
1389
|
-
packetPath,
|
|
1390
|
-
prerequisites,
|
|
1391
|
-
...(prerequisitesPath === undefined ? {} : { prerequisitesPath }),
|
|
1392
|
-
};
|
|
1393
|
-
},
|
|
1340
|
+
placedFields: async () => ({
|
|
1341
|
+
phase,
|
|
1342
|
+
...(parsed.prerequisitesPath === undefined
|
|
1343
|
+
? {}
|
|
1344
|
+
: { prerequisitesPath: parsed.prerequisitesPath }),
|
|
1345
|
+
}),
|
|
1394
1346
|
});
|
|
1395
1347
|
}
|
|
1396
1348
|
case "collect-target": {
|
|
@@ -1579,13 +1531,12 @@ export async function admitPublicRole(
|
|
|
1579
1531
|
placedFields: async (placed) => {
|
|
1580
1532
|
const targetLabel = derived.targetObjectId === "" ? "(none observed)" : derived.targetObjectId;
|
|
1581
1533
|
const sourceLabel = derived.sourceObjectId === "" ? "(none observed)" : derived.sourceObjectId;
|
|
1534
|
+
// #1168: git facts stay; do not encode dispatch text as task/authority copies.
|
|
1582
1535
|
const mergerInput = validateMergerInput({
|
|
1583
1536
|
attemptId: placed.runId,
|
|
1584
1537
|
targetObjectId: derived.targetObjectId,
|
|
1585
1538
|
sourceObjectId: derived.sourceObjectId,
|
|
1586
1539
|
materials: {
|
|
1587
|
-
task: mergerMaterialFromUtf8(instruction),
|
|
1588
|
-
authority: mergerMaterialFromUtf8(instruction),
|
|
1589
1540
|
targetIntent: mergerMaterialFromUtf8(
|
|
1590
1541
|
`Investigate primary sources for target parent ${targetLabel}. Do not invent intent.`,
|
|
1591
1542
|
),
|
|
@@ -1767,7 +1718,7 @@ async function persistPlacedAdmission(
|
|
|
1767
1718
|
* before materializeCountersignInvocation writes the page.
|
|
1768
1719
|
* Seats whose extra facts are known before placement pass them as admittedFields.
|
|
1769
1720
|
* Seats whose extra facts depend on the placed run pass placedFields
|
|
1770
|
-
* (
|
|
1721
|
+
* (merger writes merger-input.json with git facts; coder/fixer dispatch is first-message only, #1168).
|
|
1771
1722
|
*/
|
|
1772
1723
|
async function admitStandardMaterialInvocation<
|
|
1773
1724
|
R extends PackagedRole,
|
|
@@ -1849,9 +1800,10 @@ export type AdmitAuditorInvocationOptions = AdmitInspectorInvocationOptions;
|
|
|
1849
1800
|
type InstructionTransportSource = {
|
|
1850
1801
|
readonly role?: string;
|
|
1851
1802
|
readonly instruction: string;
|
|
1852
|
-
readonly instructionEmpty
|
|
1803
|
+
readonly instructionEmpty?: boolean;
|
|
1853
1804
|
readonly attachments: readonly { readonly path: string }[];
|
|
1854
1805
|
readonly requestManifestPath?: string;
|
|
1806
|
+
readonly prerequisitesPath?: string;
|
|
1855
1807
|
readonly baseRevision?: string;
|
|
1856
1808
|
readonly lens?: ReviewerLens;
|
|
1857
1809
|
readonly authorityRefs?: readonly string[];
|
|
@@ -1867,10 +1819,32 @@ function admittedTransportPromptKind(
|
|
|
1867
1819
|
return "instruction";
|
|
1868
1820
|
}
|
|
1869
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
|
+
|
|
1870
1844
|
/**
|
|
1871
1845
|
* One initial prompt transport. The registry `transportPrompt` leaf selects
|
|
1872
|
-
* a fixed kickoff, a bound baseline, or
|
|
1873
|
-
*
|
|
1846
|
+
* a fixed kickoff, a bound baseline, or skill args. Absent means the caller
|
|
1847
|
+
* instruction plus caller file-flag paths (ADR 0087).
|
|
1874
1848
|
* Engine / outsourcing material rides startup readingMaterial (#1167), not here.
|
|
1875
1849
|
*/
|
|
1876
1850
|
export function buildInstructionTransportPrompt(
|
|
@@ -1878,10 +1852,9 @@ export function buildInstructionTransportPrompt(
|
|
|
1878
1852
|
): string {
|
|
1879
1853
|
const kind = admittedTransportPromptKind(admitted);
|
|
1880
1854
|
if (kind === "fixed-kickoff") {
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
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 "";
|
|
1885
1858
|
}
|
|
1886
1859
|
if (kind === "baseline") {
|
|
1887
1860
|
if (admitted.baseRevision === undefined) {
|
|
@@ -1913,23 +1886,12 @@ export function buildInstructionTransportPrompt(
|
|
|
1913
1886
|
}
|
|
1914
1887
|
return lines.join("\n");
|
|
1915
1888
|
}
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
? []
|
|
1923
|
-
: [`--request-manifest ${admitted.requestManifestPath}`]),
|
|
1924
|
-
];
|
|
1925
|
-
if (flaggedPaths.length > 0) {
|
|
1926
|
-
lines.push("");
|
|
1927
|
-
lines.push("已受理附件:");
|
|
1928
|
-
for (const entry of flaggedPaths) {
|
|
1929
|
-
lines.push(`- ${entry}`);
|
|
1930
|
-
}
|
|
1931
|
-
}
|
|
1932
|
-
return lines.join("\n");
|
|
1889
|
+
return appendCallerFileFlagPaths(
|
|
1890
|
+
admitted.instruction,
|
|
1891
|
+
admitted.attachments,
|
|
1892
|
+
admitted.requestManifestPath,
|
|
1893
|
+
admitted.prerequisitesPath,
|
|
1894
|
+
);
|
|
1933
1895
|
}
|
|
1934
1896
|
|
|
1935
1897
|
export type AdmitCountersignInvocationOptions = {
|
|
@@ -2022,7 +1984,7 @@ export type AdmitFixerInvocationOptions = {
|
|
|
2022
1984
|
phase: FixerPhase;
|
|
2023
1985
|
instruction: string;
|
|
2024
1986
|
attachmentPaths: readonly string[];
|
|
2025
|
-
/** Optional caller path
|
|
1987
|
+
/** Optional caller --prerequisites path as-is (#1168). */
|
|
2026
1988
|
prerequisitesPath?: string;
|
|
2027
1989
|
project?: string;
|
|
2028
1990
|
createRunId?: () => string;
|
|
@@ -2198,7 +2160,7 @@ export function buildReviewerSkillArgProjection(
|
|
|
2198
2160
|
].join(" ");
|
|
2199
2161
|
}
|
|
2200
2162
|
|
|
2201
|
-
function mergerMaterialFromUtf8(text: string): MergerInput["materials"]["
|
|
2163
|
+
function mergerMaterialFromUtf8(text: string): MergerInput["materials"]["targetIntent"] {
|
|
2202
2164
|
const bytes = Buffer.from(text, "utf8");
|
|
2203
2165
|
return Object.freeze({
|
|
2204
2166
|
bytesBase64: bytes.toString("base64"),
|
|
@@ -463,8 +463,8 @@ const FIXER_OPTIONS = [
|
|
|
463
463
|
repeatable: false,
|
|
464
464
|
form: "option",
|
|
465
465
|
description: {
|
|
466
|
-
en: "
|
|
467
|
-
zh: "
|
|
466
|
+
en: "Caller prerequisites path passed as-is to the role. Package does not read, copy, or validate; use an absolute path when cwd differs from --project.",
|
|
467
|
+
zh: "调用方前置条件文件路径原样递给衙门。包不读、不复制、不校验;调用方当前目录与 --project 不同时请给绝对路径。",
|
|
468
468
|
},
|
|
469
469
|
},
|
|
470
470
|
] as const satisfies readonly PublicOptionDefinition[];
|
|
@@ -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";
|
|
@@ -132,11 +132,11 @@ function projectRelocatedTurnIdentity(
|
|
|
132
132
|
mutableRequest.principal = admitted.principal;
|
|
133
133
|
const activation = mutableRequest.activation;
|
|
134
134
|
if (isRecord(activation)) {
|
|
135
|
-
for (const field of ["
|
|
135
|
+
for (const field of ["inputPath"] as const) {
|
|
136
136
|
const record = activation as Record<string, unknown>;
|
|
137
137
|
if (field in record) record[field] = rewrite(record[field]);
|
|
138
138
|
}
|
|
139
|
-
// #1165:
|
|
139
|
+
// #1165/#1168: caller file-flag paths are not activation fields to rewrite.
|
|
140
140
|
}
|
|
141
141
|
if (result.terminal !== undefined) {
|
|
142
142
|
for (const artifact of result.terminal.artifacts) {
|
|
@@ -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,
|
|
@@ -20,7 +20,6 @@ import { findRoleRunDirectory, listBookRunDirectories, parseRunLeaf, sessionFile
|
|
|
20
20
|
import { isSafePositiveTicketNumber } from "../run-ticket-number.ts";
|
|
21
21
|
import { CliUsageError } from "./cli-errors.ts";
|
|
22
22
|
import type { FixerPhase } from "../package-contracts/fixer-output.ts";
|
|
23
|
-
import type { FixerPrerequisite } from "../package-contracts/fixer-packet.ts";
|
|
24
23
|
import { parseCollectorRepository } from "../collector-config.ts";
|
|
25
24
|
import type { DoctorCaseIdentity } from "../doctor-contracts.ts";
|
|
26
25
|
import type { NotarySourceRunLocator } from "../notary-contracts.ts";
|
|
@@ -886,21 +885,9 @@ export async function findRunDirectoryById(
|
|
|
886
885
|
);
|
|
887
886
|
}
|
|
888
887
|
|
|
889
|
-
/** Code-owned gate inspector summons prefix (public-role-summons / #747). */
|
|
890
|
-
export const GATE_DOSSIER_POINTER_PREFIX = "卷宗指针:" as const;
|
|
891
|
-
|
|
892
|
-
/** Parent path from a code-owned inspector 卷宗指针 instruction; else undefined. */
|
|
893
|
-
export function parentRunPathFromGatePointerInstruction(
|
|
894
|
-
instruction: string,
|
|
895
|
-
): string | undefined {
|
|
896
|
-
if (!instruction.startsWith(GATE_DOSSIER_POINTER_PREFIX)) return undefined;
|
|
897
|
-
const path = instruction.slice(GATE_DOSSIER_POINTER_PREFIX.length).trim();
|
|
898
|
-
return path === "" ? undefined : path;
|
|
899
|
-
}
|
|
900
|
-
|
|
901
888
|
/**
|
|
902
|
-
* Parent-run binding on a retained officer run (#747).
|
|
903
|
-
*
|
|
889
|
+
* Parent-run binding on a retained officer run (#747 / #1166).
|
|
890
|
+
* Typed sourceRunPath only — instruction bytes are never a path protocol.
|
|
904
891
|
* Missing page → undefined; damage / non-ENOENT IO propagates.
|
|
905
892
|
*/
|
|
906
893
|
export async function readRunParentPath(
|
|
@@ -911,9 +898,6 @@ export async function readRunParentPath(
|
|
|
911
898
|
if (typeof record.sourceRunPath === "string" && record.sourceRunPath.trim() !== "") {
|
|
912
899
|
return record.sourceRunPath;
|
|
913
900
|
}
|
|
914
|
-
if (typeof record.instruction === "string") {
|
|
915
|
-
return parentRunPathFromGatePointerInstruction(record.instruction);
|
|
916
|
-
}
|
|
917
901
|
return undefined;
|
|
918
902
|
}
|
|
919
903
|
|
|
@@ -992,10 +976,7 @@ type LoadedAdmittedRequestFields = {
|
|
|
992
976
|
readonly instructionEmpty: boolean;
|
|
993
977
|
readonly attachments: FrozenAttachment[];
|
|
994
978
|
readonly phase?: CoderPhase | FixerPhase;
|
|
995
|
-
readonly taskPath?: string;
|
|
996
|
-
readonly packetPath?: string;
|
|
997
979
|
readonly prerequisitesPath?: string;
|
|
998
|
-
readonly prerequisites?: readonly FixerPrerequisite[];
|
|
999
980
|
readonly baseRevision?: string;
|
|
1000
981
|
readonly lens?: ReviewerLens;
|
|
1001
982
|
readonly authorityRefs?: readonly string[];
|
|
@@ -1081,10 +1062,7 @@ async function loadResumableRunRecord(
|
|
|
1081
1062
|
let instructionEmpty = true;
|
|
1082
1063
|
let attachments: FrozenAttachment[] = [];
|
|
1083
1064
|
let phase: CoderPhase | FixerPhase | undefined;
|
|
1084
|
-
let taskPath: string | undefined;
|
|
1085
|
-
let packetPath: string | undefined;
|
|
1086
1065
|
let prerequisitesPath: string | undefined;
|
|
1087
|
-
let prerequisites: readonly FixerPrerequisite[] | undefined;
|
|
1088
1066
|
let baseRevision: string | undefined;
|
|
1089
1067
|
let lens: ReviewerLens | undefined;
|
|
1090
1068
|
let authorityRefs: readonly string[] | undefined;
|
|
@@ -1128,21 +1106,10 @@ async function loadResumableRunRecord(
|
|
|
1128
1106
|
if (record.phase === "plan" || record.phase === "apply") {
|
|
1129
1107
|
phase = record.phase;
|
|
1130
1108
|
}
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
}
|
|
1134
|
-
if (typeof record.packetPath === "string" && record.packetPath.trim() !== "") {
|
|
1135
|
-
packetPath = record.packetPath;
|
|
1136
|
-
}
|
|
1137
|
-
if (
|
|
1138
|
-
typeof record.prerequisitesPath === "string" &&
|
|
1139
|
-
record.prerequisitesPath.trim() !== ""
|
|
1140
|
-
) {
|
|
1109
|
+
// #1168: opaque caller path on resume — do not trim-filter provided values.
|
|
1110
|
+
if (typeof record.prerequisitesPath === "string") {
|
|
1141
1111
|
prerequisitesPath = record.prerequisitesPath;
|
|
1142
1112
|
}
|
|
1143
|
-
if (Array.isArray(record.prerequisites)) {
|
|
1144
|
-
prerequisites = record.prerequisites as FixerPrerequisite[];
|
|
1145
|
-
}
|
|
1146
1113
|
if (
|
|
1147
1114
|
typeof record.baseRevision === "string" &&
|
|
1148
1115
|
record.baseRevision.trim() !== ""
|
|
@@ -1319,10 +1286,7 @@ async function loadResumableRunRecord(
|
|
|
1319
1286
|
instructionEmpty,
|
|
1320
1287
|
attachments,
|
|
1321
1288
|
...(phase === undefined ? {} : { phase }),
|
|
1322
|
-
...(taskPath === undefined ? {} : { taskPath }),
|
|
1323
|
-
...(packetPath === undefined ? {} : { packetPath }),
|
|
1324
1289
|
...(prerequisitesPath === undefined ? {} : { prerequisitesPath }),
|
|
1325
|
-
...(prerequisites === undefined ? {} : { prerequisites }),
|
|
1326
1290
|
...(baseRevision === undefined ? {} : { baseRevision }),
|
|
1327
1291
|
...(lens === undefined ? {} : { lens }),
|
|
1328
1292
|
...(authorityRefs === undefined ? {} : { authorityRefs }),
|
|
@@ -1453,12 +1417,6 @@ function admitResumedRole(loaded: {
|
|
|
1453
1417
|
}
|
|
1454
1418
|
case "worker-task": {
|
|
1455
1419
|
const phase = resumedWorkerPhase(fields.phase ?? loaded.run.phase, record.phases, role, runId);
|
|
1456
|
-
const taskPath = fields.taskPath;
|
|
1457
|
-
if (taskPath === undefined) {
|
|
1458
|
-
throw new CliUsageError(
|
|
1459
|
-
`role run admitted coder task path is missing: ${runId}`,
|
|
1460
|
-
);
|
|
1461
|
-
}
|
|
1462
1420
|
if (fields.instruction.trim() === "") {
|
|
1463
1421
|
throw new CliUsageError(
|
|
1464
1422
|
`role run admitted coder task is blank: ${runId}`,
|
|
@@ -1469,34 +1427,24 @@ function admitResumedRole(loaded: {
|
|
|
1469
1427
|
phase,
|
|
1470
1428
|
...base,
|
|
1471
1429
|
instructionEmpty: false,
|
|
1472
|
-
taskPath,
|
|
1473
1430
|
};
|
|
1474
1431
|
return admitted;
|
|
1475
1432
|
}
|
|
1476
1433
|
case "worker-packet": {
|
|
1477
1434
|
const phase = resumedWorkerPhase(fields.phase ?? loaded.run.phase, record.phases, role, runId);
|
|
1478
|
-
const packetPath = fields.packetPath;
|
|
1479
|
-
if (packetPath === undefined) {
|
|
1480
|
-
throw new CliUsageError(
|
|
1481
|
-
`role run admitted fixer packet path is missing: ${runId}`,
|
|
1482
|
-
);
|
|
1483
|
-
}
|
|
1484
1435
|
if (fields.instruction.trim() === "") {
|
|
1485
1436
|
throw new CliUsageError(
|
|
1486
1437
|
`role run admitted fixer instruction is blank: ${runId}`,
|
|
1487
1438
|
);
|
|
1488
1439
|
}
|
|
1489
|
-
const prerequisites = fields.prerequisites ?? Object.freeze([]);
|
|
1490
1440
|
const admitted: AdmittedFixerInvocation = {
|
|
1491
1441
|
role: "fixer",
|
|
1492
1442
|
phase,
|
|
1493
1443
|
...base,
|
|
1494
1444
|
instructionEmpty: false,
|
|
1495
|
-
packetPath,
|
|
1496
1445
|
...(fields.prerequisitesPath === undefined
|
|
1497
1446
|
? {}
|
|
1498
1447
|
: { prerequisitesPath: fields.prerequisitesPath }),
|
|
1499
|
-
prerequisites,
|
|
1500
1448
|
};
|
|
1501
1449
|
return admitted;
|
|
1502
1450
|
}
|
|
@@ -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;
|