@akagilnc/pi-workflow-roles 0.1.3661 → 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.
@@ -1,10 +1,18 @@
1
+ /**
2
+ * Public Notary Role run: admit source-run locator → shared post-admission coordinator
3
+ * → settle Terminal result (#448 / #517). Zero caller prompt/attachment. Lifecycle is
4
+ * the shared post-admission seam; this module keeps only Notary adapters.
5
+ * #637 / #747: same-parent (--source-run) re-summons resume the seat's previous run.
6
+ */
7
+ import { existsSync } from "node:fs";
8
+ import { gateSubmissionCandidatePath } from "../auditor-dossier-tool.js";
1
9
  import { NotarySourceRunError, resolveNotarySourceRunLocator, } from "../notary-source-run.js";
2
10
  import { engineSessionMaterialFromOptions } from "../package-resources/engine-material.js";
3
11
  import { CliUsageError } from "./cli-errors.js";
4
12
  import { admitNotaryInvocation, buildNotaryTransportPrompt, } from "./invocation.js";
5
13
  import { tryResumeSameTicketSeatRun } from "./seat-ticket-binding.js";
6
14
  import { runPostAdmissionOneShot, runPostAdmissionSeatResume, resumeTurnRequestProjectionOptions, } from "./post-admission.js";
7
- import { loadResumableNotaryRun, markRunAdmitted, } from "./run-lifecycle.js";
15
+ import { appendResumeMaterialReread, loadResumableNotaryRun, markRunAdmitted, } from "./run-lifecycle.js";
8
16
  import { presentStructuralRejection, trySettleNotaryTerminalResult, } from "./settlement.js";
9
17
  import { projectRoleTurnRequest, } from "./turn-request.js";
10
18
  /** Project admitted invocation onto the host-neutral turn request. */
@@ -153,10 +161,17 @@ export async function runPublicNotaryResume(request, env, io) {
153
161
  }
154
162
  return loaded;
155
163
  },
156
- buildTurnRequest: (admitted, effective) =>
157
- // #755: review continuation is plain dialogue / resume envelope — no
158
- //「重新读」candidate line, no engine handbook packaging.
159
- buildNotaryTurnRequest(admitted, resumeTurnRequestProjectionOptions(admitted, effective, env)),
164
+ buildTurnRequest: (admitted, effective) => {
165
+ const projection = resumeTurnRequestProjectionOptions(admitted, effective, env);
166
+ const candidatePath = gateSubmissionCandidatePath(admitted.sourceRunPath);
167
+ const prompt = existsSync(candidatePath)
168
+ ? appendResumeMaterialReread(projection.continuation.prompt, candidatePath)
169
+ : projection.continuation.prompt;
170
+ return buildNotaryTurnRequest(admitted, {
171
+ ...projection,
172
+ continuation: { kind: "resume", prompt },
173
+ });
174
+ },
160
175
  adapters: notaryAdapters(),
161
176
  ...(env.engine === undefined ? {} : { effectiveEngine: env.engine }),
162
177
  });
@@ -8,10 +8,11 @@
8
8
  import { randomUUID } from "node:crypto";
9
9
  import { readFile, writeFile } from "node:fs/promises";
10
10
  import { isAbsolute, join, resolve } from "node:path";
11
- import { buildResumeContinuationPrompt, RESUME_TRANSPORT_ENVELOPE, } from "./run-lifecycle.js";
11
+ import { buildResumeContinuationPrompt, instructResumeHandbookRead, } from "./run-lifecycle.js";
12
12
  import { CliUsageError } from "./cli-errors.js";
13
13
  import { buildInstructionTransportPrompt, freezeAttachmentsIntoRun, } from "./invocation.js";
14
14
  import { pathContainedIn } from "../activation-ledger-topology.js";
15
+ import { engineSessionMaterialFromOptions } from "../package-resources/engine-material.js";
15
16
  import { projectCaseDossierPointerSection } from "./case-dossier-delivery.js";
16
17
  /** Append one system section to a continuation prompt, keeping its kind. */
17
18
  function appendContinuationSection(continuation, section) {
@@ -258,37 +259,36 @@ export async function dispatchPostAdmissionTurn(input) {
258
259
  }
259
260
  }
