@akagilnc/pi-workflow-roles 0.1.3652 → 0.1.3663
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 +0 -2
- package/dist/acp-host/production-host.js +1100 -1256
- package/dist/public-cli/case-dossier-delivery.js +43 -0
- package/dist/public-cli/inspector-run.js +9 -6
- package/dist/public-cli/instruction-seat-run.js +24 -24
- package/dist/public-cli/invocation.js +2 -24
- package/dist/public-cli/main.js +1936 -2189
- package/dist/public-cli/notary-run.js +20 -5
- package/dist/public-cli/post-admission.js +61 -42
- package/dist/public-cli/run-lifecycle.js +39 -20
- package/dist/public-cli/seat-ticket-binding.js +93 -70
- package/package.json +1 -1
- package/src/public-cli/case-dossier-delivery.ts +51 -0
- package/src/public-cli/countersign-run.ts +14 -17
- package/src/public-cli/diarist-run.ts +11 -13
- package/src/public-cli/inspector-run.ts +9 -10
- package/src/public-cli/instruction-seat-run.ts +28 -35
- package/src/public-cli/invocation.ts +4 -46
- package/src/public-cli/notary-run.ts +18 -6
- package/src/public-cli/post-admission.ts +78 -37
- package/src/public-cli/run-lifecycle.ts +46 -27
- package/src/public-cli/seat-ticket-binding.ts +108 -104
- package/dist/diarist-ticket-resolution.js +0 -177
- package/resources/diarist-resolve-ticket.md +0 -39
- package/src/diarist-ticket-resolution.ts +0 -302
|
@@ -24,9 +24,8 @@ import {
|
|
|
24
24
|
type ParseDiaristArgvResult,
|
|
25
25
|
} from "./invocation.ts";
|
|
26
26
|
import {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
ticketNumberFromProbe,
|
|
27
|
+
bindReusedTicketNumber,
|
|
28
|
+
resolveDiaristSummonsTicketNumber,
|
|
30
29
|
tryResumeSameTicketSeatRun,
|
|
31
30
|
} from "./seat-ticket-binding.ts";
|
|
32
31
|
import {
|
|
@@ -170,16 +169,15 @@ export async function runPublicDiarist(
|
|
|
170
169
|
}
|
|
171
170
|
|
|
172
171
|
// #637: same ticket → resume this seat's prior run with this summons' materials.
|
|
173
|
-
//
|
|
174
|
-
//
|
|
172
|
+
// #709 / ADR 0081: reuse book records, or take the caller's sole dispatch token
|
|
173
|
+
// on a first summons that has not yet minted a volume — no seat recognizer call.
|
|
175
174
|
const projectRoot = parsed.project ?? env.cwd;
|
|
176
|
-
const
|
|
177
|
-
parsed.instruction,
|
|
175
|
+
const reusedTicketNumber = await resolveDiaristSummonsTicketNumber({
|
|
176
|
+
instruction: parsed.instruction,
|
|
178
177
|
projectRoot,
|
|
179
|
-
env,
|
|
180
|
-
);
|
|
181
|
-
|
|
182
|
-
if (probedTicketNumber !== undefined) {
|
|
178
|
+
home: env.home,
|
|
179
|
+
});
|
|
180
|
+
if (reusedTicketNumber !== undefined) {
|
|
183
181
|
const summons: SameTicketSummonsMaterials = {
|
|
184
182
|
instruction: parsed.instruction,
|
|
185
183
|
instructionEmpty: parsed.instruction.trim() === "",
|
|
@@ -189,7 +187,7 @@ export async function runPublicDiarist(
|
|
|
189
187
|
home: env.home,
|
|
190
188
|
projectRoot,
|
|
191
189
|
role: "diarist",
|
|
192
|
-
ticketNumber:
|
|
190
|
+
ticketNumber: reusedTicketNumber,
|
|
193
191
|
freshSummons: env.freshSummons,
|
|
194
192
|
summons,
|
|
195
193
|
resume: (runId, materials) =>
|
|
@@ -256,7 +254,7 @@ export async function runPublicDiarist(
|
|
|
256
254
|
request: turnRequest,
|
|
257
255
|
adapters: diaristAdapters({
|
|
258
256
|
beforeDispatch: async (admittedSeat) => {
|
|
259
|
-
await
|
|
257
|
+
await bindReusedTicketNumber(admittedSeat, reusedTicketNumber);
|
|
260
258
|
const sourcesPath = await freezeDiaristSourceCatalog(admittedSeat, env);
|
|
261
259
|
Object.assign(
|
|
262
260
|
turnRequest,
|
|
@@ -9,8 +9,8 @@ import type { DurablePrincipalAuthority, RoleTurnRequest } from "../host-contrac
|
|
|
9
9
|
import { engineSessionMaterialFromOptions } from "../package-resources/engine-material.ts";
|
|
10
10
|
import { CliUsageError } from "./cli-errors.ts";
|
|
11
11
|
import {
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
bindReusedTicketNumber,
|
|
13
|
+
resolveKnownTicketNumber,
|
|
14
14
|
tryResumeSameTicketSeatRun,
|
|
15
15
|
} from "./seat-ticket-binding.ts";
|
|
16
16
|
import {
|
|
@@ -88,15 +88,14 @@ export async function runPublicInspector(
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
// #747: same parent (卷宗指针) → resume prior inspector run with this summons' materials.
|
|
91
|
-
//
|
|
92
|
-
// controlled failure (bare pre-admit throw skips terminal settlement).
|
|
91
|
+
// #709: ticket identity is reused from records this book already holds — no seat model call.
|
|
93
92
|
// No bare catch→fresh: lookup/resume failures surface; only true absence mints new.
|
|
94
93
|
const projectRoot = parsed.project ?? env.cwd;
|
|
95
|
-
const
|
|
96
|
-
parsed.instruction,
|
|
94
|
+
const reusedTicketNumber = await resolveKnownTicketNumber({
|
|
95
|
+
instruction: parsed.instruction,
|
|
97
96
|
projectRoot,
|
|
98
|
-
env,
|
|
99
|
-
);
|
|
97
|
+
home: env.home,
|
|
98
|
+
});
|
|
100
99
|
const parentRunPath = parentRunPathFromGatePointerInstruction(parsed.instruction);
|
|
101
100
|
if (parentRunPath !== undefined) {
|
|
102
101
|
const summons: SameTicketSummonsMaterials = {
|
|
@@ -171,8 +170,8 @@ export async function runPublicInspector(
|
|
|
171
170
|
request: turnRequest,
|
|
172
171
|
adapters: inspectorAdapters({
|
|
173
172
|
beforeDispatch: async (admittedSeat) => {
|
|
174
|
-
// #635/#
|
|
175
|
-
await
|
|
173
|
+
// #635/#709: bind the reused identity inside the controlled-failure boundary.
|
|
174
|
+
await bindReusedTicketNumber(admittedSeat, reusedTicketNumber);
|
|
176
175
|
},
|
|
177
176
|
}),
|
|
178
177
|
...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
|
|
@@ -36,11 +36,9 @@ import {
|
|
|
36
36
|
type SameTicketSummonsMaterials,
|
|
37
37
|
} from "./run-lifecycle.ts";
|
|
38
38
|
import {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
ticketNumberFromProbe,
|
|
39
|
+
bindReusedTicketNumber,
|
|
40
|
+
resolveKnownTicketNumber,
|
|
42
41
|
tryResumeSameTicketSeatRun,
|
|
43
|
-
type InstructionTicketProbe,
|
|
44
42
|
} from "./seat-ticket-binding.ts";
|
|
45
43
|
import {
|
|
46
44
|
presentStructuralRejection,
|
|
@@ -248,11 +246,11 @@ export async function runPublicInstructionSeat(
|
|
|
248
246
|
let auditorSubject: "judge" | "doctor" | undefined;
|
|
249
247
|
let auditorSourceRun: string | undefined;
|
|
250
248
|
let auditorSourceTicket: number | undefined;
|
|
251
|
-
let
|
|
249
|
+
let reusedTicketNumber: number | undefined;
|
|
252
250
|
|
|
253
251
|
// #637 / #747: resume prior seat run with this summons' materials.
|
|
254
252
|
// Auditor (#747): parent --source-run path is the lookup key.
|
|
255
|
-
// Other instruction seats: ticket
|
|
253
|
+
// Other instruction seats: reuse known ticket (#709). No bare catch→fresh.
|
|
256
254
|
const projectRoot = parsed.project ?? env.cwd;
|
|
257
255
|
if (role === "auditor") {
|
|
258
256
|
if (parsed.subject !== "judge" && parsed.subject !== "doctor") {
|
|
@@ -288,12 +286,11 @@ export async function runPublicInstructionSeat(
|
|
|
288
286
|
return { exitCode: 2 };
|
|
289
287
|
}
|
|
290
288
|
} else {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
parsed.instruction,
|
|
289
|
+
reusedTicketNumber = await resolveKnownTicketNumber({
|
|
290
|
+
instruction: parsed.instruction,
|
|
294
291
|
projectRoot,
|
|
295
|
-
env,
|
|
296
|
-
);
|
|
292
|
+
home: env.home,
|
|
293
|
+
});
|
|
297
294
|
}
|
|
298
295
|
|
|
299
296
|
const summons: SameTicketSummonsMaterials = {
|
|
@@ -322,26 +319,22 @@ export async function runPublicInstructionSeat(
|
|
|
322
319
|
}),
|
|
323
320
|
});
|
|
324
321
|
if (resumed !== undefined) return resumed;
|
|
325
|
-
} else {
|
|
326
|
-
const
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
),
|
|
342
|
-
});
|
|
343
|
-
if (resumed !== undefined) return resumed;
|
|
344
|
-
}
|
|
322
|
+
} else if (reusedTicketNumber !== undefined) {
|
|
323
|
+
const resumed = await tryResumeSameTicketSeatRun({
|
|
324
|
+
home: env.home,
|
|
325
|
+
projectRoot,
|
|
326
|
+
role,
|
|
327
|
+
ticketNumber: reusedTicketNumber,
|
|
328
|
+
freshSummons: env.freshSummons,
|
|
329
|
+
summons,
|
|
330
|
+
resume: (runId, materials) =>
|
|
331
|
+
runPublicInstructionSeatResume(
|
|
332
|
+
{ runId, ...(materials === undefined ? {} : { summons: materials }) },
|
|
333
|
+
env,
|
|
334
|
+
io,
|
|
335
|
+
),
|
|
336
|
+
});
|
|
337
|
+
if (resumed !== undefined) return resumed;
|
|
345
338
|
}
|
|
346
339
|
|
|
347
340
|
let admitted: AdmittedInstructionSeatInvocation;
|
|
@@ -406,13 +399,13 @@ export async function runPublicInstructionSeat(
|
|
|
406
399
|
request: turnRequest,
|
|
407
400
|
adapters: instructionSeatAdapters({
|
|
408
401
|
beforeDispatch: async (admittedSeat) => {
|
|
409
|
-
// #635/#
|
|
402
|
+
// #635/#709: ticket bind inside controlled-failure boundary.
|
|
410
403
|
// Auditor inherits source-run ticket (notary face).
|
|
411
|
-
// Other seats:
|
|
404
|
+
// Other seats: reuse known ticket identity.
|
|
412
405
|
if (auditorSourceTicket !== undefined) {
|
|
413
406
|
await bindAdmittedTicketNumber(admittedSeat, auditorSourceTicket);
|
|
414
|
-
} else
|
|
415
|
-
await
|
|
407
|
+
} else {
|
|
408
|
+
await bindReusedTicketNumber(admittedSeat, reusedTicketNumber);
|
|
416
409
|
}
|
|
417
410
|
},
|
|
418
411
|
}),
|
|
@@ -105,17 +105,10 @@ export type AdmittedRoleInvocationBase = {
|
|
|
105
105
|
*/
|
|
106
106
|
readonly correlationId?: string;
|
|
107
107
|
/**
|
|
108
|
-
* Typed ticketNumber after
|
|
109
|
-
* Admission does not bind from CLI flag or attachment frontmatter.
|
|
108
|
+
* Typed ticketNumber after known-identity reuse or notary source-run inheritance
|
|
109
|
+
* (#635 / #709). Admission does not bind from CLI flag or attachment frontmatter.
|
|
110
110
|
*/
|
|
111
111
|
readonly ticketNumber?: number;
|
|
112
|
-
/**
|
|
113
|
-
* Seat LLM ticket resolution settled as true-unbound (#635).
|
|
114
|
-
* Distinct from unbound-not-yet-resolved (field absent). Mutually exclusive
|
|
115
|
-
* with ticketNumber; both are durable one-shot conclusions so auto-resume
|
|
116
|
-
* and manual resume never re-enter hermes resolution.
|
|
117
|
-
*/
|
|
118
|
-
readonly ticketResolution?: "true-unbound";
|
|
119
112
|
/** Effective model from invocation identity; restored on resume when no CLI model is given. */
|
|
120
113
|
readonly model?: InvocationEffectiveModel;
|
|
121
114
|
};
|
|
@@ -464,8 +457,8 @@ export async function persistAdmittedSourceRunPath(
|
|
|
464
457
|
/**
|
|
465
458
|
* Bind a post-admission resolved ticketNumber onto the in-memory admitted
|
|
466
459
|
* object and both durable pages (invocation.json + admitted-request.json).
|
|
467
|
-
* Used by
|
|
468
|
-
*
|
|
460
|
+
* Used by known-ticket reuse when admission was unbound (#635 / #709).
|
|
461
|
+
* Never clears an existing binding.
|
|
469
462
|
*/
|
|
470
463
|
export async function bindAdmittedTicketNumber(
|
|
471
464
|
admitted: AdmittedRoleInvocation,
|
|
@@ -474,11 +467,6 @@ export async function bindAdmittedTicketNumber(
|
|
|
474
467
|
if (!Number.isSafeInteger(ticketNumber) || ticketNumber < 1) {
|
|
475
468
|
throw new Error(`bindAdmittedTicketNumber requires a safe positive integer, got ${String(ticketNumber)}`);
|
|
476
469
|
}
|
|
477
|
-
if (admitted.ticketResolution === "true-unbound") {
|
|
478
|
-
throw new Error(
|
|
479
|
-
"bindAdmittedTicketNumber refuses to replace durable true-unbound ticket resolution",
|
|
480
|
-
);
|
|
481
|
-
}
|
|
482
470
|
if (admitted.ticketNumber !== undefined) {
|
|
483
471
|
if (admitted.ticketNumber === ticketNumber) return;
|
|
484
472
|
throw new Error(
|
|
@@ -499,36 +487,6 @@ export async function bindAdmittedTicketNumber(
|
|
|
499
487
|
);
|
|
500
488
|
}
|
|
501
489
|
|
|
502
|
-
/**
|
|
503
|
-
* Persist seat LLM true-unbound conclusion onto in-memory admitted + both durable
|
|
504
|
-
* pages so later auto-resume attempts and manual resume never re-enter hermes (#635).
|
|
505
|
-
*/
|
|
506
|
-
export async function recordTrueUnboundTicketResolution(
|
|
507
|
-
admitted: AdmittedRoleInvocation,
|
|
508
|
-
): Promise<void> {
|
|
509
|
-
if (admitted.ticketNumber !== undefined) {
|
|
510
|
-
throw new Error(
|
|
511
|
-
`recordTrueUnboundTicketResolution refuses to overwrite ticket #${admitted.ticketNumber}`,
|
|
512
|
-
);
|
|
513
|
-
}
|
|
514
|
-
if (admitted.ticketResolution === "true-unbound") return;
|
|
515
|
-
(admitted as { ticketResolution?: "true-unbound" }).ticketResolution =
|
|
516
|
-
"true-unbound";
|
|
517
|
-
await mergeInvocationIdentityPage(admitted.runDirectory, {
|
|
518
|
-
ticketResolution: "true-unbound",
|
|
519
|
-
});
|
|
520
|
-
const admittedPath = admitted.admittedRequestPath;
|
|
521
|
-
const current = JSON.parse(await readFile(admittedPath, "utf8")) as Record<
|
|
522
|
-
string,
|
|
523
|
-
unknown
|
|
524
|
-
>;
|
|
525
|
-
await writeFile(
|
|
526
|
-
admittedPath,
|
|
527
|
-
`${JSON.stringify({ ...current, ticketResolution: "true-unbound" }, null, 2)}\n`,
|
|
528
|
-
"utf8",
|
|
529
|
-
);
|
|
530
|
-
}
|
|
531
|
-
|
|
532
490
|
/** Add the identity returned by the production Pi launch seam to its existing ledger page. */
|
|
533
491
|
export async function recordLaunchedPiIdentity(
|
|
534
492
|
runDirectory: string,
|
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
* the shared post-admission seam; this module keeps only Notary adapters.
|
|
5
5
|
* #637 / #747: same-parent (--source-run) re-summons resume the seat's previous run.
|
|
6
6
|
*/
|
|
7
|
+
import { existsSync } from "node:fs";
|
|
8
|
+
|
|
9
|
+
import { gateSubmissionCandidatePath } from "../auditor-dossier-tool.ts";
|
|
7
10
|
import type { DurablePrincipalAuthority, RoleTurnRequest } from "../host-contracts.ts";
|
|
8
11
|
import {
|
|
9
12
|
NotarySourceRunError,
|
|
@@ -26,6 +29,7 @@ import {
|
|
|
26
29
|
resumeTurnRequestProjectionOptions,
|
|
27
30
|
} from "./post-admission.ts";
|
|
28
31
|
import {
|
|
32
|
+
appendResumeMaterialReread,
|
|
29
33
|
loadResumableNotaryRun,
|
|
30
34
|
markRunAdmitted,
|
|
31
35
|
type PublicResumeRequest,
|
|
@@ -234,13 +238,21 @@ export async function runPublicNotaryResume(
|
|
|
234
238
|
}
|
|
235
239
|
return loaded;
|
|
236
240
|
},
|
|
237
|
-
buildTurnRequest: (admitted, effective) =>
|
|
238
|
-
|
|
239
|
-
//「重新读」candidate line, no engine handbook packaging.
|
|
240
|
-
buildNotaryTurnRequest(
|
|
241
|
+
buildTurnRequest: (admitted, effective) => {
|
|
242
|
+
const projection = resumeTurnRequestProjectionOptions(
|
|
241
243
|
admitted,
|
|
242
|
-
|
|
243
|
-
|
|
244
|
+
effective,
|
|
245
|
+
env,
|
|
246
|
+
);
|
|
247
|
+
const candidatePath = gateSubmissionCandidatePath(admitted.sourceRunPath);
|
|
248
|
+
const prompt = existsSync(candidatePath)
|
|
249
|
+
? appendResumeMaterialReread(projection.continuation.prompt, candidatePath)
|
|
250
|
+
: projection.continuation.prompt;
|
|
251
|
+
return buildNotaryTurnRequest(admitted, {
|
|
252
|
+
...projection,
|
|
253
|
+
continuation: { kind: "resume", prompt },
|
|
254
|
+
});
|
|
255
|
+
},
|
|
244
256
|
adapters: notaryAdapters(),
|
|
245
257
|
...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
|
|
246
258
|
});
|
|
@@ -11,7 +11,7 @@ import { isAbsolute, join, resolve } from "node:path";
|
|
|
11
11
|
|
|
12
12
|
import {
|
|
13
13
|
buildResumeContinuationPrompt,
|
|
14
|
-
|
|
14
|
+
instructResumeHandbookRead,
|
|
15
15
|
type PublicResumeRequest,
|
|
16
16
|
type SameTicketSummonsMaterials,
|
|
17
17
|
} from "./run-lifecycle.ts";
|
|
@@ -22,17 +22,31 @@ import {
|
|
|
22
22
|
freezeAttachmentsIntoRun,
|
|
23
23
|
} from "./invocation.ts";
|
|
24
24
|
import { pathContainedIn } from "../activation-ledger-topology.ts";
|
|
25
|
+
import { engineSessionMaterialFromOptions } from "../package-resources/engine-material.ts";
|
|
25
26
|
|
|
26
27
|
import type {
|
|
27
28
|
ControlledFailureCause,
|
|
28
29
|
DurablePrincipal,
|
|
29
30
|
DurablePrincipalAuthority,
|
|
31
|
+
RoleTurnContinuation,
|
|
30
32
|
RoleTurnHost,
|
|
31
33
|
RoleTurnKnownFailure,
|
|
32
34
|
RoleTurnRequest,
|
|
33
35
|
RoleTurnResult,
|
|
34
36
|
SessionCustomEntryAppender,
|
|
35
37
|
} from "../host-contracts.ts";
|
|
38
|
+
import { projectCaseDossierPointerSection } from "./case-dossier-delivery.ts";
|
|
39
|
+
|
|
40
|
+
/** Append one system section to a continuation prompt, keeping its kind. */
|
|
41
|
+
function appendContinuationSection(
|
|
42
|
+
continuation: RoleTurnContinuation,
|
|
43
|
+
section: string,
|
|
44
|
+
): RoleTurnContinuation {
|
|
45
|
+
const prompt = `${continuation.prompt}\n\n${section}`;
|
|
46
|
+
return continuation.kind === "initial"
|
|
47
|
+
? { kind: "initial", prompt }
|
|
48
|
+
: { kind: "resume", prompt };
|
|
49
|
+
}
|
|
36
50
|
import { projectHostTransitionPriorNative } from "../host-transition-prior-native.ts";
|
|
37
51
|
import type { CredentialProviders, SeatModelConfig } from "./config.ts";
|
|
38
52
|
import {
|
|
@@ -297,10 +311,10 @@ export async function dispatchPostAdmissionTurn<
|
|
|
297
311
|
admitted.principal === undefined
|
|
298
312
|
? undefined
|
|
299
313
|
: env.principalAuthority.decode(admitted.principal);
|
|
300
|
-
let
|
|
314
|
+
let hostTransition: RoleTurnRequest["hostTransition"];
|
|
301
315
|
try {
|
|
302
316
|
previousHost = await readInvocationHost(admitted.runDirectory);
|
|
303
|
-
|
|
317
|
+
hostTransition =
|
|
304
318
|
previousHost !== undefined && liveHost !== undefined && principalCoordinates !== undefined
|
|
305
319
|
? await projectHostTransitionPriorNative({
|
|
306
320
|
previousHost,
|
|
@@ -308,10 +322,6 @@ export async function dispatchPostAdmissionTurn<
|
|
|
308
322
|
piSessionFile: principalCoordinates.sessionFile,
|
|
309
323
|
})
|
|
310
324
|
: undefined;
|
|
311
|
-
turnRequest = env.signal === undefined ? request : { ...request, signal: env.signal };
|
|
312
|
-
if (hostTransition !== undefined) {
|
|
313
|
-
turnRequest = { ...turnRequest, hostTransition };
|
|
314
|
-
}
|
|
315
325
|
} catch (error) {
|
|
316
326
|
// prior-native IO is on the public one-shot path — controlled failure, not bare throw.
|
|
317
327
|
return (await presentControlledFailure(
|
|
@@ -351,6 +361,32 @@ export async function dispatchPostAdmissionTurn<
|
|
|
351
361
|
}
|
|
352
362
|
}
|
|
353
363
|
|
|
364
|
+
// Turn request is assembled after beforeDispatch so this turn sees whatever it
|
|
365
|
+
// settled — the seat's ticket bind re-projection. Case dossier delivery
|
|
366
|
+
// (ADR 0081) rides here for every public entry: first call, same-ticket
|
|
367
|
+
// re-summons and manual resume alike. System refs append their own neutral
|
|
368
|
+
// section; caller frozen attachments and the seat's own prompt bytes are
|
|
369
|
+
// never rewritten.
|
|
370
|
+
let turnRequest: RoleTurnRequest =
|
|
371
|
+
env.signal === undefined ? request : { ...request, signal: env.signal };
|
|
372
|
+
if (hostTransition !== undefined) {
|
|
373
|
+
turnRequest = { ...turnRequest, hostTransition };
|
|
374
|
+
}
|
|
375
|
+
const dossierSection = await projectCaseDossierPointerSection({
|
|
376
|
+
ticketNumber: admitted.ticketNumber,
|
|
377
|
+
projectRoot: admitted.projectRoot,
|
|
378
|
+
home: env.home,
|
|
379
|
+
});
|
|
380
|
+
if (dossierSection !== undefined) {
|
|
381
|
+
turnRequest = {
|
|
382
|
+
...turnRequest,
|
|
383
|
+
continuation: appendContinuationSection(
|
|
384
|
+
turnRequest.continuation,
|
|
385
|
+
dossierSection,
|
|
386
|
+
),
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
|
|
354
390
|
let result: RoleTurnResult;
|
|
355
391
|
try {
|
|
356
392
|
result = await env.roleTurnHost.executeTurn(turnRequest);
|
|
@@ -458,18 +494,15 @@ export async function dispatchPostAdmissionTurn<
|
|
|
458
494
|
}
|
|
459
495
|
|
|
460
496
|
/**
|
|
461
|
-
* Shared resume continuation projection (#471 / #600 / #633 / #637
|
|
462
|
-
*
|
|
463
|
-
* - manual resume
|
|
464
|
-
*
|
|
465
|
-
*
|
|
466
|
-
*
|
|
467
|
-
*
|
|
468
|
-
* Caller message wins as prompt base when supplied (bytes unchanged, including
|
|
469
|
-
* blank/whitespace); else summons instruction. Attachment projection must not
|
|
470
|
-
* re-interpret the caller message as instructionEmpty.
|
|
497
|
+
* Shared resume continuation projection (#471 / #600 / #633 / #637): seat-table
|
|
498
|
+
* model/engine/timeout axes, restored correlation, and either
|
|
499
|
+
* - manual resume: package envelope / optional caller message (unchanged), or
|
|
500
|
+
* - same-ticket summons: this turn's instruction + frozen attachment paths.
|
|
501
|
+
* Caller message and summons materials each keep their place: a resume message
|
|
502
|
+
* keeps manual-resume prompt semantics while open-court frozen attachments still
|
|
503
|
+
* ride; summons instruction is only the prompt base when no caller message.
|
|
471
504
|
* Seats add only their activation projection. Call prepareSummonsResumeMaterials
|
|
472
|
-
* first when request.summons carries
|
|
505
|
+
* first when request.summons carries attachment paths.
|
|
473
506
|
*/
|
|
474
507
|
export function resumeTurnRequestProjectionOptions(
|
|
475
508
|
admitted: AdmittedRoleInvocation,
|
|
@@ -481,21 +514,32 @@ export function resumeTurnRequestProjectionOptions(
|
|
|
481
514
|
readonly attachments: readonly { frozenPath: string }[];
|
|
482
515
|
},
|
|
483
516
|
): RoleTurnRequestProjectionOptions {
|
|
517
|
+
const engineMaterial = engineSessionMaterialFromOptions({
|
|
518
|
+
...(env.engine === undefined ? {} : { engine: env.engine }),
|
|
519
|
+
packageRoot: env.packageRoot,
|
|
520
|
+
});
|
|
484
521
|
let prompt: string;
|
|
485
522
|
if (request.message !== undefined) {
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
523
|
+
// Manual resume caller-message semantics stay authoritative for the prompt:
|
|
524
|
+
// message present → base bytes unchanged (including blank/whitespace).
|
|
525
|
+
// Open-court frozen attachments still continue when present; attachment
|
|
526
|
+
// projection must not re-interpret the caller message as instructionEmpty.
|
|
527
|
+
if (
|
|
528
|
+
summonsPrepared !== undefined &&
|
|
529
|
+
summonsPrepared.attachments.length > 0
|
|
530
|
+
) {
|
|
531
|
+
prompt = instructResumeHandbookRead(
|
|
532
|
+
buildInstructionTransportPrompt(
|
|
533
|
+
{
|
|
534
|
+
instruction: request.message,
|
|
535
|
+
instructionEmpty: false,
|
|
536
|
+
attachments: summonsPrepared.attachments,
|
|
537
|
+
},
|
|
538
|
+
engineMaterial,
|
|
539
|
+
),
|
|
540
|
+
engineMaterial,
|
|
541
|
+
);
|
|
497
542
|
} else {
|
|
498
|
-
// Bare manual resume — outsourcing engine axis keeps handbook (#600/#736).
|
|
499
543
|
prompt = buildResumeContinuationPrompt({
|
|
500
544
|
packageRoot: env.packageRoot,
|
|
501
545
|
...(env.engine === undefined ? {} : { engine: env.engine }),
|
|
@@ -503,14 +547,11 @@ export function resumeTurnRequestProjectionOptions(
|
|
|
503
547
|
});
|
|
504
548
|
}
|
|
505
549
|
} else if (summonsPrepared !== undefined) {
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
// source-run pointer) — plain resume envelope, no handbook / 重新读.
|
|
511
|
-
prompt = RESUME_TRANSPORT_ENVELOPE;
|
|
550
|
+
prompt = instructResumeHandbookRead(
|
|
551
|
+
buildInstructionTransportPrompt(summonsPrepared, engineMaterial),
|
|
552
|
+
engineMaterial,
|
|
553
|
+
);
|
|
512
554
|
} else {
|
|
513
|
-
// Bare manual resume — outsourcing engine axis keeps handbook (#600/#736).
|
|
514
555
|
prompt = buildResumeContinuationPrompt({
|
|
515
556
|
packageRoot: env.packageRoot,
|
|
516
557
|
...(env.engine === undefined ? {} : { engine: env.engine }),
|