260
261
  /**
261
- * Shared resume continuation projection (#471 / #600 / #633 / #637 / #755):
262
- * seat-table model/engine/timeout axes, restored correlation, and either
263
- * - manual resume (no same-ticket summons): package envelope / optional caller
264
- * message, with engine-axis handbook via buildResumeContinuationPrompt, or
265
- * - same-ticket summons (审核循环续话): caller/peer words + optional frozen
266
- * attachment paths only — no「重新读」、no engine handbook packaging
267
- * (#750/#755), whether or not attachments are present.
268
- * Caller message wins as prompt base when supplied (bytes unchanged, including
269
- * blank/whitespace); else summons instruction. Attachment projection must not
270
- * re-interpret the caller message as instructionEmpty.
262
+ * Shared resume continuation projection (#471 / #600 / #633 / #637): seat-table
263
+ * model/engine/timeout axes, restored correlation, and either
264
+ * - manual resume: package envelope / optional caller message (unchanged), or
265
+ * - same-ticket summons: this turn's instruction + frozen attachment paths.
266
+ * Caller message and summons materials each keep their place: a resume message
267
+ * keeps manual-resume prompt semantics while open-court frozen attachments still
268
+ * ride; summons instruction is only the prompt base when no caller message.
271
269
  * Seats add only their activation projection. Call prepareSummonsResumeMaterials
272
- * first when request.summons carries instruction or attachment paths.
270
+ * first when request.summons carries attachment paths.
273
271
  */
274
272
  export function resumeTurnRequestProjectionOptions(admitted, request, env, summonsPrepared) {
273
+ const engineMaterial = engineSessionMaterialFromOptions({
274
+ ...(env.engine === undefined ? {} : { engine: env.engine }),
275
+ packageRoot: env.packageRoot,
276
+ });
275
277
  let prompt;
276
278
  if (request.message !== undefined) {
277
- if (summonsPrepared !== undefined) {
278
- // #755: same-ticket review / open-court — caller words + optional paths.
279
- // Attachments are not a gate: message-only summons must stay plain too.
280
- prompt = buildInstructionTransportPrompt({
279
+ // Manual resume caller-message semantics stay authoritative for the prompt:
280
+ // message present → base bytes unchanged (including blank/whitespace).
281
+ // Open-court frozen attachments still continue when present; attachment
282
+ // projection must not re-interpret the caller message as instructionEmpty.
283
+ if (summonsPrepared !== undefined &&
284
+ summonsPrepared.attachments.length > 0) {
285
+ prompt = instructResumeHandbookRead(buildInstructionTransportPrompt({
281
286
  instruction: request.message,
282
287
  instructionEmpty: false,
283
288
  attachments: summonsPrepared.attachments,
284
- });
285
- }
286
- else if (request.summons !== undefined) {
287
- // #755: same-ticket summons without prepared materials — caller words only.
288
- prompt = request.message;
289
+ }, engineMaterial), engineMaterial);
289
290
  }
290
291
  else {
291
- // Bare manual resume — outsourcing engine axis keeps handbook (#600/#736).
292
292
  prompt = buildResumeContinuationPrompt({
293
293
  packageRoot: env.packageRoot,
294
294
  ...(env.engine === undefined ? {} : { engine: env.engine }),
@@ -297,16 +297,9 @@ export function resumeTurnRequestProjectionOptions(admitted, request, env, summo
297
297
  }
298
298
  }
299
299
  else if (summonsPrepared !== undefined) {
300
- // #755: same-ticket review summons — instruction/attachments only.
301
- prompt = buildInstructionTransportPrompt(summonsPrepared);
302
- }
303
- else if (request.summons !== undefined) {
304
- // #755: same-ticket summons with no instruction/attachments (e.g. notary
305
- // source-run pointer) — plain resume envelope, no handbook / 重新读.
306
- prompt = RESUME_TRANSPORT_ENVELOPE;
300
+ prompt = instructResumeHandbookRead(buildInstructionTransportPrompt(summonsPrepared, engineMaterial), engineMaterial);
307
301
  }
308
302
  else {
309
- // Bare manual resume — outsourcing engine axis keeps handbook (#600/#736).
310
303
  prompt = buildResumeContinuationPrompt({
311
304
  packageRoot: env.packageRoot,
312
305
  ...(env.engine === undefined ? {} : { engine: env.engine }),
@@ -32,10 +32,11 @@ function resumeRereadInstruction(materialPath, handbook) {
32
32
  : `重新读 ${materialPath}`;
33
33
  }
34
34
  /**
35
- * Engine-axis resume-only material lines (#736 / ADR 0069·0071).
36
- * #755 withdrew this rewrite from 审核循环续话; review same-ticket resume stays
37
- * plain dialogue via resumeTurnRequestProjectionOptions. Outsourcing resume
38
- * still rewrites neutral handbook/path pointers into 重新读 instructions.
35
+ * Resume-only material lines (#736 ticket exemption to ADR 0073 §3).
36
+ * Neutral `- <absolute path>` pointers already on the continuation
37
+ * (handbook from appendEngineSessionMaterial; frozen attachments from
38
+ * instruction-seat transport) become reread instructions.
39
+ * Handbook keeps the argv suffix; other materials are path-only.
39
40
  * First-round delivery is unchanged; never pastes material body.
40
41
  */
41
42
  export function instructResumeHandbookRead(prompt, engineMaterial) {
@@ -55,9 +56,16 @@ export function instructResumeHandbookRead(prompt, engineMaterial) {
55
56
  })
56
57
  .join("\n");
57
58
  }
59
+ /** Append a live-path reread instruction when the pointer is not already on the continuation. */
60
+ export function appendResumeMaterialReread(prompt, materialPath) {
61
+ const instruction = resumeRereadInstruction(materialPath, false);
62
+ const lines = prompt.split("\n");
63
+ if (lines.includes(instruction))
64
+ return prompt;
65
+ return prompt.length === 0 ? instruction : `${prompt}\n${instruction}`;
66
+ }
58
67
  /**
59
- * Unique continuation-prompt selector for manual/auto engine-axis resume
60
- * (#471 / #600 / #736). Not used for 审核循环 same-ticket summons (#755).
68
+ * Unique continuation-prompt selector for manual/auto resume (#471 / #600 / #736).
61
69
  * Message present → base bytes unchanged; absent → package transport envelope.
62
70
  * When engine material is present, append structured engine coordinates then
63
71
  * rewrite absolute material pointer lines into 重新读 instructions. Zero parse,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akagilnc/pi-workflow-roles",
3
- "version": "0.1.3661",
3
+ "version": "0.1.3663",
4
4
  "description": "Soul-bound workflow roles for Pi",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -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
- // #755: review continuation is plain dialogue / resume envelope — no
239
- //「重新读」candidate line, no engine handbook packaging.
240
- buildNotaryTurnRequest(
241
+ buildTurnRequest: (admitted, effective) => {
242
+ const projection = resumeTurnRequestProjectionOptions(
241
243
  admitted,
242
- resumeTurnRequestProjectionOptions(admitted, effective, env),
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
- RESUME_TRANSPORT_ENVELOPE,
14
+ instructResumeHandbookRead,
15
15
  type PublicResumeRequest,
16
16
  type SameTicketSummonsMaterials,
17
17
  } from "./run-lifecycle.ts";
@@ -22,6 +22,7 @@ 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,
@@ -493,18 +494,15 @@ export async function dispatchPostAdmissionTurn<
493
494
  }
494
495
 
495
496
  /**
496
- * Shared resume continuation projection (#471 / #600 / #633 / #637 / #755):
497
- * seat-table model/engine/timeout axes, restored correlation, and either
498
- * - manual resume (no same-ticket summons): package envelope / optional caller
499
- * message, with engine-axis handbook via buildResumeContinuationPrompt, or
500
- * - same-ticket summons (审核循环续话): caller/peer words + optional frozen
501
- * attachment paths only — no「重新读」、no engine handbook packaging
502
- * (#750/#755), whether or not attachments are present.
503
- * Caller message wins as prompt base when supplied (bytes unchanged, including
504
- * blank/whitespace); else summons instruction. Attachment projection must not
505
- * 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.
506
504
  * Seats add only their activation projection. Call prepareSummonsResumeMaterials
507
- * first when request.summons carries instruction or attachment paths.
505
+ * first when request.summons carries attachment paths.
508
506
  */
509
507
  export function resumeTurnRequestProjectionOptions(
510
508
  admitted: AdmittedRoleInvocation,
@@ -516,21 +514,32 @@ export function resumeTurnRequestProjectionOptions(
516
514
  readonly attachments: readonly { frozenPath: string }[];
517
515
  },
518
516
  ): RoleTurnRequestProjectionOptions {
517
+ const engineMaterial = engineSessionMaterialFromOptions({
518
+ ...(env.engine === undefined ? {} : { engine: env.engine }),
519
+ packageRoot: env.packageRoot,
520
+ });
519
521
  let prompt: string;
520
522
  if (request.message !== undefined) {
521
- if (summonsPrepared !== undefined) {
522
- // #755: same-ticket review / open-court — caller words + optional paths.
523
- // Attachments are not a gate: message-only summons must stay plain too.
524
- prompt = buildInstructionTransportPrompt({
525
- instruction: request.message,
526
- instructionEmpty: false,
527
- attachments: summonsPrepared.attachments,
528
- });
529
- } else if (request.summons !== undefined) {
530
- // #755: same-ticket summons without prepared materials — caller words only.
531
- prompt = request.message;
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
+ );
532
542
  } else {
533
- // Bare manual resume — outsourcing engine axis keeps handbook (#600/#736).
534
543
  prompt = buildResumeContinuationPrompt({
535
544
  packageRoot: env.packageRoot,
536
545
  ...(env.engine === undefined ? {} : { engine: env.engine }),
@@ -538,14 +547,11 @@ export function resumeTurnRequestProjectionOptions(
538
547
  });
539
548
  }
540
549
  } else if (summonsPrepared !== undefined) {
541
- // #755: same-ticket review summons — instruction/attachments only.
542
- prompt = buildInstructionTransportPrompt(summonsPrepared);
543
- } else if (request.summons !== undefined) {
544
- // #755: same-ticket summons with no instruction/attachments (e.g. notary
545
- // source-run pointer) — plain resume envelope, no handbook / 重新读.
546
- prompt = RESUME_TRANSPORT_ENVELOPE;
550
+ prompt = instructResumeHandbookRead(
551
+ buildInstructionTransportPrompt(summonsPrepared, engineMaterial),
552
+ engineMaterial,
553
+ );
547
554
  } else {
548
- // Bare manual resume — outsourcing engine axis keeps handbook (#600/#736).
549
555
  prompt = buildResumeContinuationPrompt({
550
556
  packageRoot: env.packageRoot,
551
557
  ...(env.engine === undefined ? {} : { engine: env.engine }),
@@ -163,10 +163,11 @@ function resumeRereadInstruction(materialPath: string, handbook: boolean): strin
163
163
  }
164
164
 
165
165
  /**
166
- * Engine-axis resume-only material lines (#736 / ADR 0069·0071).
167
- * #755 withdrew this rewrite from 审核循环续话; review same-ticket resume stays
168
- * plain dialogue via resumeTurnRequestProjectionOptions. Outsourcing resume
169
- * still rewrites neutral handbook/path pointers into 重新读 instructions.
166
+ * Resume-only material lines (#736 ticket exemption to ADR 0073 §3).
167
+ * Neutral `- <absolute path>` pointers already on the continuation
168
+ * (handbook from appendEngineSessionMaterial; frozen attachments from
169
+ * instruction-seat transport) become reread instructions.
170
+ * Handbook keeps the argv suffix; other materials are path-only.
170
171
  * First-round delivery is unchanged; never pastes material body.
171
172
  */
172
173
  export function instructResumeHandbookRead(
@@ -188,9 +189,19 @@ export function instructResumeHandbookRead(
188
189
  .join("\n");
189
190
  }
190
191
 
192
+ /** Append a live-path reread instruction when the pointer is not already on the continuation. */
193
+ export function appendResumeMaterialReread(
194
+ prompt: string,
195
+ materialPath: string,
196
+ ): string {
197
+ const instruction = resumeRereadInstruction(materialPath, false);
198
+ const lines = prompt.split("\n");
199
+ if (lines.includes(instruction)) return prompt;
200
+ return prompt.length === 0 ? instruction : `${prompt}\n${instruction}`;
201
+ }
202
+
191
203
  /**
192
- * Unique continuation-prompt selector for manual/auto engine-axis resume
193
- * (#471 / #600 / #736). Not used for 审核循环 same-ticket summons (#755).
204
+ * Unique continuation-prompt selector for manual/auto resume (#471 / #600 / #736).
194
205
  * Message present → base bytes unchanged; absent → package transport envelope.
195
206
  * When engine material is present, append structured engine coordinates then
196
207
  * rewrite absolute material pointer lines into 重新读 instructions. Zero parse,